emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [External] : optional argument defaults in `cl-defun' vs old way - w


From: Drew Adams
Subject: RE: [External] : optional argument defaults in `cl-defun' vs old way - warning, discrepancy!
Date: Fri, 6 Oct 2023 13:54:02 +0000

> After changing 60 defun to cl-defun, maybe I have to change it
> all back since the Elisp way of thinking - where nil means
> "unset", i.e. use the default - that was the way I was
> thinking when I wrote the code, and it has worked ever since.
> And just now I run into an error which brought this all to
> my attention.
> 
> But in a way the CL way is better even here, since explicit
> nil really means nil, so one could use that as an optional
> argument value.
> 
> But then, how would that mix with other code, evaluating to
> nil and then being sent as argument. Is that an unset optional
> argument which should get a default value, or is it a
> set value, just as an explicit nil, only this time not written
> by a programmer, but computed by a program, written by
> a programmer?
> 
> Bottom line, the Elisp way is preferable since it is
> consistent - see the three (1 2) results below, compared to
> the CL ditto, with one (1 2) and two (nil nil).

I think what you really mean to say is that
`&optional foo' can convey something a bit
different to human readers, in terms of intent
than does `&optional (foo nil)`.

That's true.

But I wouldn't call the latter "the CL way" and the
former "the Elisp way".  The real CL way is to let
you use either/both.  From CLTL:

(lambda ({var}*
         [&optional {var | (var [initform [svar]])}*]
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         [&rest var]
         [&key {var | ({var | (keyword var)} [initform [svar]])}*
                [&allow-other-keys]]
         [&aux {var | (var [initform])}*)]
   [[{declaration}* | documentation-string]]
   {form}*)

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node64.html#SECTION00922000000000000000

E.g., &optional foo (bar nil),
      &optional (bar nil) foo,
      &optional foo (bar foo)

(I'm sure you realize this.  Just a nit about the
labeling as "the XXX way".)

And in fact the hint to humans mentioned above,
that arg presence might make a difference, is
less clear than making the possibility explicit.

As Adam pointed out, with CL you can provide an
SVAR for a VAR that has an explicit INITFORM, to
let both the body code and humans know whether
the optional arg was actually passed.  Just the
presence of an SVAR can give you a heads-up that
presence/absence might actually matter to the
behavior (body).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]