I am teaching myself Common Lisp. I have been looking at an example of Conway's game of life, and there is a piece of syntax I do not understand.
The complete code is available here. The part in particular I am having trouble with is as follows:
(defstruct (world (:constructor %make-world))
current
next)
(defun make-world (width height)
(flet ((make-plane (width height)
(make-array (list width height)
:element-type 'bit
:initial-element 0)))
(%make-world
:current (make-plane width height)
:next (make-plane width height))))
I am wondering, first, what is the significance of the percent-sign in %make-world? Second, why does the constructor specify two different names? (make-world and %make-world) I have seen this syntax in use before, but the names are always the same. It seems like there is some deeper functionality, but it is escaping me.
There are several naming conventions is the Lisp world when it comes to identifiers. For an overview see: http://www.cliki.net/Naming+conventions
Making objects or structures can be done with system generated functions. DEFSTRUCT
will create a MAKE-FOO
function with init values for the slots as keyword arguments.
Sometimes people prefer functions with normal positional arguments - it's shorter to write and the arguments have to be given when calling the function - you can't omit them.
Here in this case there is the need to name the DEFSTRUCT
generated function in such a way that it does not collide with the name, which the user should use. So %MAKE-FOO
says that is an internal helper function to the library and is expected to NOT be called by user-level code.
My Lisp is a little rusty, but I believe it goes like this:
The % sign has no special meaning. I've seen it used for internal functions (e.g. defined by labels
), but nothing wil stop you from calling it normally. If you look at defstruct documetation, you'll see that (:constructor %make-world)
defines a named constructor %make-world
(by default the constructor would be called make-world
. This contructor can be used to create world
structs, initializing fields using named parameters.
The function make-world
exists to make creating these structs easier. The thing is, current
and next
should be 2-dimensional arrays, but it's more convenient if, instead of passing these arrays to the constructor, you could just say what the dimensions are and a function would create those arrays for you. Which is exactly what make-world
does here. It first defines an internal function make-plane
, which can create an array, then uses it to create 2 arrays and pass them to the constructor %make-plane
.
In line with the usual usage of the %
character (again, this is just a convention), it tells you that, as a programmer wishing to use the world
struct, you should not use the %make-world
constructor, but the make-world
function instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With