Lisp: rudimentary object oriented counter

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.

+4
source share
1 answer

It almost works.

 (defun myfuncall (var fun) (funcall ((cond ((equal fun ":inc") first) ((equal fun ":res") second) ((equal fun ":dec") third)) var))) 

In COND and var there is an extra ( ... ) . You need to remove it.

Also first (etc.) will be a reference to variables. You need to call (first var) .

Once you get this, you can write your code differently. What if MAKE-OBJECT returns one function and not a list of three functions. How can this work?

Next problem

 ((equal fun ":inc") 'first var) 

There is no sense above. You want to call the first function on the result of var . This then returns a function, which is then called through FUNCALL .

+3
source

Source: https://habr.com/ru/post/1489888/


All Articles