Home   Archive   Permalink

comparing characters in a string with pick

Hi guys!
I'm having trouble understanding how Rebol is interpreting this instruction.
Let's say that I have two strings:
c: "rrrr" ;and
g: "rrrg"
I want to see if the last characters match or not using pick. So if I go...
either pick c 4 = pick g 4 [print "match"] [print "no match"]
I'm expecting a no match, because "r" does not equal "g". But I get a match. I also get a match if I try...
either (pick c 4 = pick g 4) [print "match"] [print "no match"]
How come pick c 4 = pick g 4 resolves to true? Only if I do
either (pick c 4) = (pick g 4) [print "match"] [print "no match"]
do I get the expected 'no match' result.
I thought that the parentheses were not really neccesary, yet I see that they change the interpretation in a way I don't understand.
Any insights?
The Little Rebol Rat

posted by:   The Little Rebol Rat       7-Sep-2019/13:55-7:00

Here's something to know about that's a bit odd about historical Rebol: PICK with a LOGIC! will give you the first item of something if true, and the second if false.
     >> block: [a < b > #c]
     >> pick block true
     == a
     >> pick block false
     == < b >
(I always thought that was questionable semantics. Why wouldn't false pick the last item? If this is a good idea at all, I'd think it should give some protections by erroring if the series had anything other than two items to pick from...)
But since it doesn't error, you are seeing this situation. This is because when the evaluator is grinding across an expression, infix operators like `=` only see one element to their left...and run greedily. What you're actually running is thus:
     either pick c (4 = pick g 4) [print "match"] [print "no match"]
That greedy equals concluded that the INTEGER! 4 was not equal to the CHAR! #"g". So you got `pick c false`, the second character of c, which was an #"r". All values but NONE! or logic FALSE! are conditionally truthy...hence you get the match branch running.
> The Little Rebol Rat
:-) If you're willing to stick around to grow to be a larger Rebol Rat despite oddities like this case, you'll perhaps see what makes Rebol addictive. Some camps (e.g. me) think addressing its "unsafe" aspects can be accomplished without compromising the fun parts...and it can be made even more fun:
Feel free to join the discourse forum, which focuses on "Ren-C":

posted by:   Fork       7-Sep-2019/14:45:59-7:00

Argh, I forgot that this forum can't have TAG! types in it without a problem. Let's try closing the tag I used:
Then change my example to
     >> block: [a "b" #c]
     >> pick block true
     == a
     >> pick block false
     == "b"
(While Nick's forum has its benefits by being a quite small script, it's not under development and has some unaddressed quirks!)

posted by:   Fork       7-Sep-2019/14:49:04-7:00

Thank you, Mr. Fork!
I truly appreciate the help. The information was very useful. Now I know why the code would go to true so quickly. Amazing how many different things worked together to produce this result.
Your information about infix operators was jaw-dropping. I rally though that Rebol was strict about evaluating from left to right. I changed the “=” for “equal?” and it worked like a charm without having to add parentheses:
>>either equal? pick g 4 pick c 4 [print "Match!"] [print "No match..."]
==No match...
I see now that pick can also use logic, which is very helpful with learning how this little bug came to be.
I’m really motivated to learn some more Rebol. I find it much more fun than the boring Scratch stuff we were doing at school. I don’t mind the quirks as long I can find explanations like yours.
Thank you for the help!
The Little Rebol Rat

posted by:   The Little Rebol Rat       8-Sep-2019/17:30:50-7:00

Glad to help...!
Infix is different in our "Ren-C" branch, and if you would like to read about what we call "enfix" it is here:

posted by:   Fork       11-Sep-2019/15:30:37-7:00



Type the reverse of this captcha text: "h t a p - t i l - o t"