World: r3wp
[!REBOL3]
older newer | first last |
Ladislav 6-Jun-2011 [9012] | Now, what do you think about the behaviour? Do you find it useful? (I do not) |
Geomol 6-Jun-2011 [9013] | The more I think about it, I tend to not like it. It must be up to the user to be sure, the indexes are in bound when used. It's really cryptic code required to make this work. |
Ladislav 6-Jun-2011 [9014] | BTW, "Let's say, my index is way beyond the tail, and I insert a new element there." - in fact, I was right saying that the operations was not supported, since it did not insert a new element there |
Geomol 6-Jun-2011 [9015] | yeah :) |
BrianH 6-Jun-2011 [9016] | Only the part with the behavior of SKIP might be an accident. The rest was the result of a blog discussion over two years ago, which iirc happened while Ladislav was taking a break from REBOL. |
Ladislav 6-Jun-2011 [9017] | In my opinion, this is clearly unsettled (BACK vs. SKIP), and was not discussed before |
BrianH 6-Jun-2011 [9018] | No, SKIP wasn't discussed. The rest was. |
Ladislav 6-Jun-2011 [9019] | So, the above mentioned INSERT behaviour was discussed? |
BrianH 6-Jun-2011 [9020] | I think so, but it was in that private world where Carl's GUI for R3 was being worked on with Henrik and me. It looks like INSERT works like SKIP. |
Ladislav 6-Jun-2011 [9021x2] | In R2, indexes are constrained to the bounds of the series they reference, so if you shorten the series you lose your position - this is provably false |
(and the proof is quite old) | |
BrianH 6-Jun-2011 [9023x2] | I was simplifying to avoid having to write a bunch of test code when my time is limited. Any proofs are welcome, though maybe the R2 proofs should go in Core. |
The word "constrained" was a simplification of the real process. | |
Ladislav 6-Jun-2011 [9025] | The proof exists, welcome or unwelcome, to demonstrate the actual properties of the interpreter, and to prove why the behaviour of some function is unuseful. |
BrianH 6-Jun-2011 [9026] | Yup, especially for R2. |
Ladislav 6-Jun-2011 [9027] | http://www.rebol.net/wiki/Identity#Indices_of_series |
BrianH 6-Jun-2011 [9028x2] | It would be possible and in keeping with the metaphor to have an out-of-bounds INSERT pad blocks with none values, but since strings and binaries don't have a way to have inline nones, that would make the behavior of blocks inconsistent. That is why INSERT behaves the way it does. If you want INSERT to trigger an error in that case, like POKE and set-path modification, that would make sense too. |
Or we could just say that INSERT, APPEND, SKIP, AT and LENGTH? are constrained to bounds, while PICK, POKE, and the ordinals and path accesses that are based on them are not. | |
Ladislav 6-Jun-2011 [9030x3] | OK, that is why the "INSERT *there*" operation is, in fact, unsupported, and, in such cases, it is preferable to trigger an error, in my opinion |
APPEND is clearly a different case than INSERT, since APPEND always uses the tail | |
regarding the incompatibility of SKIP -1 and BACK - I am not sure, whether that is good to have. | |
BrianH 6-Jun-2011 [9033] | I think that the incompatibility of NEXT and BACK is more important, and definitely an error, and an accident. >> a: [1 2 3] == [1 2 3] >> b: skip a 2 == [3] >> remove/part a 3 == [] >> index? b == 3 >> index? next b == 3 ; constrained to the argument index, not even the series bounds >> index? back b == 2 ; not constrained to the series bounds >> index? back a == 1 ; constrained to the head |
Geomol 6-Jun-2011 [9034x2] | Option 1: NEXT will not advance, if at tail or beyond tail. Option 2: NEXT will not advance, if at tail, but will if beyond tail. Option 3: NEXT will always advance. |
And if it will not advance in some cases, should it then trigger an error, if that is tried to do? | |
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 |
older newer | first last |