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

World: r3wp

[!REBOL3]

BrianH
6-Jun-2011
[9036x5]
Option 4:

 NEXT and BACK will be constrained to the series tail, even if that 
 makes the (index? a) <= (index? next a) truism false.
I'm not advocating option 4, I was just making another option besides 
3 that made sense. Option 1 is what we have now.
Note that the other operations that are constrained to the tail of 
the series in R3 are PRINT and EMPTY?, which is why R2 gets that 
out-of-bounds error and R3 doesn't.
Also note that REMOVE/part with a negative part acts like REMOVE/part 
from the other point with a positive part. This is why it's impossible 
to create a before-the-head reference.
With Option 3 that would change, since BACK from the head of the 
series would go out of bounds. REMOVE out of bounds would continue 
to be a noop.
Geomol
6-Jun-2011
[9041]
This is something, I need to sleep on to have any useful opinion 
on. :)
BrianH
6-Jun-2011
[9042]
The off-by-one error for AT and non-positive indexes still has an 
unresolved ticket too. PICK and POKE were fixed, but not yet AT.
Geomol
7-Jun-2011
[9043x4]
Would a programmer expect this to be true always?

	(index? series) + (length? series) = (index? tail series)


That seems to define some basic rules for indexes and the functions 
involved. But it fails sometimes, as it is now:

>> s: [1 2]       
== [1 2]
>> t: tail s
== []
>> clear s
== []
>> (index? s) + (length? s) = (index? tail s)
== true
>> (index? t) + (length? t) = (index? tail t) 
== false


Problem here is, that LENGTH? t returns 0. It should return -2, if 
the result should be true.
In R2, it is true, but in R2, INDEX? t is also 1 in this case, which 
is also not good.
I noticed a funny thing, when inserting a series in the same series 
with the /only refinement.

>> s: [a b c]
== [a b c]
>> length? skip s 2
== 1				; makes sense
>> insert/only s skip s 2
== [a b c]
>> s

== [[...] a b c]		; reference to the same series is shown this way, 
ok
>> length? s/1
== 2				; unexpected

Wouldn't it be more logical, if that last result were 1?
It's the same in R2.
It's possible to create infinitely deep series with this:

>> s: [a b c]
== [a b c]
>> insert/only tail s s
== []
>> s
== [a b c [...]]
>> s/4
== [a b c [...]]
>> s/4/4
== [a b c [...]]
>> s/4/4/4
== [a b c [...]]

and so on.
Endo
7-Jun-2011
[9047x4]
No I think it is not unexpected. Because when you insert new values 
into a series its internal positions is changing:
b: [1 2 3 4 5] c: next b
insert b 0
index? c
== 2
in you example s/1 actually a pointer to s itself (the second value 
in s). and when you insert something into s, the pointer (which is 
s/1) is also moves forward.
>> same? head s/1 head s
== true

>> s/1

== [b c] ;which mean it still points to second value in the series.
so length is 2
Geomol
7-Jun-2011
[9051x4]
Hold on.
>> b: [1 2 3 4 5]
== [1 2 3 4 5]
>> c: next b
== [2 3 4 5]
>> index? c
== 2
>> insert b 0 
== [1 2 3 4 5]
>> index? c   
== 2
>> insert b 0 
== [0 1 2 3 4 5]
>> index? c   
== 2
Also look at:

>> s: "abc"
== "abc"
>> insert/only s skip s 2
== 		; some crap in R3, so check R2 here.
>> s
== "cabc"
In the last example, insert/only isn't needed, just insert.
Endo
7-Jun-2011
[9055]
That is because, c is not a series pointing to another (in this case 
same) series.
Geomol
7-Jun-2011
[9056x2]
Right.

For blocks, inserting doens't change position of other indexes to 
same series. What I expect, is that the insert is from the index 
given, before the insert is carried out. Like:

>> s: [a b c]
>> insert/only s skip s 2
should result in
	[[c] a b c]

