I have written a polynomial class along the lines described in SICP 2.5.3 (except using defclass). I would like to be able to seamlessly add and multiply polynomials and regular numbers but I can't make change-class accept a number.
I tried to simplify the problem by changing class from an integer to a float:
(change-class 4 'float)
but that gave me the error:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<BUILT-IN-CLASS FLOAT>).
[Condition of type SIMPLE-ERROR]
I get an error of the same form from (fyi):
(change-class 4 'polynomial)
I'm going to go ahead and implement a manual conversion but I would prefer to use the built-in clos facilities.
As Xach points out I could use coerce or float to change 4 to a float. That was intended as a simpler example of what I was trying to do and to remove any possibility of my update-instance-for-different-class being wrong.
Here is the longer version of what I tried that didn't work:
(defclass polynomial ()
((var :accessor var :initarg :var :initform 'x)
(terms :accessor terms :initarg :terms :initform (make-empty-term-list))))
(defmethod update-instance-for-different-class :before ((old number)
(new polynomial)
&key)
(setf (slot-value new 'terms) (adjoin-term (make-term old 0)
(make-empty-term-list))))
(change-class 4 'polynomial)
I still get an error like the example above:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<STANDARD-CLASS POLYNOMIAL>).
[Condition of type SIMPLE-ERROR]
You can use COERCE or FLOAT to do that:
(float 4) => 4.0
(coerce 4 'float) => 4.0
You can't use CHANGE-CLASS with numbers. Numbers are not instances of CLOS classes. CHANGE-CLASS is also thought to destructively modify an instance to a new class, without changing the identity of the original instance.
I would either:
add methods to CHANGE-CLASS that does what you want
or write a function CHANGE, that implements various custom coercion rules and calls CHANGE-CLASS for any change from one CLOS class to another CLOS class.
Related
When developing with Common Lisp, we have three possibilities to define new setf-forms:
We can define a function whose name is a list of two symbols, the first one being setf, e.g. (defun (setf some-observable) (…)).
We can use the short form of defsetf.
We can use the long form of defsetf.
We can use define-setf-expander.
I am not sure what is the right or intended use-case for each of these possibilities.
A response to this question could hint at the most generic solution and outline contexts where other solutions are superior.
define-setf-expander is the most general of these. All of setf's functionality is encompassed by it.
Defining a setf function works fine for most accessors. It is also valid to use a generic function, so polymorphism is insufficient to require using something else. Controlling evaluation either for correctness or performance is the main reason to not use a setf function.
For correctness, many forms of destructuring are not possible to do with a setf function (e.g. (setf (values ...) ...)). Similarly I've seen an example that makes functional data structures behave locally like a mutable one by changing (setf (dict-get key some-dict) 2) to assign a new dictionary to some-dict.
For performance, consider the silly case of (incf (nth 10000 list)) which if the nth writer were implemented as a function would require traversing 10k list nodes twice, but in a setf expander can be done with a single traversal.
I'll show the thing that I want from Common Lisp that already works in Elisp:
(defun square (x)
(* x x))
(symbol-function 'square)
;; => (lambda (x) (* x x))
So by just knowing the symbol square, I want to retrieve its whole body.
I've looked at CL's:
(function-lambda-expression #'square)
;; =>
(SB-INT:NAMED-LAMBDA SQUARE
(X)
(BLOCK SQUARE (* X X)))
NIL
SQUARE
The return result is close to what I need, but it only works sometimes.
Most of the time, I get:
(function-lambda-expression #'list)
;; =>
NIL
T
LIST
Is there a more reliable function that does this? I'm aware of swank-backend:arglist that's very
good at retrieving the arguments, but I can't find a retriever for the body there.
UPDATE
It seems that the general solution isn't possible in plain lisp. Is this possible to do in SLIME?
Assume that I always have SLIME running, and all the code was loaded through there. Can the code be
obtained more reliably than just using SLIME's goto-definition and copying the text from there?
No. The saving of the source code at the symbol is not mandated by the standard, so any implementation may choose not to do that (this also has performance implications).
I guess that you might get that behaviour more often by declaiming optimize (debug 3), but I have not tried that; it is most likely implementation dependent.
Answer to update: Since you want to implement an editor functionality interacting with the Lisp image, I'd say that using the Lisp Interaction Mode (the LIM in SLIME) is exactly what you need to do.
Perhaps the reason is that the system/core functions, like #'list, has been compiled for speed when the image was built? Perhaps if you bootstrapped SBCL yourself you could make one that was slower and had more information. Or you can just look the the source sode:
(describe #'list)
#<FUNCTION LIST>
[compiled function]
Lambda-list: (&REST ARGS)
Declared type: (FUNCTION * (VALUES LIST &OPTIONAL))
Derived type: (FUNCTION (&REST T) (VALUES LIST &OPTIONAL))
Documentation:
Return constructs and returns a list of its arguments.
Known attributes: flushable, unsafely-flushable, movable
Source file: SYS:SRC;CODE;LIST.LISP
That last line is correct since under src/code/list.lisp you actually find the definition.
Notice the behaviour of describe and function-lambda-expression are implementation dependent. Eg. in CLISP the output is completely different.
(function-lambda-expression #'list) heretries to retrieve the code of a built-in function. Not every built-in function needs to have Lisp code as its implementation.
I haven't tried it, but maybe you can build SBCL yourself, such that it records the source code and saves it in the image.
For a standard image of SBCL I would not expect that it contains source code.
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.
Here are some sample codes from text of OnLisp.
My question is that why it bothers to use a lambda function,
`(funcall (alrec ,rec #'(lambda () ,base)) ,#lsts))
as second argument to alrec in the definition of on-cdrs?
What is the difference if I just define it without using lambda?
`(funcall (alrec ,rec ,base) ,#lsts))
(defun lrec (rec &optional base)
(labels ((self (lst)
(if (null lst)
(if (functionp base)
(funcall base)
base)
(funcall rec (car lst)
#'(lambda ()
(self (cdr lst)))))))
#'self))
(defmacro alrec (rec &optional base)
"cltl2 version"
(let ((gfn (gensym)))
`(lrec #'(lambda (it ,gfn)
(symbol-macrolet ((rec (funcall ,gfn)))
,rec))
,base)))
(defmacro on-cdrs (rec base &rest lsts)
`(funcall (alrec ,rec #'(lambda () ,base)) ,#lsts))
You don't say how this is intended to be called and this code is a bit of a tangle so at a quick glance I couldn't say how it's supposed to work. However, I can answer your question.
First, let me say that
(if (functionp base) (funcall base) base)
is terrible programming style. This effectively puts a whole in your semantic space, creating a completely different handling of functions as objects than other things as objects. In Common Lisp, a function is supposed to be an object you can choose to pass around. If you want to call it, you should do so, but you shouldn't just say to someone "if I give you a function you should call it and otherwise you should not." (Why this matters will be seen as you read on.)
Second, as Barmar notes, if you write ,base you are basically saying "take the code and insert it for evaluation here". If you write
#'(lambda () ,base)
you are saying put the code inside a function so that its execution is delayed. Now, you're passing it to a function that when it receives the function is going to call it. And, moreover, calling it will evaluate it in the lexical environment of the caller, and there is no intervening change in dynamic state. So you'd think this would be the same thing as just evaluating it at the call site (other than just a little more overhead). However, there is a case where it's different.
If the thing you put in the base argument position is a variable (let's say X) or a number (let's say 3), then you'll either be doing (lrec ... X) or (lrec 3) or else you'll be doing
(lrec ... #'(lambda () X))
or
(lref ... #'(lambda () 3))
So far so good. If it gets to the caller, it's going to say "Oh, you just meant the value of X (or of 3)." But there's more...
If you say instead an expression that yields a function in the base argument position of your call to on-cdrs or your call to alrec, you're going to get different results depending on whether you wrote ,base or #'(lambda () ,base). For example, you might have put
#'f
or
#'(lambda () x)
or, even worse,
#'(lambda (x) x)
in the base argument position. In that case, if you had used ,base, then that expression would be immediately evaluated before passing the argument to lrec, and then lrec would receive a function. And then it would be called a second time (which is probably not what the macro user expects unless the documentation is very clear about this inelegance and the user of the macro has cared enough to read the documentation in detail). In the first case, it will return 3, in the second case, the value of x, and in the third case an error situation will occur because it will be called with the wrong number of arguments.
If instead you implemented it with
#'(lambda () ,base)
then lrec will receive as an argument the result of evaluating one of
#'(lambda () #'f)
or
#'(lambda () #'(lambda () 3))
or
#'(lambda () #'(lambda (x) x))
depending on what you gave it as an argument from our examples above. But in any case what lrec gets is a function of one argument that, when evaluated, will return the result of evaluating its body, that is, will return a function.
The important takeaways are these:
The comma is dropping in a piece of evaluable code, and wrapping the comma'd experession with a lambda (or wrapping any expression with a lambda) delays evaluation.
The conditional in the lrec definition should either expect that the value is already evaluated or not, and should not take a conditional effect because it can't know whether you already evaluated something based purely on type unless it basically makes a mess of functions as first-class data.
I hope that helps you see the difference. It's subtle, but it's real.
So using
#'(lambda () ,base)
protects the macro from double-evaluation of a base that might yield a function, but on the other hand the bad style is something that shouldn't (in my view) happen. My recommendation is to remove the conditional function call to base and make it either always or never call the base as a function. If you make it never call the function, the caller should definitely use ,base. If you make it always call the function, the caller should definitely include the lambda wrapper. That would make the number of evaluations deterministic.
Also, as a purely practical matter, I think it's more in the style of Common Lisp just to use ,base and not bother with the closure unless the expression is going to do something more than travel across a function call boundary to be immediately called. It's a waste of time and effort and perhaps extra consing to have the function where it's really not serving any interesting purpose. This is especially true if the only purpose of the lrec function is to support this facility. If lrec has an independent reason to have the contract that it does, that's another matter and maybe you'd write your macro to accommodate.
It's more common in a functional language like Scheme, which has a different aesthetic, to have a regular function as an alternative to any macro, and to have that function take such a zero-argument function as an argument just in case some user doesn't like working with macros. But mostly Common Lisp programmers don't bother, and your question was about Common Lisp, so I've biased the majority of my writing here to that dialect.
Let's say I define a new class foo:
(defclass foo ()
((bar :initarg :bar ...)
(baz :initarg :baz ...)
...))
And I want to create a custom comparator for foo, such as:
(defun foo-equalp (foo1 foo2)
(equalp (bar foo1)))
Would there be a better, more explicit way to tie this foo-equalp function to the foo class?
I was thinking of not having to pass #'foo-equalp as the :test argument to functions like REMOVE-DUPLICATES, but even if that is not possible, I would still like to know if there is a more idiomatic Lisp way to define this function.
If I understand your question then generic functions could help here
(defgeneric foo-equalp (foo1 foo2))
(defmethod foo-equalp ((foo1 foo) (foo2 foo))
(and (equal (bar foo1) (bar foo2))
(equal (baz foo1) (baz foo2))))
and now when you call foo-equalp with objects that are not of type foo you get this error.
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION FOO-EQUALP (1)>
when called with arguments
(1 2).
or you might want everything else to return nil
(defmethod foo-equalp ((foo1 t) (foo2 t))
nil)
Here we specialize on t which is the set of all objects. When you call a method common lisp will always choose the 'closest/most specific' type match for the arguments (ugh that is a terrible mangling of a description..I need more coffee, check out the link as it is awesome :))
You don't actually need to specialize of t as this is the default but I wanted to include it to show what was happening.
The following are snippets from Practical Common Lisp (which is linked at the top of this
answer)
A generic function defines an abstract operation, specifying its name
and a parameter list but no implementation. The actual implementation
of a generic function is provided by methods.
Methods indicate what kinds of arguments they can handle by
specializing the required parameters defined by the generic function.
For instance, for a generic function draw, you might define one method
that specializes the shape parameter for objects that are instances of
the class circle while another method specializes shape for objects
that are instances of the class triangle.