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

World: r3wp

[!REBOL3]

Geomol
13-May-2011
[8591]
I notice ++ and --, which was discussed here:
http://www.rebol.net/cgi-bin/r3blog.r?view=0057#comments

Would it be ok to let NEXT and BACK do the job, like this:

next: func [series] [
	either word? series [
		set series system/contexts/lib/next get series
	][
		system/contexts/lib/next series
	]
]

Examples of use:

>> blk: [a b c]
== [a b c]
>> next blk
== [b c]
>> blk
== [a b c]
>> next 'blk
== [b c]
>> blk
== [b c]
Maxim
13-May-2011
[8592]
it would break a lot of code, and in fact, I prefer it like it is. 
  


this being said, if we have ++/--, then I expect *these* to work 
as you just depicted
Geomol
13-May-2011
[8593]
WIll it break code? Hmm, what kind of code?
Maxim
13-May-2011
[8594]
all of my code  ;-)
Geomol
13-May-2011
[8595x2]
I don't see how. Notice, NEXT in my example works just like today 
with all arguments beside words, which gives an error today.
The first part of my examples above use the new NEXT just like the 
old NEXT, we have today.
Maxim
13-May-2011
[8597]
ahhh.. I just re-read your code... and was bitten by the lit-word 
evaluation again.

I didn't realize that:

either word? series [

triggers when you give a lit-word.

in this case, you are right.


except in implementation.   words carry their binding, you don't 
need (in fact shoudn't) acess it via system   

set word next get word

should be enough.
Geomol
13-May-2011
[8598x2]
If just using NEXT instead of full path, R3 will create a stack overflow. 
The function is called NEXT, you know! ;)

But anyway, this should be changed in the native.
I guess, the reason for the stack overflow is that function body 
is rebound to local context.
Maxim
13-May-2011
[8600]
ok... I just hit myself on the head a few times.  clearly, I'm not 
sharp right now.  :-)
Geomol
13-May-2011
[8601]
Winblows mess with your mind! Save yourself! :)
Maxim
13-May-2011
[8602]
yeah, I guess that's it.  my brain is getting fried by the sun going 
through the windows (our first full week of sun in months).
BrianH
13-May-2011
[8603x2]
Geomol, the return values of ++ and -- are different than those of 
NEXT and BACK, which is why we have the seperate functions.
NEXT and BACK are also non-modifying (except for ports), which is 
another valuable difference.
Geomol
13-May-2011
[8605]
Are you sure, that's why we have separate functions? What benefit 
is there from the return values of ++?
BrianH
13-May-2011
[8606x2]
By "valuable difference" I don't mean that one or the other behavior 
is preferable all of the time and so we should choose one, I mean 
that both patterns of behavior are valuable in different circumstances 
and so we need to support both. Both sets of functions are needed 
in mezzanine code, as they are now.
Yes, I am sure. The different pattern of behavior was why Carl added 
++ and --, since he needed something like this for mezzzanine code.
Geomol
13-May-2011
[8608]
My viewpoint is, that ++ isn't the speedy native, many people would 
expect. When using ++ on a series, a new series is created. So ++ 
take one series and produce two, one is the original, which is incremented, 
the other is the return value, which is the old series position. 
This isn't very effective from a performance perspective.


If my NEXT function was implemented in the current NEXT native, it 
didn't have to produce another series, if called with a word. This 
will mean good performance.
BrianH
13-May-2011
[8609]
++ doesn't create a new series, it just increments the index of the 
reference to the same series.
Geomol
13-May-2011
[8610x2]
Same could be done with many other natives, if they were improved 
to also take words as arguments.
It does create a new series:

>> b: [a b c]
== [a b c]
>> same? ++ b b
== false


(I know, it's the same area of memory, but we have two set of series 
variables to work on that memory.)
BrianH
13-May-2011
[8612]
A series reference fits into a value slot, so returning a reference 
to the same position doesn't take any more space than returning a 
reference to a different position. This means that there is nothing 
to be gained by losing the information.
Geomol
13-May-2011
[8613x2]
Are you saying, e.g. an integer value take up the same amount of 
memory as a series ref.? Doesn't sound very effective, but you could 
be correct. :)
(Remember a series need info about the area, the head, tail, position.)
BrianH
13-May-2011
[8615x2]
++ and -- return a reference to the previous position in order to 
lower the need for local temporary variables to save the previous 
position when you need to. Returning it means that information is 
not lost. Technically, since ++ and -- are modifying functions they 
don't need to return anything at all. The only reason they return 
that information is because it's valuable.
Yes, an integer takes up the same space as a series ref (though the 
series itself takes additional space). Though in R3 currently integers 
are 64bit and series refs are a 32bit pointer and a 32bit offset, 
so it's not as much of a waste as in R2 where integers are 32bit. 
For both though, the value slot is 128bit anyways. This is the price 
you pay for using variants.
Geomol
13-May-2011
[8617x2]
This is from R2:

