defstruct - :read-only is not read only - lisp

In the CLHS I read for :read-only x: "When x is true, this specifies that this slot cannot be altered; it will always contain the value supplied at construction time."
Bit I can do this (CCL, SBCL):
CL-USER> (defstruct foo
(one 0 :read-only t))
FOO
CL-USER> (defparameter *foo* (make-foo))
*FOO*
CL-USER> *foo*
#S(FOO :ONE 0)
CL-USER> (setf (slot-value *foo* 'one) 1)
1 (1 bit, #x1, #o1, #b1)
CL-USER> *foo*
#S(FOO :ONE 1)
Shouldn't changing this slot be prohibited by Lisp?

slot-value is not how you access the fields of an object whose class was defined with defstruct. Such objects do not portably have named slots at all: they have named accessors.
Some implementations give the fields of such objects names, and may also allow access to them with slot-value: such behaviour is entirely nonportable however.
If you work within the language defined by the standard then you should not be able to modify the value of a structure field defined with a :read-only option.

The specification says:
setf will not accept the reader function for this slot.
slot-value is not the reader function created by defstruct. The reader function is foo-one (unless you override the naming scheme with the :conc-name keyword). So you should get an error if you try to do
(setf (foo-one *foo) 1)

Related

Are symbols and names different?

Are symbols and names different? On Lisp by Paul Graham, which focuses on common lisp, has some discussions that seem to imply so, e.g.
Since lambda-expressions are also names of functions, they can also appear first in function calls:
((lambda (x) (* x 2) 3)
6
This makes it sound like symbols are names but names aren't symbols. But I don't understand what sort of Lisp "object" symbols are / could be.
This is also deriving from my question here on the sharp-quote (#') operator v. symbol-function. I'm suspecting the only reason these are different is because not all names are symbols but I don't have enough background to understand those answers yet (hence this question).
I'm also asking for clarification in elisp v. common lisp. I'm assuming this pertains to lexical form, which wasn't introduced in elisp until version 24 (24.1 I think).
Lambda Expressions are not names of functions. It's just that ((lambda (...) ...) ...) is allowed in Common Lisp, since it is defined in the standard as legal syntax.
The only allowed function names in Common Lisp are symbols and lists like (setf symbol).
For example one can write
(defun (setf foo) (...) ...)
Here (setf foo) is the function name.
Other function names don't exist in Common Lisp, only symbols and (setf symbol) names.
Common Lisp Hyperspec Glossary: Function Name.
function name n. 1. (in an environment) A symbol or a list (setf
symbol) that is the name of a function in that environment. 2. A
symbol or a list (setf symbol).
Note: the Common Lisp version of 1984 (as published in CLtL1) did only have symbols as function names. Thus the idea of a function name was not defined. The function to retrieve a function from a symbol was called SYMBOL-FUNCTION. In 1989 the ANSI CL standardization group decided to add setf lists as function names. It also introduced the function FDEFINITION, which is like SYMBOL-FUNCTION but also accepts other function names, besides symbols. See here: Issue FUNCTION-NAME.
I think Rainer's answer gets this right, but since the question appeared in a comment on my answer to another question, I'll include (an update to) my response from that comment.
A symbol is an actual object. You can inspect it, you can create them with make-symbol, etc. Importantly, symbols are one of the primary components of source code in Common Lisp. Function names, especially in the context that this question arose in (arguments to the function special operator) are either symbols or lists of the form (setf symbol) according to the glossary entry:
function name n. 1. (in an environment) A symbol or a list (setf symbol) that is the name of a function in that environment. 2. A
symbol or a list (setf symbol).
Function is a special operator that doesn't evaluate its arguments, so passing a symbol or setf list means something like:
(function car)
(function (setf car))
and not:
(function 'car)
(function '(setf car))
Now, lexical variables, e.g., x in (let ((x 42)) x), while represented by symbols in the source code, don't actually have any connection with the symbol at runtime. The compiled version of (let ((x 42)) x) doesn't need to know anything about the symbol x. Intuitively, this makes sense, because we'd expect the code (let ((y 42)) y) to compile to the same thing. However, when a variable is special, there is a connection with the symbol. The difference is clearest with:
(let ((x 42))
(symbol-value x))
;=> NIL
(let ((x 42))
(declare (special x)) ; or (defparameter x ...) or (defvar x ...) earlier
(symbol-value x))
;=> 42
We'd expect the same thing to be true of lexically scoped functions, e.g., the following code causes an error because there's no connection between the symbol x at runtime and the local function:
(flet ((x () 42))
(symbol-function 'x)) ; ERROR, no function value for symbol x
But even so, we can still do:
(flet ((x () 42))
(function x))
This is because function is special operator and can access the environment where is occurs. That means that (because it's special, and the implementation makes it work) it can know that x is defined as function here. It may be interesting to note, now, that since flet and labels are defined to take a function name, you can do:
(flet (((setf kar) (value kons)
...))
...)

Why is my variable "undefined"?

Why is my variable nodes undefined in the vector-push-extend line?
(defun make_graph (strings)
(defparameter nodes (make-array 0))
(loop for x in strings do
(vector-push-extend (make-instance 'node :data x) nodes))
n)
The short answer is that you should use let instead of defparameter to introduce your variable. For instance:
(defun make_graph (strings)
(let ((nodes (make-array 0)))
(loop for x in strings do
(vector-push-extend (make-instance 'node :data x) nodes))
;; your code says N here, but I assume that's a typo...
nodes))
The defparameter form is useful for creating "special" variables, which are somewhat similar to global variables in other programming languages. (There are some differences, e.g., the special variables introduced by defparameter aren't exactly global---instead, they are dynamically scoped, and can be let bound, etc...)
At any rate, the let form will instead create a local variable.
DEFPARAMETER is used at toplevel to define global special variables.
Toplevel:
(defparameter *foo* 42)
Still at toplevel, because forms inside PROGN are still at toplevel (by definition):
(progn
(defparameter *foo* 42)
(defparameter *bar* 32))
Not at toplevel:
(defun baz ()
(defparameter *foo* 42))
Above last form is not recognized by the compiler as a variable declaration. But when one calls (baz) and the function is running, the variable is defined and initialized.
A non-toplevel use of DEFPARAMETER will not be recognized by the compiler, but at runtime it will create a special global variable.
(defun make_graph (strings)
(defparameter nodes (make-array 0))
(loop for x in strings do
(vector-push-extend (make-instance 'node :data x) nodes))
n)
The compiler warns:
;;;*** Warning in MAKE_GRAPH: NODES assumed special
;;;*** Warning in MAKE_GRAPH: N assumed special
Thus in above code, the compiler does not recognize nodes as a defined variable, if it wasn't defined somewhere else already. The use of nodes in the function creates a warning.
Still the code might work, since at runtime the variable is created and initialized - but for every function invocation. Over and over. This compiler also assumes that nodes is just this: some kind of special variable. Still I would not count on it for all compilers.
n is also not defined anywhere.
Notes:
the correct way to introduce local lexical variables is to use LET and LET* (and other binding forms)
use DEFPARAMETER as a toplevel form. It is unusual when it's not a toplevel form. Typically the author makes a mistake then.

Trying to understand setf + aref "magic"

I now have learnt about arrays and aref in Lisp. So far, it's quite easy to grasp, and it works like a charme:
(defparameter *foo* (make-array 5))
(aref *foo* 0) ; => nil
(setf (aref *foo* 0) 23)
(aref *foo* 0) ; => 23
What puzzles me is the aref "magic" that happens when you combine aref and setf. It seems as if aref knew about its calling context, and would then decide whether to return a value or a place that can be used by setf.
Anyway, for the moment I just take this as granted, and don't think about the way this works internally too much.
But now I wanted to create a function that sets an element of the *foo* array to a predefined value, but I don't want to hardcode the *foo* array, instead I want to hand over a place:
(defun set-23 (place)
…)
So basically this function sets place to 23, whatever place is. My initial naive approach was
(defun set-23 (place)
(setf place 23))
and call it using:
(set-23 (aref *foo* 0))
This does not result in an error, but it also doesn't change *foo* at all. My guess would be that the call to aref resolves to nil (as the array is currently empty), so this would mean that
(setf nil 23)
is run, but when I try this manually in the REPL, I get an error telling me that:
NIL is a constant, may not be used as a variable
(And this absolutely makes sense!)
So, finally I have two questions:
What happens in my sample, and what does this not cause an error, and why doesn't it do anything?
How could I solve this to make my set-23 function work?
I also had the idea to use a thunk for this to defer execution of aref, just like:
(defun set-23 (fn)
(setf (funcall fn) 23))
But this already runs into an error when I try to define this function, as Lisp now tells me:
(SETF FUNCALL) is only defined for functions of the form #'symbol.
Again, I wonder why this is. Why does using setf in combination with funcall apparently work for named functions, but not for lambdas, e.g.?
PS: In "Land of Lisp" (which I'm currently reading to learn about Lisp) it says:
In fact, the first argument in setf is a special sublanguage of Common Lisp, called a generalized reference. Not every Lisp command is allowed in a generalized reference, but you can still put in some pretty complicated stuff: […]
Well, I guess that this is the reason (or at least one of the reasons) here, why all this does not work as I'd expect it, but nevertheless I'm curious to learn more :-)
A place is nothing physical, it's just a concept for anything where we can get/set a value. So a place in general can't be returned or passed. Lisp developers wanted a way to easily guess a setter from just knowing what the getter is. So we write the getter, with a surrounding setf form and Lisp figures out how to set something:
(slot-value vehicle 'speed) ; gets the speed
(setf (slot-value vehicle 'speed) 100) ; sets the speed
Without SETF we would need a setter function with its name:
(set-slot-value vehicle 'speed 100) ; sets the speed
For setting an array we would need another function name:
(set-aref 3d-board 100 100 100 'foo) ; sets the board at 100/100/100
Note that the above setter functions might exist internally. But you don't need to know them with setf.
Result: we end up with a multitude of different setter function names.
The SETF mechanism replaces ALL of them with one common syntax. You know the getter call? Then you know the setter, too. It's just setf around the getter call plus the new value.
Another example
world-time ; may return the world time
(setf world-time (get-current-time)) ; sets the world time
And so on...
Note also that only macros deal with setting places: setf, push, pushnew, remf, ... Only with those you can set a place.
(defun set-23 (place)
(setf place 23))
Above can be written, but place is just a variable name. You can't pass a place. Let's rename it, which does not change a thing, but reduces confusion:
(defun set-23 (foo)
(setf foo 23))
Here foo is a local variable. A local variable is a place. Something we can set. So we can use setf to set the local value of the variable. We don't set something that gets passed in, we set the variable itself.
(defmethod set-24 ((vehicle audi-vehicle))
(setf (vehicle-speed vehicle) 100))
In above method, vehicle is a variable and it is bound to an object of class audi-vehicle. To set the speed of it, we use setf to call the writer method.
Where does Lisp know the writer from? For example a class declaration generates one:
(defclass audi-vehicle ()
((speed :accessor vehicle-speed)))
The :accessor vehicle-speed declaration causes both reading and setting functions to be generated.
The setf macro looks at macro expansion time for the registered setter. That's all. All setf operations look similar, but Lisp underneath knows how to set things.
Here are some examples for SETF uses, expanded:
Setting an array item at an index:
CL-USER 86 > (pprint (macroexpand-1 '(setf (aref a1 10) 'foo)))
(LET* ((#:G10336875 A1) (#:G10336876 10) (#:|Store-Var-10336874| 'FOO))
(SETF::\"COMMON-LISP\"\ \"AREF\" #:|Store-Var-10336874|
#:G10336875
#:G10336876))
Setting a variable:
CL-USER 87 > (pprint (macroexpand-1 '(setf a 'foo)))
(LET* ((#:|Store-Var-10336877| 'FOO))
(SETQ A #:|Store-Var-10336877|))
Setting a CLOS slot:
CL-USER 88 > (pprint (macroexpand-1 '(setf (slot-value o1 'bar) 'foo)))
(CLOS::SET-SLOT-VALUE O1 'BAR 'FOO)
Setting the first element of a list:
CL-USER 89 > (pprint (macroexpand-1 '(setf (car some-list) 'foo)))
(SYSTEM::%RPLACA SOME-LIST 'FOO)
As you can see it uses a lot of internal code in the expansion. The user just writes a SETF form and Lisp figures out what code would actually do the thing.
Since you can write your own setter, only your imagination limits the things you might want to put under this common syntax:
setting a value on another machine via some network protocol
setting some value in a custom data structure you've just invented
setting a value in a database
In your example:
(defun set-23 (place)
(setf place 23))
you can't do it just like that, because you have to use setf in context.
This will work:
(defmacro set-23 (place)
`(setf ,place 23))
CL-USER> (set-23 (aref *foo* 0))
23
CL-USER> *foo*
#(23 NIL NIL NIL NIL)
The trick is, setf 'knows' how to look at real place its arguments come from, only for limited number of functions. These functions are called setfable.
setf is a macro, and to use it the way you wanted to, you also have to use macros.
The reason why you have not been getting errors, is that you actually successfully modified lexical variable place which was bound to copy of selected array element.

How do I define a function that creates a function alias?

The Lisp forum thread Define macro alias? has an example of creating function alias using a form such as
(setf (symbol-function 'zero?) #'zerop)
This works fine, making zero? a valid predicate. Is it possible to parametrize this form without resorting to macros? I'd like to be able to call the following and have it create function?:
(define-predicate-alias 'functionp)`
My take was approximately:
(defun defalias (old new)
(setf (symbol-function (make-symbol new))
(symbol-function old)))
(defun define-predicate-alias (predicate-function-name)
(let ((alias (format nil "~A?" (string-right-trim "-pP" predicate-function-name))))
(defalias predicate-function-name alias)))
(define-predicate-alias 'zerop)
(zero? '())
This fails when trying to call zero? saying
The function COMMON-LISP-USER::ZERO? is undefined.
make-symbol creates an uninterned symbol. That's why zero? is undefined.
Replace your (make-symbol new) with e.g. (intern new *package*). (Or you may want to think more carefully in which package to intern your new symbol.)
Your code makes a symbol, via MAKE-SYMBOL, but you don't put it into a package.
Use the function INTERN to add a symbol to a package.
To expand on Lars' answer, choose the right package. In this case the default might be to use the same package from the aliased function:
About style:
Anything that begins with DEF should actually be a macro. If you have a function, don't use a name beginning with "DEF". If you look at the Common Lisp language, all those are macro. For example: With those defining forms, one would typically expect that they have a side-effect during compilation of files: the compiler gets informed about them. A function can't.
If I put something like this in a file
(define-predicate-alias zerop)
(zero? '())
and then compile the file, I would expect to not see any warnings about an undefined ZERO?. Thus a macro needs to expand (define-predicate-alias 'zerop) into something which makes the new ZERO? known into the compile-time environment.
I would also make the new name the first argument.
Thus use something like MAKE-PREDICATE-ALIAS instead of DEFINE-PREDICATE-ALIAS, for the function.
There are already some answers that explain how you can do this, but I'd point out:
Naming conventions, P, and -P
Common Lisp has a naming convention that is mostly adhered to (there are exceptions, even in the standard library), that if a type name is multiple words (contains a -), then its predicate is named with -P suffix, whereas if it doesn't, the suffix is just P. So we'd have keyboardp and lcd-monitor-p. It's good then, that you're using (string-right-trim "-pP" predicate-function-name)), but since the …P and …-P names in the standard, and those generated by, e.g., defstruct, will be using P, not p, you might just use (string-right-trim "-P" predicate-function-name)). Of course, even this has the possible issues with some names (e.g., pop), but I guess that just comes with the territory.
Symbol names, format, and *print-case*
More importantly, using format to create symbol names for subsequent interning is dangerous, because format doesn't always print a symbol's name with the characters in the same case that they actually appear in its name. E.g.,
(let ((*print-case* :downcase))
(list (intern (symbol-name 'foo))
(intern (format nil "~A" 'foo))))
;=> (FOO |foo|) ; first symbol has name "FOO", second has name "foo"
You may be better off using string concatenation and extracting symbol names directly. This means you could write code like (this is slightly different use case, since the other questions already explain how you can do what you're trying to do):
(defmacro defpredicate (symbol)
(flet ((predicate-name (symbol)
(let* ((name (symbol-name symbol))
(suffix (if (find #\- name) "-P" "P")))
(intern (concatenate 'string name suffix)))))
`(defun ,(predicate-name symbol) (x)
(typep x ',symbol)))) ; however you're checking the type
(macroexpand-1 '(defpredicate zero))
;=> (DEFUN ZEROP (X) (TYPEP X 'ZERO))
(macroexpand-1 '(defpredicate lcd-monitor))
;=> (DEFUN LCD-MONITOR-P (X) (TYPEP X 'LCD-MONITOR))

define a symbol local inside the function?

Just as an example, put inside the function create x property and its value globally:
(defun foo ()
(put 'spam 'x 1))
(foo)
(get 'spam 'x) ; -> 1
Is it there way to set the symbol property locally?
No, because 'spam is always the same symbol a property can't be set on it locally.
I don't know if this would be appropriate for your situation, but you could create a fresh symbol and put the property on that. Because the symbol wouldn't be available outside the function neither would the property.
(defun foo ()
(let ((private (make-symbol "private")))
(put private 'x 1)
(get private 'x)))
(foo) ;=> 1
(get 'private 'x) ;=> nil
make-symbol returns a "newly allocated [and] uninterned symbol", which means the symbol returned by (make-symbol "private") is a different symbol from the global 'private and all others. See here for the Emacs manual's section on creating and interning symbols for more information.
Emacs also supports buffer-local variables, though that's not quite the same thing (the symbol's value is local to a particular buffer, but the symbol itself and its properties are still global).
If you just need to bind a value to a name locally, you could also use either Emacs 24's support for lexical binding or, if you're on an older version, lexical-let from the cl package (which is included with Emacs).
You can do it "locally" in the sense of dynamic-scoping:
(require 'cl-lib)
(defun foo ()
(cl-letf (((get 'spam 'x) 1))
(get 'spam 'x)))
(foo) ; -> 1
(get 'spam 'x) ; -> nil
Although I don't quite understand what is that you want to do, seems to me that you are looking for a closure, that is, a function with an environment. To do so you have to enable lexical binding, which is supported starting from emacs 24.3 IIRC. To enable it set the buffer local variable lexical-binding to t. The popular example of a closure would be an adder factory, that is a function that returns a function that adds by a constant.
(defun make-adder (constant)
(lambda (y) (+ y constant)))
(make-adder 3)
;; As you can see a closure is a function with an environment associated
=> (closure ((constant . 3) t) (y) (+ y constant))
(funcall (make-adder 3) 2)
=> 5
(funcall (make-adder 5) 2)
=> 8
So yes, using closures you can have private variables for a function.