Reputation: 33
I am reading the book successful lisp, There is a example:
(defstruct (ship
(:print-function
(lambda (struct stream depth)
(declare (ignore depth))
(format stream "[ship ~A of ~A at (~D, ~D) moving (~D, ~D)]"
(ship-name struct)
(ship-player struct)
(ship-x-pos struct)
(ship-y-pos struct)
(ship-x-vel struct)
(ship-y-vel struct)))))
(name "unnamed")
player
(x-pos 0.0)
(y-pos 0.0)
(x-vel 0.0)
(y-vel 0.0))
How can i understand this part:
(lambda (struct stream depth)
(declare (ignore depth))
why declare to ignore the depth? I feel quite confused, why not write lambda as
(lambda (struct stream)
.....)
Thanks
Upvotes: 3
Views: 1134
Reputation: 139411
The Common Lisp standard says this:
If the :print-function option is used, then when a structure of type structure-name is to be printed, the designated printer function is called on three arguments:
- the structure to be printed (a generalized instance of structure-name).
- a stream to print to.
- an integer indicating the current depth. The magnitude of this integer may vary between implementations; however, it can reliably be compared against
*print-level*
to determine whether depth abbreviation is appropriate.
So it is a three argument function. We need to write a function which takes three arguments then.
As usual, if our code does not use all arguments, we can declare them to be ignored, so that the compiler will not print a warning. Here the user has not used the variable depth
.
Example: in the following function it is not clear if we forgot to use b
or if not using it is on purpose.
CL-USER 21 > (defun foo (a b)
(list a))
FOO
CL-USER 22 > (compile 'foo)
;;;*** Warning in FOO: B is bound but not referenced
FOO
Now we can tell the compiler that we chose not to use b
.
CL-USER 23 > (defun foo (a b)
(declare (ignore b))
(list a))
FOO
No warnings during compilation:
CL-USER 24 > (compile 'foo)
FOO
NIL
NIL
Upvotes: 6
Reputation: 6303
You cannot simply ignore arguments in Common Lisp - unlike, for example, javascript. That is, if you write a function such as
(defun foo (bar baz)
(list bar baz))
you cannot call it with any other number of arguments:
(foo 'a 'b) ; correct number of arguments
=> (a b)
(foo 'a) ; too few arguments
=> error
(foo 'a 'b 'c) ; too many arguments
=> error
As the printer functions are called with three arguments - the object, stream and depth - you must also define all printers with exactly three arguments. The declaration simply removes a warning message by indicating to the compiler you are intentionally leaving the parameter unused.
Upvotes: 5