[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: subst-if-not and nsubst-if-not, programming folk-lore
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.
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))
(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).
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
I think this would be a bad idea. Consistency is important. Everywhere else
that there are two functions that differ only by a -not in the name of
one, the only difference in the semantics is to reverse the test. This is
as it should be.
Conceptually, there are four possible subst-if-like functions, depending on
whether the the test is positive or negative and whether the substitution applies
to subtrees or only to leaves. These could have names like subst-if, subst-if-not,
leaf-subst, and leaf-subst-if-not. If you think that the only two of these
worthy of being part of common lisp are subst-if and leaf-subst-if-not, I
would disagree with you, but not strongly. If you think that these functions
should exist under the names subst-if and subst-if-not, and everyone should
remember that -not automatically implies leaf-, I would disagree with you
leaf-subst-if and its relatives might be useful, but they're easy
to simulate with test functions like
(lambda (foo) (and (atom foo) (whatever foo))),
though this would match nil cdr's. Do we really need them?