At the moment I'm working through "Practical Common Lisp" from Peter Seibel.
In the chapter "Practical: A Simple Database" (http://www.gigamonkeys.com/book/practical-a-simple-database.html) Seibel explains keyword parameters and the usage of a supplied-parameter with the following example:
(defun foo (&key a (b 20) (c 30 c-p)) (list a b c c-p))
Results:
(foo :a 1 :b 2 :c 3) ==> (1 2 3 T)
(foo :c 3 :b 2 :a 1) ==> (1 2 3 T)
(foo :a 1 :c 3) ==> (1 20 3 T)
(foo) ==> (NIL 20 30 NIL)
So if I use &key at the beginning of my parameter list, I have the possibility to use a list of 3 parameters name, default value and the third if the parameter as been supplied or not. Ok.
But looking at the code in the above example:
(list a b c c-p)
How does the lisp interpreter know that c-p is my "supplied parameter"?
Let's reindent the function foo:
(defun foo (&key a
(b 20)
(c 30 c-p))
(list a b c c-p))
If you indent it like this you will see that the function has three keyword parameters: a, b and c. These are available in the body of the function.
For the keyword parameter c there is a variable declared c-p that will be T or NIL depending whether c has been passed when foo gets called.
A keyword parameter generally can be declared as one of the following options:
as a single variable name
a list of a variable name and a default value
a list of a variable name, a default value and a variable that will show whether the parameter has been passed or not when the function gets called
The supplied-p is particularly interesting when one wants to see whether the value comes from the call or the default value:
(defun make-my-array (size &key (init-value nil init-value-supplied-p))
(if init-value-supplied-p
(make-array size :initial-element init-value)
(make-array size)))
Now the user can init the elements to NIL:
(make-my-array 10 :init-value nil)
Here the default value and the supplied value can both be NIL, but we need to make a difference. The variable init-value-supplied-p makes it possible to see whether the NIL value of the variable init-value comes from the default or from the function call.
It's difficult to tell what you are asking. c-p is bound to T or NIL, depending on whether c is supplied as a parameter. This binding is then available to the body of the function.
Related
In Common Lisp, given that "a" is simply a character, what is the difference between #\a, 'a #'a?
My question comes from the tutorialspoint.com tutorial on Lisp. At one point the tutorial introduces:
; a character array with all initial elements set to a
; is a string actually
(write(make-array 10 :element-type 'character :initial-element #\a))
(terpri)
; a two dimensional array with initial values a
(setq myarray (make-array '(2 2) :initial-element 'a :adjustable t))
(write myarray)
(terpri)
With the output:
"aaaaaaaaaa"
#2A((A A) (A A))
#' is not included in this example but I'm including it in the question because it can be confusing as well. 🙂
Thank you very much! 😊
To start, a is not "simply a character." The Lisp reader parses #\a as the character literal a, which is an object in Common Lisp. Note that #\a and #\A are different character objects.
When the Lisp reader encounters a single quote, the expression following the single quote is not evaluated. Specifically, 'a is treated as (quote a), where quote returns its argument unevaluated. Now, a is a symbol, so 'a evaluates to that symbol. But the Lisp reader upcases most characters it reads by default, so 'a really evaluates to the symbol A. The good news is that whether you type a or A, the Lisp reader will read A (unless you mess with the readtable), and both 'a and 'A evaluate to the symbol A.
When the Lisp reader encounters #'a, the entire expression is treated as (function a), which when evaluated returns the function associated with the name a. But, note that it is an error to use function, and by extension #', on an identifier that does not denote a function.
To clarify this last part a bit, consider the following REPL interaction:
CL-USER> (defvar a 1)
A
CL-USER> a
1
CL-USER> #'a
The function COMMON-LISP-USER::A is undefined.
[Condition of type UNDEFINED-FUNCTION]
Here the variable a is defined and given the value 1, but when we try to access the function denoted by a we get an error message because there is no such function. Continuing:
; Evaluation aborted on #<UNDEFINED-FUNCTION A {1002DDC303}>.
CL-USER> (defun a (x) x)
A
CL-USER> (a 'b)
B
CL-USER> a
1
CL-USER> #'a
#<FUNCTION A>
Now we have defined a function named a that simply returns its argument. You can see that when we call a with an argument 'b we get the expected result: (a 'b) --> b. But, then when we evaluate a alone we still get 1. Symbols in Common Lisp are objects that have, among other cells, value cells and function cells. After the above interaction, the symbol a now has 1 in its value cell, and it has the function we have defined in its function cell. When the symbol a is evaluated the value cell is accessed, but when (function a) or #'a is evaluated, the function cell is accessed. You can see above that when #'a is evaluated, the function we defined is returned, and the REPL prints #<FUNCTION A> to show this.
As an aside, I wouldn't recommend using Tutorialspoint to learn Common Lisp. Glancing over the site, right away I see this:
LISP expressions are case-insensitive, cos 45 or COS 45 are same.
This is just wrong. And, Lisp is not written in all-caps. None of this inspires faith. Instead, find a good book. There are some recommendations on the common-lisp tag-info page.
#\
This is to introduce a character.
CL-USER> #\a
#\a
CL-USER> (character 'a)
#\A
CL-USER> (character "a")
#\a
'
This is quote, to quote and not evaluate things and construct object literals.
CL-USER> a
=> error: the variable a is unbound.
CL-USER> 'a
A
CL-USER> (inspect 'a)
The object is a SYMBOL.
0. Name: "A"
1. Package: #<PACKAGE "COMMON-LISP-USER">
2. Value: "unbound"
3. Function: "unbound"
4. Plist: NIL
> q
CL-USER> (equal (list 1 2) (quote (1 2))) ;; aka '(1 2)
T ;; but watch out with object literals constructed with quote, prefer constructor functions.
and #'
This is sharpsign-quote to reference a function.
CL-USER> #'a
=> error: The function COMMON-LISP-USER::A is undefined.
CL-USER> (defun a () (print "hello A"))
A
CL-USER> (a)
"hello A"
"hello A"
CL-USER> #'a
#<FUNCTION A>
CL-USER> (function a)
#<FUNCTION A>
One can ask Lisp to describe the data objects you've mentioned.
If we look at the expressions:
CL-USER 13 > (dolist (object (list '#\a ''a '#'a))
(terpri)
(describe object)
(terpri))
#\a is a CHARACTER
Name "Latin-Small-Letter-A"
Code 97
(QUOTE A) is a LIST
0 QUOTE
1 A
(FUNCTION A) is a LIST
0 FUNCTION
1 A
NIL
If we look at the evaluated expressions:
CL-USER 5 > (dolist (object (list #\a 'a #'a))
(terpri)
(describe object)
(terpri))
#\a is a CHARACTER
Name "Latin-Small-Letter-A"
Code 97
A is a SYMBOL
NAME "A"
VALUE #<unbound value>
FUNCTION #<interpreted function A 422005BD54>
PLIST NIL
PACKAGE #<The COMMON-LISP-USER package, 73/256 internal, 0/4 external>
#<interpreted function A 422005BD54> is a TYPE::INTERPRETED-FUNCTION
CODE (LAMBDA (B)
A)
Coming from a C++ background, I'm trying to figure out how arguments are passed into methods in Elisp. While I acknowledge that maybe the wording could be different, I'm wondering if it is closer to the C++ idea of passing by reference or passing by value? If I alter the parameter in the method itself, will it alter the parameter that was passed in in the function call?
All Lisps (Emacs Lisp, Common Lisp) pass parameters by value, always:
(defparameter x 42) ; defconst in Emacs Lisp
(defun test (x)
(setq x 10))
(test x)
==> 10
x
==> 42
Note, however, that some values are actually pointers (or, rather, objects with components), so a function can modify their content by side effects:
(defparameter x (list 1 2))
(defun test (x)
(setf (first x) 42
(second x) 24
x 17))
(test x)
==> 17
x
==> (42 24)
PS1. Cf. When to use ' (or quote) in Lisp? -- "quoted arguments" are evaluated too: the evaluation strips the quote.
PS2. Cf. add-to-list - it accepts a symbol (variable name) and modifies its value. This only works for global dynamic variables, not for lexical variables. Not a very good idea.
Actually, in Emacs Lisp, there is no such thing like passing a argument by value or by reference, not to mention pointer. But all arguments passed to function will be evaluated in advance except those have a ' prefix. Always remember When you set a variable, you always just create symbol with a value.[1]
So if you want to modify a variable's value in a function, all you need to do is modifying the value of that variable's symbol in that function.
Check my code bellow.
(defvar my-val 1)
(defun my-func-value (val)
(setq val 2))
(defun my-func-symbol (sym)
;; NOTE! using set instead of setq,
;; casue we want symbol "my-val" be evaluated from "sym" here
(set sym 2))
(my-func-value my-val) ; evaluate my-val before passed into function
(message "my-val: %s" my-val) ; my-val: 1
(my-func-symbol 'my-val) ; pass my-val symbol directly into function
(message "my-val: %s" my-val) ; my-val: 2
Note! If the variable is a lexically-bound variable[2], it's still true that you can modified the symbol's value but not the value in the lexical environment.
Here is the code:
(let ((my-lexical-var 1))
(my-func-symbol 'my-lexical-var)
;; evaluate from lexical environment
(message "my-lexical-var: %s" my-lexical-var) ; my-lexical-var: 1
;; evaluate from the symbol
(message "symbol my-lexical-var: %s" (symbol-value 'my-lexical-var))
; symbol my-lexical-var: 2
I'm doing a tutorial on emacs lisp, and it's talking about the let function.
;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello local-name)
(other-window 1))
I don't understand the role of the double parentheses after let in the first line. What are they doing that a single set wouldn't do? Running that section without them, I get an error: Wrong type argument: listp, "you".
You can introduce multiple variables there. The outer parentheses delimit the list of bindings, the inner the individual binding form.
(let ((foo "one")
(bar "two"))
(frobnicate foo bar))
There are not "double parens".
Presumably, you are thinking of (let ((foo...)...)), and you mean the (( that come after let? If so, consider this:
(let (a b c) (setq a 42)...)
IOW, let declares local variables. It may also bind them. In the previous sexp, it declares a, b, and c, but it doesn't bind any of them, leaving it to the let body to give them values.
An example that declares two variables but binds only one of them (a):
(let ((a 42) b) ... (setq b ...) ...)
According to gnu.org, it looks like you can construct and initialize multiple variables with one let statement, so the double parenthesis is there to allow the separation between the variables.
If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:
(let ((variable value)
(variable value)
…)
body…)
The let special form takes a list of bindings: (let (<binding-form> ...) <body>).
The binding form is one of <symbol> (denoting a variable bound to the value nil) or a list (<symbol> <value>) (where value is computed when the let is entered).
The difference between let and let* is how the "value" bits are executed. For plain let, they're executed before any of the values are bound:
(let ((a 17)
(b 42))
(let ((a b) ; Inner LET
(b a))
(list a b)))
Whereas let* executes the binding forms one after another. Both have their places, but you can get by with only using let since (let* (<form1> <form2>...) is equivalent to (let (<form1>) (let (<form2>) ...))
In Common Lisp, the special operator quote makes whatever followed by un-evaluated, like
(quote a) -> a
(quote {}) -> {}
But why the form (quote ()) gives me nil? I'm using SBCL 1.2.6 and this is what I got in REPL:
CL-USER> (quote ())
NIL
More about this problem: This is some code from PCL Chapter 24
(defun as-keyword (sym)
(intern (string sym) :keyword))
(defun slot->defclass-slot (spec)
(let ((name (first spec)))
`(,name :initarg ,(as-keyword name) :accessor ,name)))
(defmacro define-binary-class (name slots)
`(defclass ,name ()
,(mapcar #'slot->defclass-slot slots)))
When the macro expand for the following code:
(define-binary-class id3-tag
((major-version)))
is
(DEFCLASS ID3-TAG NIL
((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION)))
which is NIL rather than () after the class name ID3-TAG.
nil and () are two ways to express the same concept (the empty list).
Traditionally, nil is used to emphasize the boolean value "false" rather than the empty list, and () is used the other way around.
The Common LISP HyperSpec says:
() ['nil], n. an alternative notation for writing the symbol nil, used
to emphasize the use of nil as an empty list.
Your observation is due to an object to having more than one representation. In Common Lisp the reader (that reads code and reads expressions) parses text to structure and data. When it's data the writer can print it out again but it won't know exactly how the data was represented when it was initially read in. The writer will print one object exactly one way, following defaults and settings, even though there are several representations for that object.
As you noticed nil, NIL, nIL, NiL, ... ,'nil, 'NIL, (), and '() are all read as the very same object. I'm not sure the standard dictates exactly how it's default representation out should be so I guess some implementations choose one of NIL, nil or maybe even ().
With cons the representation is dependent on the cdr being a cons/nil or not:
'(a . nil) ; ==> (a)
'(a . (b . c)) ; ==> (a b . c)
'(a . (b . nil)) ; ==> (a b)
With numbers the reader can get hints about which base you are using. If no base is used in the text it will use whatever *read-base* is:
(let ((*read-base* 2)) ; read numbers as boolean
(read-from-string "(10 #x10)")) ; ==> (2 16)
#x tells the reader to interpret the rest as a hexadecimal value. Now if your print-base would have been 4 the answer to the above would have been visualized as (2 100).
To sum it up.. A single value in Common Lisp may have several good representations and all of them would yield the very same value. How the value is printed will follow both implementation, settings and even arguments to the functions that produce them. Neither what it accepts as values in or the different ways it can visualize the value tells nothing about how the value actually gets stored internally.
In Common Lisp (SBCL 1.0.58) why does the macro OR use a gensym, but not AND?
For example,
CL-USER> (macroexpand '(and 1 2 3 4 5))
(IF 1
(AND 2 3 4 5)
NIL)
T
CL-USER> (macroexpand '(or 1 2 3 4 5))
(LET ((#:G967 1))
(IF #:G967
#:G967
(OR 2 3 4 5)))
T
CL-USER>
I looked at defboot.lisp where the macros are defined but found nothing relevant in the comments.
That's because the implemented logic operators are intended to be short-circuiting and to return the value produced by the last form they evaluated.
To achieve this, and does not need a gensym because the last form it evaluates will either produce NIL or be the result of the final tail call to itself.
On the other hand, or has to return the first non-NIL value it evaluates, so it cannot rely on the tail call. It needs a gensym to do that, because without one:
(IF 1
1
(OR 2 3 4 5))
1 appears twice in the expansion, and in our case that means the expression that produces 1 is evaluated twice. And you never want that in your macros.
Let's say a is false, but b, c, and d are true. Now, because of short-circuiting we have:
(or a b c d) => b
(and a b c d) => nil
(or b c d) => b
(and b c d) => d
As you can see, in the AND case, the value of the leftmost argument is never used as the return value of the form (unless there is only one argument, in which case the expansion is different). In the OR case, on the other hand, the value of the leftmost argument is the return value if it is true. Therefore, AND can discard the value after testing it for truthiness (and thus does not need to store it in a temporary variable), but OR can't.