Distinguish &optional argument with default value from no value - common-lisp

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))

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.

Related

Is it valid to use "setf" to create special variables?

It appears that I can use setf to create special variables. For example, if I start the REPL and enter (setf x 123), a special variable x will be created. There is no error in CLISP and ECL. SBCL gives a warning (undefined variable: COMMON-LISP-USER::X), but creates the special variable anyway. Is setf a valid way to create special variables?
It is not valid to use setf to create new variables. The HyperSpec is pretty clear that setf is only intended to update existing variables:
setf changes the value of place to be newvalue.
(setf place newvalue) expands into an update form that stores the result of evaluating newvalue into the location referred to by place.
setf is intended for updating a place. There is no behavior specified for attempting to use setf to update the value of a place that does not already exist.
In the section which discusses assignment, CLTL2 says a bit more:
Such alteration is different from establishing a new binding. Constructs for establishing new bindings of variables are described in section 7.5.
While this may seem to work, you can't rely on it. It often works in REPLs, and it is fine if you want to use setf this way when playing around in a REPL, but you should not do this in any program.
Actually it is a bit tricky.
This is one of the things in Common Lisp which are underspecified. Unfortunately.
LispWorks:
CL-USER 61 > (setf foo 1)
1
CL-USER 62 > (defun bar () foo)
BAR
CL-USER 63 > (bar)
1
CL-USER 64 > (let ((foo 2))
(bar))
1
The last foo in the let is using lexical binding and thus there it is not assumed to be special.
In the forms (setf foo 1) and (defun bar () foo) the variable foo is assumed by the particular Lisp implementation to be special and it even could be declared to be special by setf (-> which most implementations don't).
Whether above let form returns 1 or 2 is unspecified in the Common Lisp language standard. Most implementations will return 1, though.
Next:
CL-USER 65 > (let ((foo 2))
(declare (special foo))
(bar))
2
Above we see that the use of foo inside bar is actually using the dynamic binding of foo in the let.
Basically the exact effects of setting an undefined variable is unspecified. The variable could be assumed to be special or not. Most implementations prefer to NOT declare it special, such that further use of the variable must be special.
But whether the variable is special or not, and the exact effects using it, is actually undefined in the Common Lisp language standard.
Most implementations agree
that setf setting an undefined variable only changes the symbol value of the symbol
that setting and retrieving the variable is assuming a special variable
that rebinding the variable by let(or similar) does not create a special variable
that a compiler (if used) will warn about an undefined variable and/or about assuming a special variable.
One implementation where the default disagrees is CMUCL -> there the setf also declares the variable to be special, similar to what defparameter would do.
For a general style rule see the last paragraph of ad absurdum's answer.

What is the meaning of the "explicit-check" declaration identifier in SBCL?

In the source code of SBCL's y-or-n-p, I see (declare (explicit-check)):
(defun y-or-n-p (&optional format-string &rest arguments)
"..."
(declare (explicit-check))
(flet ((print-query ()
(apply #'maybe-print-query "(y or n)" format-string arguments)))
(loop (print-query)
(case (query-read-char)
((#\y #\Y) (return t))
((#\n #\N) (return nil))
(t (clarify-legal-query-input "y" "n"))))))
What does explicit-check do? It is not listed as a standard declaration identifier in the HyperSpec, so it is probably implementation-defined. However, I don't see any mention of explicit-check in the SBCL manual.
Based on the following sources in the code, it appears that explicit-check indicates that the types associated with function parameters, as declared by an FTYPE declaration, are not automatically checked but checked explicitly (manually).
This avoids having redundant checks when some function f dispatches on type of one argument a to a specialized function f_a whose signature is declared by FTYPE. Without the explicit-check in f_a, the type of a would be checked twice, once during type dispatch, and once when entering the function.
src/compiler/ir1-translators.lisp
;;; Check a new global function definition for consistency with
;;; previous declaration or definition, and assert argument/result
;;; types if appropriate. This assertion is suppressed by the
;;; EXPLICIT-CHECK attribute, which is specified on functions that
;;; check their argument types as a consequence of type dispatching.
;;; This avoids redundant checks such as NUMBERP on the args to +, etc.
;;; FIXME: this seems to have nothing at all to do with adding "new"
;;; definitions, as it is only called from IR1-CONVERT-INLINE-EXPANSION.
src/compiler/ctype.lisp
(warn "Explicit-check without known FTYPE is meaningless")
package-data-list.lisp-expr
;; Advice to the compiler that it doesn't need to assert types.
"EXPLICIT-CHECK"
src/compiler/ir1tran.lisp
;; EXPLICIT-CHECK by itself specifies that all argument and
;; result types are checked by the function body.
In the context of y-or-n-p, the intent is to have types checked only once. It could be done early, e.g. at the beginning of y-or-n-p, which would then call "unsafe" functions which do not check their type, but this is not the case here.
Instead, the function is defined with defknown, which executes the following code:
(setf (info :function :type name) type-to-store)
(see src/compiler/knownfun.lisp)
This is the same effect, if I am not mistaken, as having an FTYPE declared for the function (both ftype and defknown set this info slot).
But, here y-or-n-p does not need to check the type itself, since it mostly delegates to another function, namely maybe-print-query. That function calls format, which is also declared explicit-check.
The first thing it does is to etypecheck the destination argument, in order to dispatch the call to format to different invocations of %format, which in turns also branches out to different outcomes based on the type of the next argument (a control string or a formatter function).
So in practice, checking the type of the arguments is interleaved with dispatching, because there are a lot of corner cases to consider.
A top-down approach where the input types are checked first then passed down to unsafe functions would need to perform some complex type checking step too, and then it would still require to dispatch based on the argument types. That's probably why type checking is delayed until the code reaches the different special cases.

Symbol names undefined variable

I have a question concerning the relation between symbols and global variables.
The hyperspec states for the value attribute of a symbol:
"If a symbol has a value attribute, it is said to be bound, and that fact can be detected by the function boundp. The object contained in the value cell of a bound symbol is the value of the global variable named by that symbol, and can be accessed by the function symbol-value."
If I apply the following steps:
CL-USER> (intern "*X*")
*X*
NIL
CL-USER> (boundp '*x*)
NIL
CL-USER> (setf (symbol-value '*x*) 1)
1
CL-USER> (boundp '*x*)
T
as I understand the above cited conditions are fulfilled. There should be a global variable named by the symbol and the value of the variable is the symbol-value. But this is wrong.
CL-USER> (describe '*x*)
COMMON-LISP-USER::*X*
[symbol]
*X* names an undefined variable:
Value: 1
; No value
CL-USER>
It has to be proclaimed special.
CL-USER> (proclaim '(special *x*))
; No value
CL-USER> (describe '*x*)
COMMON-LISP-USER::*X*
[symbol]
*X* names a special variable:
Value: 1
; No value
CL-USER>
Can you please explain this behaviour. What means an "undefined variable", I did not find this term in the hyperspec.
(I use SBCL 1.3.15.)
Thank you for your answers.
Edit:
(Since this comment applies to both answers below (user Svante and coredump), I write it as an Edit and not as a comment to both answers).
I agree with the answers that * x* is a global variable.
The hyperspec states for global variable:
"global variable n. a dynamic variable or a constant variable."
Therefore I think now, the reason why SBCL says it is "undefined" is not whether is special, but whether it is a dynamic (special) variable or a constant variable (hyperspec:"constant variable n. a variable, the value of which can never change").
The third definition which is mentioned in the below answers (maybe I understand the answers wrong), that it is a global variable which is not special (and not a constant) does not exist according to the hyperspec.
Can you agree with that?
Edit 2:
Ok, in summary, I thought, since the hyperspec does not define undefined global variables, they do not exist.
But the correct answer is, they do exist and are undefined, that means it is implementation dependent how it is dealt with them.
Thank you for your answers, I accept all three of them, but I can only mark one.
There is a global variable named by the symbol, and its value is the symbol-value. That is what the output tells you. The thing that is undefined is the status of the variable: whether it is special. I agree that the wording of the output is a bit special.
If you set the value of a variable without creating it first (which is what a naked setq would do as well), it is undefined whether it becomes special or not.
Conventionally, one does not use global variables that are not special. That's why you should use defvar, defparameter etc..
As said in the other answer(s), *X* is not declare special (dynamic). SBCL also gives you a warning if your lexically bind the symbol:
FUN> (let ((*X* 30)) (list *X* (symbol-value '*X*)))
; in: LET ((*X* 30))
; (LET ((FUN::*X* 30))
; (LIST FUN::*X* (SYMBOL-VALUE 'FUN::*X*)))
;
; caught STYLE-WARNING:
; using the lexical binding of the symbol (FUN::*X*), not the
; dynamic binding, even though the name follows
; the usual naming convention (names like *FOO*) for special variables
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
(30 10)
Note also what happens if *X* is locally declared as special:
FUN> (let ((*X* 30)) (declare (special *X*)) (list *X* (symbol-value '*X*)))
(30 30)
The symbol-value accessor retrieves the binding from the dynamic environment.
global variable which is not special (and not a constant) does not exist according to the hyperspec.
The actual behaviour is undefined in the standard, but in implementations it might work in some way.
This example in LispWorks:
CL-USER 46 > (boundp 'foo)
NIL
So FOO is unbound.
CL-USER 47 > (defun baz (bar) (* foo bar))
BAZ
The above defines a function baz in the LispWorks interpreter - it is not compiled. There is no warning.
Now we set this symbol foo:
CL-USER 48 > (setq foo 20)
20
CL-USER 49 > (baz 22)
440
We have successfully called it, even though FOO was not declared as a global function.
Let's check, if it is declared as special:
CL-USER 50 > (SYSTEM:DECLARED-SPECIAL-P 'foo)
NIL
Now we compile the function from above:
CL-USER 51 > (compile 'baz)
;;;*** Warning in BAZ: FOO assumed special
BAZ
The compiler says that it does not know of FOO and assumes that it is special.
This behaviour is undefined and implementations differ:
an interpreter might just use the global symbol value and not complain at all - see the LispWorks example above. That's relatively common in implementations.
a compiler might assume that the undefined variable is a special variable and warns. This is also relatively common in implementations.
a compiler might assume that the undefined variable is a special variable and also declare the variable to be special. This is not so common - the CMUCL did (does?) that by default. This behaviour is not common and not liked, since there is no standard way to undo the declaration.

Neither a function nor a macro would do

Consider this question. Here the basic problem is the code:
(progv '(op arg) '(1+ 1)
(eval '(op arg)))
The problem here is that progv binds the value to the variable as variable's symbol-value not symbol-function. But, that's obvious because we didn't explicitly suggest which values are functions.
The Plan
So, in order to solve this problem, I thought of manually dynamically binding the variables, to their values based on the type of values. If the values are fboundp then they should be bound to the symbol-function of the variable. A restriction, is that match-if can't be a macro. It has to be a function, because it is called by a funcall.
Macro : functioner:
(defmacro functioner (var val)
`(if (and (symbolp ',val)
(fboundp ',val))
(setf (symbol-function ',var) #',val)
(setf ,var ,val)))
Function: match-if:
(defun match-if (pattern input bindings)
(eval `(and (let ,(mapcar #'(lambda (x) (list (car x))) bindings)
(declare (special ,# (mapcar #'car bindings)))
(loop for i in ',bindings
do (eval `(functioner ,(first i) ,(rest i))))
(eval (second (first ,pattern))))
(pat-match (rest ,pattern) ,input ,bindings))))
Here, the let part declares all the variables lexically (supposedly). Then declare declares them special. Then functioner binds the variables and their values aptly. Then the code in the pattern is evaluated. If the code part is true, then only the pattern-matcher function pat-match is invoked.
The Problem
The problem is that in the function, all it's arguments are evaluated. Thus bindings in the let and declare parts will be replaced by something like :
((v1 . val1)(v2 . val2)(v3 . val3))
not
'((v1 . val1)(v2 . val2)(v3 . val3))
So, it's treated as code, not a list.
So, I'm stuck here. And macros won't help me on this one.
Any help appreciated.
Not the answer you are looking for, but PROGV is a special operator; it is granted the ability to modify the dynamic bindings of variables at runtime; AFAIK, you can't simply hack it to operate on "dynamic function bindings".
The point of progv is to use list of symbols and values that are evaluated, meaning that you can generate symbols at runtime and bind them dynamically to the corresponding values.
You might be able to find a solution with eval but note that if you macroexpand into (eval ...), then you loose the surrounding lexical context, which is generally not what you want ("eval" operates on the null lexical environment). I speculate that you could also have a custom code walker which works on top-level forms but reorganizes them, when it finds your special operator, to bring the context back in, producing something like (eval '(let (...) ...)).

How to call particular function depending on variable that's passed in?

I'm fairly new to lisp but I've been playing around with it. I have several problems which I need clarifying. Below is my little macro that I defined.
(defmacro transform (query)
'(lambda (row)
(eq (nth 1 query) (nth 0 (nth 0 row)))
)
)
I'm just wondering how I can specify the function to use in the body dynamically? Say if I want to use the "+" or "-" function instead of "eq", or even another function that I defined? Like I thought it'd be possible to pass in the name of the function as a parameter but that obviously doesn't work. I also get variable unbound errors when I modify the list (query) that's passed in.
In the body of the macro, you can use all of Lisp's run-time library to generate the actual expansion. So, for example:
(defmacro transform (query &key (test 'eq))
(let ((row-var (gensym)))
`(lambda (,row-var)
(,test (nth 1 ,query) (nth 0 (nth 0 ,row-var))))))
This version uses the "backtick" instead of a plain apostrophe, which allows for "unquoting" of forms within the body, thus allowing the inclusion of generated forms into the result.
You can use this macro like your original version:
(transform (...))
or (passing an explicit test function):
(transform (...) :test equal)
Note, that you should not use plain symbols as variable names in macro expansions (as your row argument to the generated lambda expression) as that might accidentally interfer with the use of that symbol at the site of the use of your macro. You simply don't know when writing your macro, whether there will be a variable called row somewhere when your macro is used, and whether it is not already used within the query form/expression. Your original definition would "capture" the variable, possibly altering the meaning of whatever query does.
funcall is the answer! Decided to just pass it in and use funcall to evaluate the function.

Resources