[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
subst-if-not and nsubst-if-not, programming folk-lore
Date: Sun, 6 Jul 86 14:48 EDT
From: Brad Miller <miller@UR-ACORN.ARPA>
Date: Sun, 29 Jun 86 19:42 EDT
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
These are really neat functions, and counterintuitive to boot. One of
our documentation people tried this:
[...]
Now, when one tries subst-if-not, one gets a small surprise
until one thinks about it a bit:
(let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar)))
(new (subst-if-not '3.1415 #'numberp item-list)))
(values new item-list))
=> 3.1415
(NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR))
and nsubst-if-not gives the same thing
[...]
, i.e., the list is NOT destructed. A careful reading explains why: the
item-list is indeed not a number, and therefore it gets substituted (but
you can't substitute the entire list, so you don't modify it).
What the person probably wanted is to replace the non-null atomic
leafs. I'm not sure what to think. One thing I'm thinking is that
(n)subst-if-not is too counter-intuitive to be worth having in the
language, even for completeness. At the very list, I think the
book/manual should carefully discuss this issue to people don't get
confused for years.
Good point. To point out the obvious: perhaps [n]subst-if-not should not
try to match subtrees? (which would include nil cdrs).....
That would still give a useful function on leaves.... Your example would
have been evaluated to:
(3.1415 (1.0 2 5/3) 3.1415 (3.1415 3.1415))
which is a bit more intuitive, I think, though not precisely an inverse
to subst-if, which as you suggested, can be quite non-intuitive (and
perhaps unnecessary)....
No, I think if [n]subst-if-not stay in the language then their
definitions should not change. Conses are just as valid as any other
data, and changing their definition could make them even more confusing.
I'm not (currently) advocating removing them from the language. I am
advocating documenting this pitfall. It may want to say that "we"
currently believe code is easier to write, undersetand and maintain if
[n]subst-if is used intead of [n]subst-if-not and give the example
(nsubst-if 3.1415 #'(lambda (item)
(and item
(atom item)
(not (numberp item))))
item-list)
The screw here is that NIL in the CAR isn't distinguished from NIL in
the CDR, which may be a more fundamental problem. Doing the CDR, even
though it may be NIL has several valid applications, so it shouldn't be
dismissed lightly.