Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Show how relative paths works on containers
Red [
Name: "Power Selector"
Purpose: "Demostrate the working scenario of relative paths"
Notes: {
Idea: Giuseppe Chillemi
Path operator: Toomas Vooglaid
}
]
;---- Create the new "///" operator
path: function [a b][to path! append to block! a to block! b]
///: make op! :path
;------------
;The list of relative accessors
mystruct: [
name: heading/name
size: heading/size
body: body
extra: extra
authors: extra/authors
]
;Now we create 2 contaniers having the same structure
; the second one is the previous version of the first one
software-list: [
[
heading [name "Red" size 1200]
body ["The new merging Full-stack language"]
extra [
authors [
"Nenad Rakočević"
"Quingtian"
"Greg Irvin"
"Valdimir Valiliev"
"Boleslav Březovský"
"Hiiamboris"
]
]
]
[
heading [name "Rebol" size 900]
body ["The Ancestor of our language"]
extra [
authors [
"Carl Sassenrath"
]
]
]
[
heading [name "REN-C" size 650]
body ["Experimental Rebol derived language" ]
extra [
authors [
"Hostile Fork"
]
]
]
]
software-list-Previous: [
[
heading [name "Red" size 1200]
body ["The new merging Full-stack language"]
extra [
Authors [
"Nenad Irvin"
]
]
]
]
; Here we print some elements of the strcuture of the following containers.
containers-to-print: [software-list software-list-Previous]
;The code loops the containers
foreach series containers-to-print [
print ["------- Container name: -------" series]
;All the records
repeat idx length? get series [
Print [
"Software name:" get series /// idx /// mystruct/name lf
"Size is:" get series /// idx /// mystruct/size
]
;And sub records
auth-temp: get series /// idx /// mystruct/authors
forall auth-temp [
print [" Author:" first auth-temp]
]
Print lf
]
Print lf
]
;--- Output: ------
comment {
------- Container name: ------- software-list
Software name: Red
Size is: 1200
Author: Nenad Rakočević
Author: Quingtian
Author: Greg Irvin
Author: Valdimir Valiliev
Author: Boleslav Březovský
Author: Hiiamboris
Software name: Rebol
Size is: 900
Author: Carl Sassenrath
Software name: REN-C
Size is: 650
Author: Hostile Fork
------- Container name: ------- software-list-Previous
Software name: Red
Size is: 1200
Author: Nenad Irvin
}
@Oldes

This comment has been minimized.

Copy link

@Oldes Oldes commented Jan 14, 2021

Using something like:

resolve: func [path [block!] /local out][
	out: copy []
	forall path [append out to block! get path/1]
	get as path! out 
]

instead of:

path: function [a b][probe to path! append to block! a to block! b]

///: make op! :path

would be more efficient and imho I prefer to read:

auth-temp: resolve [series idx mystruct/authors]   

instead of:

auth-temp: get series /// idx /// mystruct/authors    	
@Oldes

This comment has been minimized.

Copy link

@Oldes Oldes commented Jan 14, 2021

You can name it <== instead of resolve to make it shorter:-)

auth-temp: <==[series idx mystruct/authors] 
@GiuseppeChillemi

This comment has been minimized.

Copy link
Owner Author

@GiuseppeChillemi GiuseppeChillemi commented Jan 14, 2021

Good! Let's continue this exploration on relative path composition. I will try to stress mine adding calculated elements and a path dialect. I am 100% sure we will discover many creative ways of doing this thing.

@GiuseppeChillemi

This comment has been minimized.

Copy link
Owner Author

@GiuseppeChillemi GiuseppeChillemi commented Jan 14, 2021

Note: => is another good symbol combination !

@greggirwin

This comment has been minimized.

Copy link

@greggirwin greggirwin commented Jan 15, 2021

I like resolve. It's a very clean and simple solution, and a good name.

@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 15, 2021

[resolve] would be more efficient ...

Not correct. Speed-wise, ops are more efficient than functions. Experiment:

;;Set-up
;Giuseppe
path: function [a b][to path! append to block! a to block! b]
///: make op! :path

;Oldes
resolve: func [path [block!] /local out][
	out: copy []
	forall path [append out to block! get path/1]
	get as path! out 
]

