I need to program an object oriented counter. First, the make-object function must create objects a and b with an internal state of 0. Then the "methods" are called: inc ,: dec and: res (increase, decrease, reset). It should look like this:
> (setq a (make-object) b (make-object)) ... > (funcall a :inc) 1 > (funcall a :inc) 2 > (funcall a :res) 0 > (funcall a :dec) -1 > (funcall b :inc) 1
My solution so far is as follows:
(defun make-object () (let ((counter 0)) (list #'(lambda () (incf counter)) #'(lambda () (setf counter 0)) #'(lambda () (decf counter)))))
WITH
(setq a (make-object) b (make-object))
I can create an instance of a and b, and the methods are called using
(funcall (first a)) (funcall (second b)) (funcall (third a))
I tried the following to call methods with ": inc" instead of "first":
(defun myfuncall (var fun) (funcall ((cond ((equal fun ":inc") first) ((equal fun ":res") second) ((equal fun ":dec") third)) var)))
but there is a mistake
While compiling MYFUNCALL : In the form (#1=(COND ((EQUAL FUN ":inc") FIRST) ((EQUAL FUN ":res") SECOND) ((EQUAL FUN ":dec") THIRD)) VAR), #1# is not a symbol or lambda expression. [Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]
Can anybody help me? How do I make funcall right for me?
Found a solution.
(defun make-object () (let ((count 0)) (lambda (msg) (case msg ((:inc) (incf count)) ((:dec) (decf count)) ((:res) (setq count 0))))))
It does what I wanted.
source share