I can't use the clos accessor functions when the class is in a list.
Say I have class a:
(defclass a ()
((a :accessor a
:initarg :a)))
And I make 2 instances:
(defparameter b (make-instance 'a :a 1))
(defparameter c (make-instance 'a :a 2))
and then if I wanted to create a function that would get the a value for each of the instances while in a list i would do
(defun get-a (lst)
(mapcar #'a lst))
and call it with
(get-a '(b c))
but I do that I get an error:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION A (1)>
when called with arguments
(B).
[Condition of type SIMPLE-ERROR]
And it also happens if instead of calling the accessor directly with mapcar, I call a function which contains the accessor. Also I've tried using loops and other things instead of mapcar.
Thanks
If you read the error, you get the explanation.
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION A (1)>
when called with arguments
(B).
So you got a call, which is similar to (a 'b). But b is a symbol, not a CLOS instance.
(b c) is a list of two symbols. You probably wanted to create a list of two CLOS instances. Use LIST to create a list with evaluated arguments.
Related
I made my own prototypal OO system in Racket which uses "this" for methods. Everything works great, but unfortunately it prevents Racket's native class system from using "this".
Here's what I want to do:
(require (only-in racket (this oldthis)))
(define-syntax this
(syntax-id-rules (set!)
((set! this ...) (void))
((this a ...) ((self) a ...))
(this (if (null? (self)) oldthis (self)))))
One thing I've tried to do is rename the above "this" macro to be "newthis" and make a helper macro as follows:
(define-syntax (this stx)
(syntax-case stx ()
(this #'(if (null? (self)) oldthis newthis))))
But in both cases Racket throws an error because I'm using "oldthis" outside of a class context. How do I merely reference the old "this" macro without expanding it and throwing an error? Or, more broadly, how can I make my "this" macro delegate to the old "this" macro when (self) is null?
Thanks in advance!
EDIT: Here is some code that uses "this" properly:
(define Foo (new))
(void (# Foo 'name "Foo")
(# Foo 'method (lambda () (# this 'name))))
You can then run Foo's "method" by calling
((# Foo 'method))
Which gives the correct result "Foo"
However, if I use Racket's class system:
(define foo%
(class object%
(super-new)
(define/public (displayself)
(displayln this))))
and run
(define foo (make-object foo%))
(send foo displayself)
I get (), always, since "this" returns (self) and (self) has in its closure a value "self" which is currently null. What I want to do is to check if (self) is null and, if it is, delegate to the built-in "this" macro.
EDIT2:
It looks like this answer is doing what I want to do. When I try it, however, I still get the same error about class context. I think the reason for that is that the #%top macro is invoked by (real-top . rest) and not by real-top on its own. In my case, however, oldthis gets invoked immediately and throws the error. I have no idea how to prevent that.
One thing I did that got close was to enclose oldthis in (eval 'oldthis), but that only worked in the current namespace. In order for that to work consistently, I would have to provide oldthis in conjunction with everything else, which is not only ugly but error prone, since an unsuspecting user of the library wouldn't necessarily understand that they have to pass oldthis all the time for anything to work properly. So I don't want to do it this way.
SOLVED:
(define-syntax this
(syntax-id-rules (set!)
((set! this ...) (void))
((this a ...) ((self) a ...))
(this (if (null? (self)) (eval 'this (module->namespace 'racket)) (self)))))
By providing the racket language as the namespace argument for eval, I can reference the old "this" without making any assumptions about the program using my OO library except that it have access to the racket language.
You should be able to do this directly with rename-in. Take the following code for example:
#lang racket
(require (rename-in racket [this old-this]))
(define this 42)
(define foo%
(class object%
(super-new)
(define/public (get-me)
old-this)))
(define bar (new foo%))
(send bar get-me)
Here we use rename-in to import old-this to point to the same binding as this in Racket. Which is needed because we immediately shadow that binding with: (define this 42)
Next, we define the foo% object, with one method: get-me, which just returns the current object with this (or specifically old-this.
Finally, we define a new foo% called bar, and call get-me. As you can see, it returns the bar object as you would expect.
If, instead of old-this, you returned this, then get-me would return 42, because of the definition. Likewise, if you removed the definition for this as 42, then this would still be bound to the one the class macro expects.
This question already has answers here:
What is the difference between Lisp-1 and Lisp-2?
(2 answers)
Closed 6 years ago.
I am attempting to understand the lambda notion found within Emacs Lisp.
In ielm, executing:
((lambda (x) (* x x)) 5)
gives us 25, and
(let ((x 4)) (* x x))
gives us 16. However when I do:
(let ((f (lambda (x) (* x x)))) (f 7))
it does not give me 49, but instead informs me:
*** Eval error *** Symbol's function definition is void: f
Don't know why, I am sure the syntax is right and f is defined in the let?
Using cl-flet to define let-ed function
We can actually do this without using funcall. The cl module includes standard functions from Common Lisp. We first import it:
(require 'cl)
Thereafter we can use cl-flet to define our function:
(cl-flet ((f (x) (* x x)))
(f 7))
I'd be surprised if this isn't a duplicate, but I can't find it readily here on Stack Overflow. In "Lisp-2" languages (e.g., Emacs Lisp and Common Lisp), there are separate namespaces for functions and variables. A function call looks like:
((lambda ...) ...) ; call the lambda function
or
(f ...) ; call the function binding of f
If you want to call the function that is the value of a variable, then you need to use funcall or apply:
(apply f ...)
(funcall f ...)
The difference between apply and funcall is well documented in other places, but the quick difference is that apply expects an argument list (in some Lisps, a "spreadable argument list"), whereas funcall takes the arguments directly. E.g.,
(let ((f (lambda (a b) (+ a b))))
(funcall f 1 2) ; arguments directly
(apply f '(1 2))) ; arguments in a list
In a "Lisp-1", (like Scheme), you don't need funcall, since there's only one space for bindings. In Scheme you can do:
(let ((f (lambda (a b) (+ a b))))
(f 1 2))
The difference between Lisp-1 and Lisp-2 languages is described more in What is the difference between Lisp-1 and Lisp-2?. The big difference is when the system sees a function call, how it figures out what function to call. In a Lisp-1, variables have values, and that's all. So when the system sees something like:
(f ...)
f is a variable, and the only possible thing to call is the value of f. In a Lisp-2, the systems tries to call the function value of f, which doesn't have to have anything do with the value of the variable f. That can be a bit confusing at first, but it's actually pretty handy in many cases, because it makes it harder to accidentally obscure functions with common names. E.g., in a Lisp-1, you'll see lots of people use lst as an argument name instead of list, because if they named the argument list, then they couldn't use the (standard) function list within the function.
It is said, only special variables in Common Lisp can be unbound. For all lexical variables the default value is nil. I thought that class slots exist in something like closure, but obviously they don't.
If I define a CLOS slots without :initform parameter (in hope that they will be bound to nil anyway) and do not supply values when creating instance, I'll get an instance with unbound slots. Why it is so? It's not handy.
It is very handy for things like computing slot values on demand, where the value may sometimes be nil. When accessing an unbound slot, CLOS normally calls the SLOT-UNBOUND generic function, which signals an error. Instead of an error, though, you can specialize SLOT-UNBOUND to compute and store the value on demand. Subsequent accesses will use the slot value directly, and you can flush the slot "cache" by using SLOT-MAKUNBOUND.
You could do this with a sentinel "not-bound" value of some sort, but it's very handy to have the functionality built-in instead.
Example of slot-unbound use:
(defclass foo ()
((bar :accessor bar)
(baz :accessor baz)))
(defmethod slot-unbound (class (instance foo) slot-name)
(declare (ignorable class))
(setf (slot-value instance slot-name) nil))
In action:
CL-USER> (defparameter *foo* (make-instance 'foo))
*FOO*
CL-USER> (bar *foo*)
NIL
CL-USER> (setf (baz *foo*) (not (baz *foo*)))
T
CLOS instances are not closures
CLOS instances are usually not implemented as closures. That would be difficult. They are some data structure with something like a vector for the slots. Similar to Common Lisp's structures. A difference between CLOS instances and structures complicates it: it is possible for CLOS instances to change the number of slots at runtime and one can change the class of a CLOS instance at runtime.
Making sure slots have a NIL value
With some advanced CLOS you can make sure that slots have a NIL value. Note that the functions in the package CLOS in my example may be in another package in your CL.
This functions looks over all slots of an instance. If a slot is unbound, it gets set to NIL.
(defun set-all-unbound-slots (instance &optional (value nil))
(let ((class (class-of instance)))
(clos:finalize-inheritance class)
(loop for slot in (clos:class-slots class)
for name = (clos:slot-definition-name slot)
unless (slot-boundp instance name)
do (setf (slot-value instance name) value))
instance))
We make a mixin class:
(defclass set-unbound-slots-mixin () ())
The fix will be run after initializing the object.
(defmethod initialize-instance :after ((i set-unbound-slots-mixin) &rest initargs)
(set-all-unbound-slots i nil))
Example:
(defclass c1 (set-unbound-slots-mixin)
((a :initform 'something)
b
c))
CL-USER 1 > (describe (make-instance 'c1))
#<C1 4020092AEB> is a C1
A SOMETHING
B NIL
C NIL
I am trying to do an "overload call" of a multimethod in Common Lisp. Here is a simplified rundown of the case:
(defclass foo ()
((slotty :accessor slotty :initarg :slotty)))
(defclass bar ()
((slotty :accessor slotty :initarg :slotty)))
(defparameter *foo* (make-instance 'foo :slotty "defnoodle"))
(defparameter *bar* (make-instance 'bar :slotty "Chocolate"))
(defmethod contrived ((f foo) (b bar))
(format t "i pity the foo ~A, who has a bar ~A ~%" (slotty f) (slotty b)))
(contrived *foo* *bar*)
outputs: i pity the foo defnoodle, who has a bar Chocolate
But as soon as I try to define the next method:
(defmethod contrived ((f foo))
(format t "i just pity the foo ~A ~%" (slotty f)))
CL gets mad:
; The generic function #<STANDARD-GENERIC-FUNCTION CONTRIVED (1)>
; takes 2 required arguments; was asked to find a method with
; specializers (#<STANDARD-CLASS FOO>)
; [Condition of type SB-PCL::FIND-METHOD-LENGTH-MISMATCH]
; See also:
; Common Lisp Hyperspec, FIND-METHOD [:function]
Does anyone know what I am doing wrong here? I know that initialize-instance has a similar kind of flexibility since one should be able to identify n number of initialize-instance methods per class and per any number of arguments.
(defmethod initialize-instance :after ((f foo) &key)
())
but it is not clear to me how I can translate this to the vanilla example I gave above. And I feel like I could be barking up the wrong tree since this is part of MOP.
You write: Does anyone know what I am doing wrong here?
To make it clear: CLOS does not support that. You can't have different numbers of required arguments in method parameter lists of methods of a single generic function. Dispatching works over the required arguments only. Common Lisp does not support 'overloading'.
INITIALIZE-INSTANCE is defined with this syntax:
initialize-instance instance &rest initargs &key &allow-other-keys => instance
All methods take one required argument, the instance. Dispatching is only done over this object. It then allows various keyword arguments - no dispatching is done for them.
So you need to agree on the numbers of required arguments your generic function should take and call it that way in your code.
See the CL Hyperspec for the rules: Congruent Lambda-lists for all Methods of a Generic Function.
All methods of a generic function must have a congruent argument list. Argument lists are congruent if you have the same number of required arguments, the same number of optional arguments, and use &rest and &key in a compatible way.
But, of course, you cannot specialize by the types of the &optional, &rest or &key arguments.
I'm confused about how defun macro works, because
(defun x () "hello")
will create function x, but symbol x still will be unbound.
If I'll bind some lambda to x then x will have a value, but it will not be treated by interpreter as function in form like this:
(x)
I think that it is related to the fact that defun should define function in global environment, but I'm not sure what does it exactly mean. Why can't I shadow it in the current environment?
Is there any way to force interpreter treat symbol as function if some lambda was bound to it? For example:
(setq y (lambda () "I want to be a named function"))
(y)
P.S.: I'm using SBCL.
Common Lisp has different namespaces for functions and values.
You define functions in the function namespace with DEFUN, FLET, LABELS and some others.
If you want to get a function object as a value, you use FUNCTION.
(defun foo (x) (1+ x))
(function foo) -> #<the function foo>
or shorter:
#'foo -> #<the function foo>
If you want to call a function, then you write (foo 100).
If you want to call the function as a value then you need to use FUNCALL or APPLY:
(funcall #'foo 1)
You can pass functions around and call them:
(defun bar (f arg)
(funcall f arg arg))
(bar #'+ 2) -> 4
In the case of DEFUN:
It is not (setf (symbol-value 'FOO) (lambda ...)).
It is more like (setf (symbol-function 'foo) (lambda ...)).
Note that the two namespaces enable you to write:
(defun foo (list)
(list list))
(foo '(1 2 3)) -> ((1 2 3))
There is no conflict between the built-in function LIST and the variable LIST. Since we have two different namespaces we can use the same name for two different purposes.
Note also that in the case of local functions there is no symbol involved. The namespaces are not necessarily tied to symbols. Thus for local variables a function lookup via a symbol name is not possible.
Common Lisp has multiple slots for each symbol, including a value-slot, and a function-slot. When you use the syntax (x), common lisp looks for the function-slot-binding of x. If you want to call the value-binding, use funcall or apply.
See http://cl-cookbook.sourceforge.net/functions.html