I know that def* can have docstrings, so I just give lambdas a try.
Embarrassingly, The following returns NIL.
(documentation (lambda () "a function which always returns nil" nil) 'function)
What's wrong? Can't lambdas have docstrings? Is there a way to do it?
According to the HyperSpec section Symbol LAMBDA, the syntax is:
lambda lambda-list [[declaration* | documentation]] form*
so a doc-string is clearly allowed. Standard Generic Function DOCUMENTATION, (SETF DOCUMENTATION) lists two of the standard method signatures as:
documentation (x function) (doc-type (eql 't))
documentation (x function) (doc-type (eql 'function))
which match the way you tried to call it.
However, the function description includes the following caveat:
Documentation strings are made available for debugging purposes. Conforming programs are permitted to use documentation strings when they are present, but should not depend for their correct behavior on the presence of those documentation strings. An implementation is permitted to discard documentation strings at any time for implementation-defined reasons.
So while it's not technically a bug that the doc strings are not saved in your case, it's a poor implementation.
As Barmar said, this is possible, but optional.
CLISP and SBCL support documentation strings for anonymous lambda functions.
CCL, ECL and LispWorks don't.
Related
i don't know why NOT is defined as function but macro.i've heard that function call may be cache-unfriendly.
will it be better if NOT is a macro?the only reason i can think of is that a NOT function can be passed as value by adding #'.
grateful for your answers!
not has the semantics of a function: its argument is evaluated perfectly normally (unlike, say, and and so on). It should therefore be a function: macros should be used only for things which cannot semantically be functions.
Making not a function has benefits: simply because it is a function you don't need to write your own version every time you need a function with the semantics of not. Making not a function also has zero cost since the semantics of CL leave a compiler or interpreter entirely free to never actually call the function but rather generate inline code.
Indeed you can see, for instance, in the SBCL sources that this is happening: in src/code/pred.lisp you will find
(defun not (object)
"Return T if X is NIL, otherwise return NIL."
(not object))
You can do this yourself, pretty much:
(declaim (inline neg))
(defun neg (x)
(if x nil t))
(And if you are really feeling your oats define a compiler macro as well, although I can't see any strong reason to do that here.)
I'm interested in knowing what &allow-other-keys is supposed to do. I'm getting shockingly few references to it and no real definitions when I consult all documentation I can get my hands on. Best I can figure out is that it's effectively an error handling bit of code that you can put after &key to suppress the checking of key arguments when the macro is being called. For reference, this is where I found it:
(defmacro macro-name ((passed-variable
&rest open-args
&key &allow-other-keys)
&body body)
...)
&allow-other-keys is well documented: it suppresses Keyword Argument Checking.
In your example, it makes (macro-name (foo :bar 1) ...) an acceptable invocation of macro-name.
Although I think sds's answer is the right one, it's worth perhaps giving an example what is probably the canonical use-case for &allow-other-keys:
(defun open-unsigned-byte (f &rest kws &key &allow-other-keys)
(apply #'open f :element-type 'unsigned-byte kws))
This function wants to let open have whatever keyword arguments it takes, possibly including non-standard ones, but wants to make sure that the element-type is unsigned-byte, and that all the additional arguments passed to open are keyword arguments. This works because in the case of duplicated keyword arguments (which are legal) the leftmost one wins.
I'm trying to learn and understand the Lisp programming language to a deep level. The function + evaluates its arguments in applicative order:
(+ 1 (+ 1 2))
(+ 1 2) will be evaluated and then (+ 1 3) will be evaluated, but the if function works differently:
(if (> 1 2) (not-defined 1 2) 1)
As the form (not-defined 1 2) isn't evaluated, the program doesn't break.
How can the same syntax lead to different argument evaluation? How is the if function defined so that its arguments aren't evaluated?
if is a special operator, not an ordinary function.
This means that the normal rule that the rest elements in the compound form are evaluated before the function associated with the first element is invoked is not applicable (in that it is similar to macro forms).
The way this is implemented in a compiler and/or an interpreter is that one looks at the compound form and decides what to do with it based on its first element:
if it is a special operator, it does its special thing;
if it is a macro, its macro-function gets the whole form;
otherwise it is treated as a function - even if no function is defined.
Note that some special forms can be defined as macros expanding to other special forms, but some special forms must actually be present.
E.g., one can define if in terms of cond:
(defmacro my-if (condition yes no)
`(cond (,condition ,yes)
(t ,no)))
and vice versa (much more complicated - actually, cond is a macro, usually expanding into a sequence of ifs).
PS. Note that the distinction between system-supplied macros and special operators, while technically crisp and clear (see special-operator-p and macro-function), is ideologically blurred because
An implementation is free to implement a Common Lisp special operator
as a macro. An implementation is free to implement any macro operator
as a special operator, but only if an equivalent definition of the
macro is also provided.
sds's answer answers this question well, but there are a few more general aspects that I think are worth mentioning. As that answer and others have pointed out, if, is built into the language as a special operator, because it really is a kind of primitive. Most importantly, if is not a function.
That said, the functionality of if can be achieved using just functions and normal function calling where all the arguments are evaluated. Thus, conditionals can be implemented in the lambda calculus, on which languages in the family are somewhat based, but which doesn't have a conditional operator.
In the lambda calculus, one can define true and false as functions of two arguments. The arguments are presumed to be functions, and true calls the first of its arguments, and false calls the second. (This is a slight variation of Church booleans which simply return their first or second argument.)
true = λ[x y].(x)
false = λ[x y].(y)
(This is obviously a departure from boolean values in Common Lisp, where nil is false and anything else is true.) The benefit of this, though, is that we can use a boolean value to call one of two functions, depending on whether the boolean is true or false. Consider the Common Lisp form:
(if some-condition
then-part
else-part)
If were were using the booleans as defined above, then evaluating some-condition will produce either true or false, and if we were to call that result with the arguments
(lambda () then-part)
(lambda () else-part)
then only one of those would be called, so only one of then-part and else-part would actually be evaluated. In general, wrapping some forms up in a lambda is a good way to be able delay the evaluation of those forms.
The power of the Common Lisp macro system means that we could actually define an if macro using the types of booleans described above:
(defconstant true
(lambda (x y)
(declare (ignore y))
(funcall x)))
(defconstant false
(lambda (x y)
(declare (ignore x))
(funcall y)))
(defmacro new-if (test then &optional else)
`(funcall ,test
(lambda () ,then)
(lambda () ,else)))
With these definitions, some code like this:
(new-if (member 'a '(1 2 3))
(print "it's a member")
(print "it's not a member"))))
expands to this:
(FUNCALL (MEMBER 'A '(1 2 3)) ; assuming MEMBER were rewritten
(LAMBDA () (PRINT "it's a member")) ; to return `true` or `false`
(LAMBDA () (PRINT "it's not a member")))
In general, if there is some form and some of the arguments aren't getting evaluated, then the (car of the) form is either a Common Lisp special operator or a macro. If you need to write a function where the arguments will be evaluated, but you want some forms not to be evaluated, you can wrap them up in lambda expressions and have your function call those anonymous functions conditionally.
This is a possible way to implement if, if you didn't already have it in the language. Of course, modern computer hardware isn't based on a lambda calculus interpreter, but rather on CPUs that have test and jump instructions, so it's more efficient for the language to provide if a primitive and to compile down to the appropriate machine instructions.
Lisp syntax is regular, much more regular than other languages, but it's still not completely regular: for example in
(let ((x 0))
x)
let is not the name of a function and ((x 0)) is not a bad form in which a list that is not a lambda form has been used in the first position.
There are quite a few "special cases" (still a lot less than other languages, of course) where the general rule of each list being a function call is not followed, and if is one of them. Common Lisp has quite a few "special forms" (because absolute minimality was not the point) but you can get away for example in a scheme dialect with just five of them: if, progn, quote, lambda and set! (or six if you want macros).
While the syntax of Lisp is not totally uniform the underlying representation of code is however quite uniform (just lists and atoms) and the uniformity and simplicity of representation is what facilitates metaprogramming (macros).
"Lisp has no syntax" is a statement with some truth in it, but so it's the statement "Lisp has two syntaxes": one syntax is what uses the reader to convert from character streams to s-expressions, another syntax is what uses the compiler/evaluator to convert from s-expressions to executable code.
It's also true that Lisp has no syntax because neither of those two levels is fixed. Differently from other programming languages you can customize both the first step (using reader macros) and the second step (using macros).
It would not make any sense to do so. Example: (if (ask-user-should-i-quit) (quit) (continue)). Should that quit, even though the user does not want to?
IF is not a function in Lisp. It is a special built-in operator. Lisp a several built-in special operators. See: Special Forms. Those are not functions.
The arguments are not evaluated as for functions, because if is a special operator. Special operators can be evaluated in any arbitrary way, that's why they're called special.
Consider e.g.
(if (not (= x 0))
(/ y x))
If the division was always evaluated, there could be a division by zero error which obviously was not intended.
If isn't a function, it's a special form. If you wanted to implement similar functionality yourself, you could do so by defining a macro rather than a function.
This answer applies to Common Lisp, but it'll probably the same for most other Lisps (though in some if may be a macro rather than a special form).
Are there any practical differences between special forms and macros? In what do they differ?
The terms aren't quite synonymous, but they aren't exclusive either (this answer assumes Scheme):
A special form (also known as a syntax in the Scheme Reports) is an expression that's not evaluated according to the default rule for function application. (The default rule, just to be explicit, is to eval all of the subexpressions, and then apply the result of the first one to the list of the results of the others.)
The macro system is a language feature that allows definition of new special forms within the language itself. A macro is a special form defined using the macro system.
So you could say that "special form" is a term that pertains to interface or semantics, whereas "macro" is a term that pertains to implementation. "Special form" means "these expressions are evaluated with a special rule," while "macro" means "here's an implementation of a special rule for evaluating some expressions."
Now one important thing is that most Scheme special forms can be defined as macros from a really small core of primitives: lambda, if and macros. A minimal Scheme implementation that provides only these can still implement the rest as macros; recent Scheme Reports have made that distinction by referring to such special forms as "library syntax" that can be defined in terms of macros. In practice, however, practical Scheme systems often implement a richer set of forms as primitives.
Semantically speaking, the only thing that matters about an expression is what rule is used to evaluate it, not how that rule is implemented. So in that sense, it's not important whether a special form is implemented as a macro or a primitive. But on the other hand, the implementation details of a Scheme system often "leak," so you may find yourself caring about it...
Lisp has certain language primitives, which make up Lisp forms:
literal data: numbers, strings, structures, ...
function calls, like (sin 2.1) or like ((lambda (a b) (+ a b 2)) 3 4)
special operators used in special forms. These are the primitive built-in language elements. See Special Operators in Common Lisp. These need to be implemented in the interpreter and compiler. Common Lisp provides no way for the developer to introduce new special operators or to provide your own version of these. A code parsing tool will need to understand these special operators; these tools are usually called 'code walkers' in the Lisp community. During the definition of the Common Lisp standard, it was made sure that the number is very small and that all extensions otherwise are done via new functions and new macros.
macros: macros are functions which are transforming source code. The transformation will happen recursively until no macro is left in the source code. Common Lisp has built-in macros and allows the user to write new ones.
So the most important practical difference between special forms and macros is this: special operators are built-in syntax and semantics. They can't be written by the developer. Macros can be written by the developer.
In contrast to special forms, macro forms can be macroexpanded:
CL-USER(1): (macroexpand '(with-slots (x y z)
foo
(format t "~&X = ~A" x)))
(LET ((#:G925 FOO))
(DECLARE (IGNORABLE #:G925))
(DECLARE (SB-PCL::%VARIABLE-REBINDING #:G925 FOO))
#:G925
(SYMBOL-MACROLET ((X (SLOT-VALUE #:G925 'X))
(Y (SLOT-VALUE #:G925 'Y))
(Z (SLOT-VALUE #:G925 'Z)))
(FORMAT T "~&X = ~A" X)))
T
For me the most practical difference has been in the debugger: Macros don't show up in the debugger; instead, the (typically) obscure code from the macro's expansion shows up in the debugger. It is a real pain to debug such code and a good reason to ensure your macros are rock solid before you start relying upon them.
the super short answer for the lazy
You can write your own macroes any time you want, though you can't add special forms without recompiling clojure.
Take this function:
(defun sum-greater (x y z)
(> (+ x y) z))
It's my understanding that in LISP the first element in a list always represents a function to be performed on the subsequent atoms/lists. So why doesn't LISP treat the x in (x y z) as a function to be performed on y and z. Clearly this would not be desirable behavior, but it would be the expected behavior.
Presumably the function that defines defun somehow overrides the standard LISP evaluation of a list? If so, could you detail this?
Thanks
IIRC in Common Lisp at least defun is a macro (HyperSpec), meaning it may define any evaluation strategy whatsoever for its arguments.
defun is special because it is a macro. And since macros can be implementation dependent, all sorts of black magic can happen beneath the hood.
Lisp HyperSpec (Common Lisp) says, and I quote: "None of the arguments are evaluated at macro expansion time".
Your presumption is correct. Defun is commonly a special form or macro
You can download here a basic introduction into Lisp:
Common Lisp: A Gentle Introduction to Symbolic Computation, by David S. Touretzky.
Lisp and especially Common Lisp has several Lisp forms:
function calls
macro calls
special forms
DEFUN is a macro. Thus the macro defines which parts are evaluated and which not. For ANSI Common Lisp this is defined in the standard and implemented by the DEFUN macro.
defun is not a function, but a special form (or boils down to one), and for these, evaluation mechanics are different. Similar examples would be if, where one of the arguments is even discarded entirely without being evaluated at all!