Comments on: Picking the right PICK

Carl Sassenrath, CTO
REBOL Technologies
9-Feb-2009 17:16 GMT

Article #0173
Main page || Index || Prior Article [0172] || Next Article [0174] || 22 Comments || Send feedback

Today, while formatting R3 documents, I was jabbed by PICK:

In R2:

>> blk: [a b c d]
== [a b c d]
>> blk: skip blk 3
== [d]
>> pick blk -1
== c
>> pick blk 0
== none
>> pick blk 1
== d

But, in R3:

>> blk: [a b c d]
== [a b c d]
>> blk: skip blk 3
== [d]
>> pick blk -1
== b
>> pick blk 0
== c
>> pick blk 1
== d

The R3 change is an important improvement, because it makes PICK work smoothly... in a linear way.

However, is this too big a change? What do you think?



Brian Hawley
9-Feb-2009 13:34:38
I am a big fan of this change, and would prefer it be ported back to R2, though I know that won't happen. This is like the R2 DIR? bug. Please, try to avoid being bug-for-bug compatible with R2. This is our chance for a clean break.
9-Feb-2009 13:40:57
Seems a lot more logical to me!
Brian Hawley
9-Feb-2009 13:58:22
The off-by-one error of R2's PICK and POKE for negative numbers makes it so that you can't reliably use math to calculate the offsets without either forgoing negative offsets altogether or special-casing the code. It's a bad situation either way.

This is exactly the kind of thing we don't want to be compatible with.

9-Feb-2009 15:18:14
Pick change should affect also (but it doesn't):

pick next "1" 0 ;== none

change/part next x: [1] 'new 0 x ;== [1 new]

poke next x: [1] 0 'new

** Script Error: Value out of range: 0 ** Near: poke next x: [1] 0

insert/part x: [] next [1] 0 x ;== []

copy/part next [1] 0 ;== []

remove/part next x: [1] 0 x ;== [1]

other cases should exist both for string and for block.

Brian Hawley
9-Feb-2009 15:37:29
Slottery, all of the /part examples you give are not indexes, so they are not related.

The PICK and POKE examples are bugs, and recent ones at that. I'll submit a ticket.

Brian Hawley
9-Feb-2009 15:45:58
The /part option of various functions works in offsets (like SKIP), not indexes (like AT), so the change in PICK indexing wouldn't affect their behavior.
Brian Hawley
9-Feb-2009 16:09:31
Apparently the PICK and POKE bug is not new. It just affects strings, not blocks, so your third example is incorrect. Posted to CureCode ticket 608.
9-Feb-2009 16:13:39
Brian, the /part refinement works under R2 with indexes, at least in this case:

change/part next x: [1] 'new x x ; == [new]

(in R3 it seems buggy)

9-Feb-2009 16:29:18
The /part is not implemented yet in R3. It's simply ignored.
9-Feb-2009 16:35:22
Also it's good change. I don't know how others, but I don't use pick and poke much. It's faster to use the path notation:
>> tm 10000000 [pick blk 2]
== 0:00:01.782
>> tm 10000000 [blk/(2)]
== 0:00:00.938
>> tm 10000000 [blk/2]
== 0:00:00.641
Brian Hawley
9-Feb-2009 17:55:19
Oldes, look at the comments of CHANGE/part bug 490 - /part is not ignored.
Brian Hawley
9-Feb-2009 18:09:19
Slottery, in
change/part next x: [1] 'new x
that is not an index, that is a position. A position is a direct series reference, while indexes and offsets are numbers that are used to calculate positions relative to other positions. When a /part option is passed a series reference, it uses a position. When passed a number, it treats it like an offset.

An offset is a number that is added to a position to get another position. An index is like counting from a position, though with a base index meaning the position you are at. With 1-based indexing like REBOL has, the base is 1. In general, you add the base to the offset to get the index.

Most languages with 1-based indexing don't allow indexes less than 1 at all, but the ones that do (at least the well-designed ones) act like R3's new behavior.

You are right that CHANGE/part is buggy in R3, but it is not the bug you think. See the above link for the real bug.

Brian Hawley
9-Feb-2009 18:14:28
Oldes, Slottery, I messed up the link. The CHANGE/part bug and comments: 490
9-Feb-2009 19:05:43
Brian you can be logic about the differences between indexes, offsets and positions, but

1) I think they are too complex, too subtle and confusing.

2) You say that "0" in pick x 0 is an index. I say that an index 0 (and also a position 0) does not exist in R2 and in R3, so i can't understand what you say. Instead i see here a difference between the value 0 and the value 1 (-1) and a difference is an offset, not and index. But "0" in /part 0 (an offset) means 0 not -1. I find R3 solution not logic, confusing and hard to remember. I think that R2 is logic: 0 is an offset 0 for pick and also for /part.

Brian Hawley
9-Feb-2009 19:14:33
Oldes, not only is path syntax faster, it works properly, so we can use it until PICK and POKE get fixed :)

Note that AT also has the off-by-one error: Bug #609

Brian Hawley
9-Feb-2009 19:27:22
Slottery, I agree, it is too complex.

That is the price we pay for 1-based indexing. If we had 0-based indexing the base would be 0, so the offset and the index would be the same thing. Since it's not, we need to subtract the base from the index to get the offset.

Ironically enough, 1-based indexing was chosen because it was deemed easier to understand by beginning programmers. Too bad it makes everything more difficult for everyone else.

9-Feb-2009 19:32:38
3) what i like in R2: change/part 0 means "change nothing" (== insert) and pick 0 means "pick nothing" (== none!)
Brian Hawley
9-Feb-2009 19:42:10
No, PICK series none means pick nothing. That doesn't work? It's not supposed to.
11-Feb-2009 6:52:16
The R3 addition seems to be a bad decision. We are introducing zero based indexing and opening the can of worms ... I am curious what will functions like 'index? return in above case?
11-Feb-2009 7:13:46
Pekr, it does not appear to be zero based indexing. It just uses zero in a different way than before. When you "skip block N" and do a "first block", you will get the same value as "pick block 1". This is exactly like R2.

R3's version adds symmetry to let you pick negative offsets without disturbing the odd/evenness of the index. Offsets are easier to calculate with R3's version.

Perhaps it would be nice for Carl to write up an example where he used it.

Greg Schofield
12-Feb-2009 0:47:23
As a newbie -- I had tried to use pick once, could not make it do what I considered it should do -- never used it again.

The new pick seems sensible, logical and a lot less mysterious -- hope this comment helps.

maxim olivier-adlhoch
15-Feb-2009 0:08:52
R3 is better, though has to be explicitly documented.

New usage is more linear, but it IS a bit strange that 0 skips backwards... but that's a side effect of the oddity of using one-based indexing.

(at) Greg: I use pick all the time since it allows out of bound indexes to return none (which is a fast way to get a value and verify bounds in one command).

its the main advantage of using pick IMHO.

Post a Comment:

You can post a comment here. Keep it on-topic.


Blog id:



 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

Updated 25-Mar-2017 - Edit - Copyright REBOL Technologies -