# simple “if”-less algebraic computation using CLOS

For educational purposes I've tried to implement a simple algebraic OOP example using CLOS. The functionality is as far as I can say as it is supposed to be. The intended approach was to implement a simple example of ideomatic OOP polymorphism. For a greater learning experience I've wanted to show the code to get suggestions, critic and so on.

``````;; main node class, most general
(defclass node ()
;; abstract class for nodes

(defgeneric evaluate (node)
(:documentation "the standard evaluation"))

;; node containing an operation, more specific
(defclass op-node (node)
;; abstract class for a node containing an operation
((left-node  :initform nil :initarg :left-node  :reader left-node)
(right-node :initform nil :initarg :right-node :reader right-node)))

(defmethod evaluate ((node op-node))
(apply (value node)
(list (evaluate (left-node node))
(evaluate (right-node node)))))

;; concrete nodes

(defclass minus-node (op-node)
;; class for subtraction

(defclass multi-node (op-node)
;; class for multiplication

(defclass value-node (node)
;; class for a node containing a numerical value

(defmethod evaluate (value-node)
(value value-node))

;; 1 + 3
:left-node  (make-instance 'value-node :value 1)
:right-node (make-instance 'value-node :value 3)))

;; 1 * 10
(setf *simple-multi* (make-instance 'multi-node
:left-node  (make-instance 'value-node :value 1)
:right-node (make-instance 'value-node :value 10)))

;; (1 + 3) + (1 * 10)
:right-node *simple-multi*))

(evaluate *simple-multi*  ;; => 10
``````
-

``````(defmethod evaluate ((node op-node))
(apply (value node)
(list (evaluate (left-node node))
(evaluate (right-node node)))))
``````

can be written:

``````(defmethod evaluate ((node op-node))
(funcall (value node)
(evaluate (left-node node))
(evaluate (right-node node))))
``````

For this example, instead of different subclasses for every binary operation, you could just use a `binop` class and instantiate it with the respective functions, since they share the same `evaluate` method, but that depends on what else you want do do with the nodes. (Maybe, for example, you want to have different `print-object` methods for each of them.)

(Also, using toplevel `setf`s on unestablished symbols is considered bad style, but I suppose this was just for testing and demonstration purposes. In real code, `defparameter` or `defvar` should be used.)

-
Is there any difference between using `apply` and `funcall` in this case? Are there cases where one is better usage instead of the other? The `binop` class hint is very good! I thought of abstracting it more but I wasn't sure how to do it without getting the code too confusing. –  beyeran Aug 25 '12 at 7:47
lispworks.com/documentation/HyperSpec/Body/f_funcal.htm: `(funcall function arg1 arg2 ...) == (apply function arg1 arg2 ... nil) == (apply function (list arg1 arg2 ...))`. So no, there is no difference in this case. Just use whatever is less convoluted. –  danlei Aug 25 '12 at 9:38
``````(defmethod evaluate (value-node)