confused by match semantics and $0 var
Postby bairui » Mon Jul 23, 2012 9:10 am
I've either found a bug in NL (10.4.3) or, more likely, a bug in my understanding of how its match semantics and the $0 variable work. In particular, I am having trouble with an example on the NL wikibooks site:
Given a sample list:
Code: Select all
(set 'planets '(("Mercury" (p-name "Mercury") (diameter 0.382) (moons 0))("Venus" (p-name "Venus")(diameter 0.949)(moons 10))("Earth" (p-name "Earth")(diameter 1)(moons 1))))
The example on the wiki page is:
Code: Select all
(set-ref-all '(moons ?) planets (if (> (last $0) 9) "lots" (last $0)) match)
But that doesn't seem to work for me. This seems to instead:
Code: Select all
(set-ref-all '(moons ?) planets (if (> (last $it) 9) '(moons "lots") $it) match)
I am confused with what is supposed to be stored in the $0 variable. It seems that the [*+?] capture is being ignored and $0 is being set to 1 regardless of the actual value in the list.
Code: Select all
(set-ref-all '(moons ?) planets $0 match)
Results in:
Code: Select all
(("Mercury" (p-name "Mercury") (diameter 0.382) (moons 1)) ("Venus" (p-name "Venus") (diameter 0.949) (moons 1)) ("Earth" (p-name "Earth") (diameter 1) (moons 1)))
Where the (moons 1) sublists boggle me. What have I missed here?
bairui
-----
Re: confused by match semantics and $0 var
Postby cormullion » Mon Jul 23, 2012 10:53 am
I think the wikibook is wrong. In newLISP version 9, I think the code worked as written, but I can't remember when $it was introduced. However, there are still some lingering errors in the wikibook, and you've found one of them. Sorry - but congratulations anyway... :)
To preserve the spirit of the original, you could probably use:
Code: Select all
(set-ref-all '(moons ?) planets (if (> (last $it) 9) '(moons "lots") $it) match)
But perhaps the whole section should be rewritten.
cormullion
-----
Re: confused by match semantics and $0 var
Postby bairui » Mon Jul 23, 2012 12:34 pm
Thanks, cormullion,
I gather you did most of the NL wikibook work. Awesome job, mate. I suspected the few glitches I've found along the way were due to API/lib changes as NL marched along. That's fair. It would be good to keep the wikibook resource as up to date there as we can. I patched it in a few small places today, but as I'm new to NL and lisp in general, I am hesitant to make bold changes.
I am still confused about the differences between $0 and $it. It seems that $it is working the way $0 did for you in version 9 (I came to NL only after it was well into version 10). $0 on the other hand seems... broken to my mind. I am happy to assume the breakage there is all mine though, so I'd like an explanation of how it works. (Lutz?)
bairui
-----
Re: confused by match semantics and $0 var
Postby Lutz » Mon Jul 23, 2012 2:26 pm
In set-ref-all the $0 variable is only set when regular expressions are involved. But $it is always set. The following example works with both $0 and $it
Code: Select all
> (set-ref-all ".*m.*" '("abmcd" "defg" "xymzw") (upper-case $0) regex)
("ABMCD" "defg" "XYMZW")
> (set-ref-all ".*m.*" '("abmcd" "defg" "xymzw") (upper-case $it) regex)
("ABMCD" "defg" "XYMZW")
>
All strings containing an "m" are upper-cased.
See also here for an explanation of anaphoric $it and other system variables:
Lutz
-----
Re: confused by match semantics and $0 var
Postby bairui » Mon Jul 23, 2012 2:39 pm
Thanks, Lutz.
Interestingly, $0 and $it behave differently when the regex matches less than the element:
Code: Select all
> (set-ref-all "m" '("abmcd" "defg" "xymzw") (upper-case $0) regex)
; ("M" "defg" "M")
> (set-ref-all "m" '("abmcd" "defg" "xymzw") (upper-case $it) regex)
; ("ABMCD" "defg" "XYMZW")
bairui
-----
Re: confused by match semantics and $0 var
Postby Lutz » Mon Jul 23, 2012 3:01 pm
Yes, because $0 referes to the matched sub-expression part, and $it to the entire element.