>> next b
== [b c]
>> stats/series
== [34304 26141 7434 231 498 497 406]
>> next b      
== [b c]
>> stats/series
== [34304 26145 7444 231 484 483 409]
>> ++ b
== [a b c]
>> stats/series
== [34304 26151 7454 231 468 467 412]
>> ++ b        
== [b c]
>> stats/series
== [34304 26157 7464 231 452 451 415]


You see, NEXT increment BLOCKS (2nd number) by 4 each time. ++ increment 
it by 6 each time. So ++ take up more memory.
I think, you assume too much, my young padawan! ;)
BrianH
13-May-2011
[8619x2]
In R2, ++ and -- are mezzanines which I wrote, not natives. You are 
assuming too much :)
The R2 versions are optimized for R3 compatibility, not for efficiency. 
They are still efficient for mezzanine implementations of that behavior.
Geomol
13-May-2011
[8621]
:) Touchˇ!
BrianH
13-May-2011
[8622]
On the other hand, I really don't know how to interpretet the results 
of R2's STATS function, so I'm taking your word for it that the series 
are created by the ++ calls. Which numbers tell you this?
Geomol
13-May-2011
[8623]
Got it. Series are 32 bit pointer and 32 bit offset. So no additional 
space is wasted by having ++ return as it does.
Henrik
13-May-2011
[8624]
SAME? must work from the same index in the same series:

== [a b c]
>> same? a next a
== false
Geomol
13-May-2011
[8625x3]
Henrik, yes. I'm trying to point out, that an additional index is 
created.
Brian, do

? stats


in R2. I read it, as the /series refinement show BLOCKS as the second 
number.
And a block here is a series index. Two blocks can share the same 
mem area for the actual content of the series.
BrianH
13-May-2011
[8628]
The area, head, tail and such attributes of a series are in the series 
itself, not in the reference to the series. This is good because 
series references are copied every time they are passed to a function 
- REBOL is strictly pass-by-value. All return values are copied too.
Geomol
13-May-2011
[8629]
Makes sense. So the additional mem for the series ref. is on the 
stack (or whatever data structure is used), and if that area is reused 
between additional computations, no mem is wasted by ++. Correct?
BrianH
13-May-2011
[8630]
>> stats/series
== [16384 11618 4590 25 151 150 199]
>> a: [1 2 3]
== [1 2 3]
>> stats/series
== [16384 11623 4601 25 135 134 202]


Only one of those is the new block - the rest are overhead of either 
the STATS function or of the REPL loop itself, or runtime overhead, 
or call overhead, or assignment overhead. I'm starting to think that 
STATS/series isn't very useful.
Geomol
13-May-2011
[8631]
Yes, stats/series eat 3 blocks each time, it's called.
BrianH
13-May-2011
[8632x2]
No mem is wasted by ++ that isn't also wasted by NEXT.
AFAICT, that's no mem at all.
Maxim
13-May-2011
[8634x2]
when I look at the extensions model, the references to series are 
just pointers to a series payload. but the start, *is* part of the 
reference, not the series data.  since values are 128 bits, you can 
have the pointer to the series and its head in the same value.
hope this makes sense.
BrianH
13-May-2011
[8636x4]
Of course ++ and -- allocate error! values to trigger if they are 
called incorrectly, and the R2 version does a REDUCE as part of that 
error triggering call. But that's not the normal case.
Maxim, a series reference only contains a pointer to the internal 
series structure and either a pointer to the offset or a 32bit index 
(Carl could say which). The internal series structure could have 
a pointer to the start of the series, or it could be a header of 
the series data itself, depending on which is better for memory allocation. 
What you see in extensions are marshalled values, not regular R3 
stack frames or other value slots.
Command call frames are not made up of 128bit values, afaik, they 
are 64bit unions.
As for value slots, not all datatypes use all 128 bits. 32 bits are 
used for flags, and the payload could be 32 bits (as in char!), 64 
bits (series, integer, decimal) or up to 96 bits. The rest is wasted 
space. The value slots need to be the same size so you can set one 
of them to a different value without moving the rest in the block 
if that value is of a different type.
Maxim
13-May-2011
[8640]
yep. but we don't have the xtra information which links the data 
in the core, we only get the data.   in the extensions, we get a 
some sort of internal reference to the series and the index.   this 
is how I see it working in the core too.   there is ample room for 
this info in 128 bits.