;Toomas
//: make op! func [a b][as path! append to block! a to block! b]

;------------

;The list of relative accessors
;Giuseppe & Oldes
mystruct: [
   name:  heading/name
   size:  heading/size
   body:  body
   extra: extra
   authors: extra/authors
]
;Toomas
struct: context [
   name:  'heading/name
   size:  'heading/size
   body:  'body
   extra: 'extra
   authors: 'extra/authors
]

;;Adapted funcs (printing eliminated, containers as originally)
Giuseppe: func [][
	foreach series containers-to-print [
		repeat idx length? get series [
			"Software name:" get series /// idx /// mystruct/name
			"Size is:" get series /// idx /// mystruct/size
			auth-temp: get series /// idx /// mystruct/authors    	
			forall auth-temp [
				"       Author:" first auth-temp
			]
		]
	]
]
Oldes: func [][
	foreach series containers-to-print [
		repeat idx length? get series [
			"Software name:" resolve [series idx mystruct/name]
			"Size is:" resolve [series idx mystruct/size]
			auth-temp: resolve [series idx mystruct/authors]
			forall auth-temp [
				"       Author:" first auth-temp
			]
		]
	]
]
Toomas: func [][
	foreach series containers-to-print bind [
		repeat idx length? get series [
			software: series // idx
			"Software name:" get software // name
			"Size is:" get software // size
			auth-temp: get software // authors    	
			forall auth-temp [
				"       Author:" first auth-temp
			]
		]
	] struct
]

Profiling results:

