r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Anton
27-Sep-2010
[18517x5]
sforpath: func ["Evaluate a path similar to the builtin path evaluation, 
except number elements SELECT (rather than PICK)."
	path [path!] action [function! block!] /local e v c
][

 v: get path/1 ; The path is assumed to begin with a word, so get 
 its value.

 while [not tail? path: next path][ ; Step through the path to inspect 
 each of its elements.
		c: v ; Store the current value before SELECTing into it.
		e: pick path 1 ; The current element.
		;print [mold :e mold type? :e]
		if get-word? :e [e: get e]
		case [

   number? e [v: select v e] ; SELECT this number element. (Paths normally 
   PICK number elements.)

   word? e [v: select v e] ; SELECT this word element (as paths normally 
   do).
		]
	]
	;?? e ?? v ?? c
	; Process the last element.
	if block? :action [action: func [c e] action]
	action c e
]
; Test
values: [1 [dos [new 0]]]

sforpath 'values/1/dos/new [c/:e: c/:e + 1]  ; <- DideC's INC-COUNTER 
function could be implemented simply using this.
Just to remind, DideC's example had:

values: [

 1 [dos [new 0 modified 0 deleted 0] fic [new 0 modified 0 deleted 
 0]]

 2 [dos [new 0 modified 0 deleted 0] fic [new 0 modified 0 deleted 
 0]]
]
And here's an idea which may make the usage simpler:
Write a function USEPATH, used like this:

	values: [1 [dos [new 0]]]
	p: 'values/1/dos/new

 usepath p [p: p + 1]  ;=== (values/1/dos/new: values/1/dos/new + 
 1)
	values ;== [1 [dos [new 1]]
	
or perhaps, achieving the same result:

	usepath p 'v [v: v + 1]


where v is the value SELECTed by the last element in the path (so 
you can choose a different variable name).
  
or even:

	usepath p 4 'v [v: v + 1]


where 'v is set to refer to the value of the 4th element ('new) in 
the path.

so we can refer to any path element by its number, and so this would 
achieve the same:


 usepath p 3 'v [v/new: v/new + 1]  ;=== (values/1/dos/new: values/1/dos/new 
 + 1)
  
and even crazier:

	usepath p 'root/pid/fs/flag [flag: flag + 1]


where the second path elements (all word!s) reference the values 
actually SELECTed in p,
so these are all equivalent:
	usepath p 'values/pid/fs/flag [fs/dos: flag + 1]
	usepath p 'values/pid/fs/flag [fs/dos: fs/dos + 1]
	usepath p 'values/pid/fs/flag [root/pid/fs/flag: flag + 1]
All good fun.
(Oops, the last three examples should begin:   usepath p 'root/.... 
)
BrianH
27-Sep-2010
[18522x5]
Ladislav, REDUCE/into is used to eliminate a temporary series allocation 
in the common INSERT REDUCE and APPEND REDUCE patterns. It is used 
in mezzanine code, and does in fact reduce memory allocation overhead. 
Hate to break it to you, but REDUCE/into and COMPOSE/into were actually 
worth adding. Sorry.
REDUCE/into and COMPOSE/into cut down 2 copies to 1. They don't eliminate 
copies altogether.
The main reason that UNIQUE isn't used is because it is not very 
useful: It is easier to make sure that the series is unique in the 
first place. The other "set" functions like INTERSECT, DIFFERENCE 
and EXCLUDE are used more often, even though they do the same copies 
as UNIQUE, using the same hashing method.
I suggested REDUCE/into and COMPOSE/into, and found them to be immediately 
useful. I don't know why UNIQUE/into is being suggested, its use 
case.
Henrik had a use case for DEDUPLICATE, though that was when he thought 
he could eliminate the copy, and actually wanted to change UNIQUE 
to be modifying instead. It's not a common enough use case to make 
it into the core functions, but there is a mezzanine for it in the 
CureCode ticket.
Ladislav
27-Sep-2010
[18527x3]
REDUCE/into and COMPOSE/into were actually worth adding

 - no problem with that, what I was saying, though, was something 
 else
I specifically had objections against the

    reduce/into b b

expression, which cannot be done efficiently without copying
...neither it is really useful, in my opinion
BrianH
29-Sep-2010
[18530]
I definitely agree with that. I can't figure out a use for that code 
pattern, at least at first glance.
Maxim
30-Sep-2010
[18531]
when we generate blocks on the fly, we sometimes need evaluation 
to occur at a later stage.  this allows to save on an uneeded additional 
copy.  (which can be taxing on the GC when blocks are large)
Ladislav
1-Oct-2010
[18532]
this allows to save on an uneeded additional copy.
 - if you are referring to the

    reduce/into b b


