Distinguish &optional argument with default value from no value
Asked Answered
L

1

7

According to Functions on GigaMonkeys, Common Lisp supports optional positional parameters via &optional and the default value can be set arbitrarily.

The default default value is nil.

(defun function (mandatory-argument &optional optional-argument) ... )

and the default value can be set arbitrarily

(defun function (mandatory-argument &optional (optional-argument "")) ....)

Is there a way of distinguishing the cases where the optional parameter has the default value explicitly passed in vs no value at all?

EDIT: evidently the page I linked explains this.

Occasionally, it's useful to know whether the value of an optional argument was supplied by the caller or is the default value. Rather than writing code to check whether the value of the parameter is the default (which doesn't work anyway, if the caller happens to explicitly pass the default value), you can add another variable name to the parameter specifier after the default-value expression. This variable will be bound to true if the caller actually supplied an argument for this parameter and NIL otherwise. By convention, these variables are usually named the same as the actual parameter with a "-supplied-p" on the end. For example:

(defun foo (a b &optional (c 3 c-supplied-p)) 
    (list a b c c-supplied-p))
Lidless answered 26/12, 2015 at 7:40 Comment(2)
This applies to keyword arguments too. E.g., see LISP: Keyword parameters, supplied-p.Tanika
This is answered in the same link you provided!Tera
A
14

According to the specification, you can add another variable name after the optional argument. This variable will be bound to t if the optional parameter is specified, and nil otherwise.

For instance:

CL-USER> (defun foo (mandatory &optional (optional1 nil optional1-supplied-p))
           (if optional1-supplied-p
               optional1
               mandatory))

FOO
CL-USER> (foo 3 4)
4
CL-USER> (foo 3)
3
CL-USER> (foo 3 nil)
NIL

In the first case the optional parameter is specified, so that it is produced as result of the function.

In the second case the optional parameter is not specified, and the result is the first parameter.

In the last case, even if the value of the optional parameter is equal to the default value, the function can distinguish that a parameter has actually been specified, and can return that value.

Amplifier answered 26/12, 2015 at 8:21 Comment(1)
A common naming convention is to use the p or -p suffix to name the provided indicator.Tanika

© 2022 - 2024 — McMap. All rights reserved.