>> recycle/off
>> profile/show/count [[Giuseppe][Oldes][Toomas]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.04   | 0:00:00      |     4220284 | [Toomas]
0:00:00.055  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.065  | 0:00:00      |     4032284 | [Oldes]
>> profile/show/count [[Giuseppe][Oldes][Toomas]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.042  | 0:00:00      |     4220284 | [Toomas]
0:00:00.053  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.061  | 0:00:00      |     4032284 | [Oldes]
>> profile/show/count [[Giuseppe][Oldes][Toomas]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.041  | 0:00:00      |     4220284 | [Toomas]
0:00:00.054  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.062  | 0:00:00      |     4032284 | [Oldes]
>> profile/show/count [[Giuseppe][Oldes][Toomas]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.039  | 0:00:00      |     4220284 | [Toomas]
0:00:00.053  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.061  | 0:00:00      |     4032284 | [Oldes]
@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 15, 2021

And this is even better:

get-path: func [block [block! hash! paren! object! map!] path [path! block!]][
	foreach i path [block: block/:i]
]
Toomas2: func [][
	foreach series containers-to-print bind [
		repeat idx length? get series [
			software: get series // idx
			"Software name:" get-path software name
			"Size is:" get-path software size
			auth-temp: get-path software authors    	
			forall auth-temp [
				"       Author:" first auth-temp
			]
		]
	] struct
]
>> profile/show/count [[Giuseppe][Oldes][Toomas][Toomas2]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.03   | 0:00:00      |      620596 | [Toomas2]
0:00:00.039  | 0:00:00      |     3116672 | [Toomas]
0:00:00.055  | 0:00:00      |     6050212 | [Giuseppe]
0:00:00.064  | 0:00:00      |     4032596 | [Oldes]
@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 15, 2021

And still better :)

context [
	//: make op! :get-path
	set 'Toomas3 does [
		foreach series containers-to-print bind [
			repeat idx length? series: get series [
				software: series/:idx
				"Software name:" software // name
				"Size is:" software // size
				auth-temp: software // authors    	
				forall auth-temp [
					"       Author:" first auth-temp
				]
			]
		] struct
	]
]
>> profile/show/count [[Giuseppe][Oldes][Toomas][Toomas2][Toomas3]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.022  | 0:00:00      |       44284 | [Toomas3]
0:00:00.031  | 0:00:00      |      620284 | [Toomas2]
0:00:00.04   | 0:00:00      |     3116284 | [Toomas]
0:00:00.053  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.064  | 0:00:00      |     4032284 | [Oldes]
@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 15, 2021

And, surprisingly, ultimate solution seems to be stepping back a bit:

context [
	//: make op! :get-path
	set 'Toomas4 does [
		foreach series containers-to-print [
			repeat idx length? series: get series [
				"Software name:" series/:idx // mystruct/name
				"Size is:" series/:idx // mystruct/size
				auth-temp: series/:idx // mystruct/authors    	
				forall auth-temp [
					"       Author:" first auth-temp
				]
			]
		] 
	]
]
>> profile/show/count [[Giuseppe][Oldes][Toomas][Toomas2][Toomas3][Toomas4]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.022  | 0:00:00      |         284 | [Toomas4]
0:00:00.024  | 0:00:00      |       44284 | [Toomas3]
0:00:00.029  | 0:00:00      |      620284 | [Toomas2]
0:00:00.04   | 0:00:00      |     3116284 | [Toomas]
0:00:00.055  | 0:00:00      |     6048440 | [Giuseppe]
0:00:00.062  | 0:00:00      |     4032284 | [Oldes]
@greggirwin

This comment has been minimized.

Copy link

@greggirwin greggirwin commented Jan 15, 2021

I love naming the tests this way. Will try to review the code later.

@GiuseppeChillemi

This comment has been minimized.

Copy link
Owner Author

@GiuseppeChillemi GiuseppeChillemi commented Jan 15, 2021

It is becoming a Toomas VS Toomas battle, as Computer VS Computer chess games. I hope there are enough computing resources and stack space in yourself otherwise, you could generate an error!

@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 16, 2021

Sorry! Got excited. Going away.

@GiuseppeChillemi

This comment has been minimized.

Copy link
Owner Author

@GiuseppeChillemi GiuseppeChillemi commented Jan 16, 2021

Toomas, when I have looked at all the solutions you have been able to create, I have thought about you as a supreme computer fighting against itself to create the best possible one. The observation must be read as my admiration for your incredible coding and combinatorial skills. Especially, the last solution has raised many questions to me about the very low amount of memory used if compared to the others:

0:00:00.022 | 0:00:00 | 284 | [Toomas4]

EDIT: it should be someone else to say this but it is fantastic when you are excited!!! :-D

@greggirwin

This comment has been minimized.

Copy link

@greggirwin greggirwin commented Jan 16, 2021

It is becoming a Toomas VS Toomas battle

This made me laugh. I like it. When any of get excited by an idea it can help to run with it and see where it goes. Getting into a state of flow, and understanding a problem in order to think more deeply about it is 90% of the battle. That's what makes working quickly so powerful.

@greggirwin

This comment has been minimized.

Copy link

@greggirwin greggirwin commented Jan 16, 2021

The memory pressure reduction comes from not binding the block to the context every time.

@GiuseppeChillemi

This comment has been minimized.

Copy link
Owner Author

@GiuseppeChillemi GiuseppeChillemi commented Jan 16, 2021

It's huge, about 21.200 times. Which block is being bound so often to generate such memory consumption?

@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 16, 2021

:)
Oldes' resolve can be restructured in a somewhat similar way to get-path:

resolve2: func [block [block!] path [block! path!]][
	forall path [
		block: either any-block? path/1 [
			resolve2 block path/1
		][
			block/(path/1)
		]
	]
]

And main procedure reformulated as

Oldes2: does [
	foreach series containers-to-print [
		repeat idx length? series: get series [
			;print [
				"Software name:" resolve2 series/:idx mystruct/name
			;] print [
				"Size is:" resolve2 series/:idx mystruct/size
			;]
			auth-temp: resolve2 series/:idx mystruct/authors
			forall auth-temp [
				;print [
					"       Author:" first auth-temp
				;]
			]
		]
	]
]

with similar results:

>> profile/show/count [[Oldes2][Toomas4]] 1000
Count: 1000
Time         | Time (Per)   |      Memory | Code
0:00:00.021  | 0:00:00      |         284 | [Toomas4]
0:00:00.038  | 0:00:00      |         596 | [Oldes2]
@toomasv

This comment has been minimized.

Copy link

@toomasv toomasv commented Jan 17, 2021

Ah, sorry, resolve2 doesn't work this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment