English 中文(简体)
Create a polynomial object from a number using change-class
原标题:

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 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.

问题回答

You can use COERCE or FLOAT to do that:

(float 4) => 4.0
(coerce 4  float) => 4.0




相关问题
How to make a list of arrays, not their symbols, in Lisp?

I m trying to make a function to get a delta between arrays, but right now just want to make a subset: get Nth element. (defvar p1 #(1 2)) (defvar p2 #(3 4)) (mapcar (lambda (x) (aref x 0)) (p1 ...

SBCL standard library documentation? [closed]

I want to learn and use SBCL because of its ease of learning and speed. (I ve been playing with Lisp 3 years ago, and now am refreshing it.) But how can I learn what s included in the standard library,...

returning a lambda function in clisp, then evaluating it

Suppose I have this wonderful function foo [92]> (defun foo () (lambda() 42)) FOO [93]> (foo) #<FUNCTION :LAMBDA NIL 42> [94]> Now, suppose I want to actually use foo and return 42. ...

A lisp function refinement

I ve done the Graham Common Lisp Chapter 5 Exercise 5, which requires a function that takes an object X and a vector V, and returns a list of all the objects that immediately precede X in V. It works ...

lambda-gtk negative pointer

I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative ...

Pointers in Lisp?

I ve started learning Lisp recently and wanted to write a program which uses gtk interface. I ve installed lambda-gtk bindings (on CMUCL). I want to have putpixel/getpixel ability on a pixbuf. But I ...

Is there a common lisp package naming convention?

I have created some of my own user packages and have run into a name clash. In Java, the naming convention is to use your domain name in the package name: e.g. import com.example.somepackage;. Are ...

热门标签