expression, Max, then your assumption is wrong, this cannot save 
an unneeded additonal copy
Maxim
1-Oct-2010
[18533]
well IIRC Steeve had done tests and it was much faster... so something 
is being saved.
Izkata
1-Oct-2010
[18534]
it was so that new memory didn't need to be allocated in this expression, 
and the old didn't need to be garbage collected:

b: reduce b
Steeve
1-Oct-2010
[18535x3]
About the /into refinement.

I don't bother if internaly, a copy is done or not, while it's faster 
and memory safe (the block must be freed immediatly not by the GC) 

The GC used to have some memory leaks and was reacting too late to 
be useful (especialy in apps with a GUI).
I now it's better now (thanks to recycle/ballast).
* I know
about reduce/into b b

It allows to keep several references of the same block without the 
need to reassign them when the block is reconstructed.

But currently, we can't avoid the block expansion because the data 
are inserted instead of beeing replaced (which would be more useful 
to my mind).

Then, if internaly it's faster to do a copy, I don't care while it's 
not recycled by the GC (for the reasons I mentioned previously).
BrianH
1-Oct-2010
[18538x2]
Sounds interesting. I know that CHANGE/part is the real fundamental 
operation, but that needs an additional parameter and would require 
renaming the option - /into isn't an appropriate name for that operation. 
But I don't think it would have been implemented in that case, and 
having it be a direct CHANGE would definitely not have been accepted 
because /into is mostly used to replace chained INSERT and APPEND 
operations.
The downside of the /into option is that you have to be careful when 
using it or your code won't be task-safe. Your multiple references 
to a block that can change scenario is an example that can quite 
easily lead to task-unsafe code, for instance. But /into is great 
for micro-optimization and local code simplification, as long as 
you are careful to not modify shared structures without coordinating 
tasks.
Steeve
1-Oct-2010
[18540]
yeah indeed
BrianH
1-Oct-2010
[18541]
Of course task-safety isn't a problem for most R2 code, but then 
neither does R2 have natives with /into. Some of the new mezzanines 
though.
Maxim
1-Oct-2010
[18542]
for the record (for the other people reading, which might not be 
as fluent in the more low level aspects of the core)..


I just want to note that your comment about thread safety doesn't 
only apply specifically to the /into... 


It applies to *all* series usage in REBOL 3 since they are mutable 
and MANY functions modifiy series "in-place".


Other languages always copy on assign so its not as big an issue 
as in REBOL.
BrianH
1-Oct-2010
[18543]
Agreed. Though not many other languages always copy on assign - that's 
a relatively new habit.
Izkata
1-Oct-2010
[18544]
Or copy on any change, rather than on assign, as Java does with String
Gregg
3-Oct-2010
[18545x2]
Does anyone have a well-tested mezz version of CASE handy for use 
with older REBOL cores?
Ladislav's PIF is my first stop.
Graham
3-Oct-2010
[18547]
how old is old?
Gregg
3-Oct-2010
[18548]
1.2.47
Graham
3-Oct-2010
[18549]
I don't know where this came from:

	case: func [
		[throw catch]
		args [block!] /local res
	] [
		either unset? first res: do/next args [
			if not empty? args [
				; invalid guard
				throw make error! [script no-arg case condition]
			]
		] [
			either first res [
				either block? first res: do/next second res [
					do first res
				] [
					; not a block
					throw make error! [
						script expect-arg case block [block!]
					]
				]
			] [
				case second do/next second res
			]
		]
	]
Gregg
3-Oct-2010
[18550]
Thanks Graham!
Graham
3-Oct-2010
[18551]
looks like PIF!
Gregg
3-Oct-2010
[18552x2]
That's Ladislav's PIF, just renamed.
:-)
Graham
3-Oct-2010
[18554]
Yep ... !
Gregg
3-Oct-2010
[18555]
All roads lead to Ladislav.
Graham
3-Oct-2010
[18556x3]
Does anyone else experience the inability to read the clipboard ?
I can paste from the browser to notepad, and other apps, and it's 
just text, but .... the clipboard shows empty.  The problem will 
go away if I reboot though.
If I write to clipboard://, nothing is there either ...
Gregg
3-Oct-2010
[18559x2]
REBOL sometimes seems to get confused if there is data on the clipboard, 
possibly related to the format of the clipboard data. Writing can 
fail at times too IME. Clearing the clipboard before writing usually 
solves the problem for me.
I think this is also what messes up AltMe's clipboard behavior at 
times.
Graham
3-Oct-2010
[18561x2]
Correction, I can write to the clipboard:// and paste into other 
apps, but Rebol is seeing nonthing there.
I can paste this: test
from Rebol, but can not paste into a new instance of View
Gregg
3-Oct-2010
[18563]
Do you have any kind of clipboard monitoring software installed?
Graham
3-Oct-2010
[18564]
No, I don't
Gregg
3-Oct-2010
[18565]
What program are you writing data to the clipboard with?
Graham
3-Oct-2010
[18566]
if the clipboard were screwed .... then Altme wouldn't see it either??