, where the first element is a pointer to one before the end of s, 
not two before the end of s as we have today.
In other words, INSERT take two arguments, series and value. The 
value should be picked up before starting the insert, not after starting 
the insert. (If that makes sense.) :)
Endo
7-Jun-2011
[9058x3]
actually it does as you expect, in first phase.
Here is the trace log (R2)
>> s: [a b c]
== [a b c]
>> trace on
Result: (unset)
>> insert/only s skip s 2
Trace:  insert/only (path)
Trace:  s (word)
Trace:  skip (word)
Trace:  s (word)
Trace:  2 (integer)
Result: [c] (block)
it inserts [c] into s.
Ladislav
7-Jun-2011
[9061]
The value should be picked up before starting the insert, not after 
starting the insert. (If that makes sense.) :)
 - actually, it does not
Endo
7-Jun-2011
[9062x3]
But then, the internal pointer changes because of the insert.
>> head s/1
Trace:  head (word)
Trace:  s/1 (path)
Result: [[...] a b c] (block)
>> index? s/1
Trace:  index? (word)
Trace:  s/1 (path)
Result: 3 (integer)
>> s/1
Trace:  s/1 (path)
== [b c]
Geomol
7-Jun-2011
[9065x2]
Now I'm in doubt! Need to think some more. :)
I understand, what happens, that it's a position in a series, I try 
to insert earlier in the same series. I just find it a bit confusing, 
it works as it does. Woldn't it be more logical, if it's the position 
+ 1, that is inserted in such cases? I think, this looks strange:

>> s: [a b c d e f g h]
== [a b c d e f g h]
>> insert/only s find s 'd
== [a b c d e f g h]
>> s/1
== [c d e f g h]

It seems more logical to me, if it does this:

>> s: [a b c d e f g h]
== [a b c d e f g h]
>> insert/only s next find s 'd
== [a b c d e f g h]
>> s/1
== [d e f g h]
Ladislav
7-Jun-2011
[9067x2]
So, you prefer lists
You need to realize, that there are implementation differences between 
lists and blocks, and that they are "enforced" by the properties 
of the respective datatypes.
Geomol
7-Jun-2011
[9069x2]
hm, could be. :) Nah, blocks are very cool for many things. I think, 
both blocks and lists are useful though.
It's also interesting, that if /only isn't used, the result is what 
I first would expect:

>> s: [a b c d e f g h]
== [a b c d e f g h]
>> insert s find s 'd
== [a b c d e f g h]
>> s
== [d e f g h a b c d e f g h]
Ladislav
7-Jun-2011
[9071]
block: [1 2]
index? block ; == 1
insert block 0
index? block ; == 1

list: make list! [1 2]
index? list ; == 1
insert list 0
index? list ; == 2
Endo
7-Jun-2011
[9072x2]
without /only is more general use of course, but it is completely 
different. In your last example (Geomol) you get the values of a 
series and insert them into another series.
with /only you get a "pointer" to a series and put that "pointer" 
into another series. (I know "pointer" is not a correct word for 
this but you got the idea)
Geomol
7-Jun-2011
[9074]
What if I want to insert the tail position of a series earlier in 
the same series?

>> s: [1 2]
== [1 2]
>> insert/only s tail s
== [1 2]
>> s/1
== [2]
>> insert/only s next tail s
== [[...] 1 2]
>> s/1
== [2]

So that can't be done.
Endo
7-Jun-2011
[9075]
So you could have a series which holds "pointers" to other some positions 
in another series, even a position in itself.
Ladislav
7-Jun-2011
[9076]
s: make list! [1 2]
insert/only s tail s
s/-1 ; []
Geomol
7-Jun-2011
[9077]
Yes, works with list as expected.
Ladislav
7-Jun-2011
[9078]
It is not hard to find out, why it cannot work with blocks the same 
way
Geomol
7-Jun-2011
[9079]
It can't? Isn't that just a design desision?
Ladislav
7-Jun-2011
[9080]
It can't
Geomol
7-Jun-2011
[9081]
*decision*

ok, can you explain why or give an example, that clearly show it?
Ladislav
7-Jun-2011
[9082]
The above list example proves, that lists don't "know" their index, 
and have to calculate it every time, which means, that "index access" 
is slow.
Geomol
7-Jun-2011
[9083]
I think, this is only a problem with blocks, if you insert a later 
position earlier in the same block.
Ladislav
7-Jun-2011
[9084]
As opposed to that, blocks are designed for fast index access, so 
they have to "know" it, which means, that INSERT cannot change it
Geomol
7-Jun-2011
[9085]
I don't think, INSERT have to change position of some index, it just 
have to insert the next position than the one given, and only if 
insert is earlier in the same series.