Lisp:基本的面向对象计数器

时间:2013-07-05 11:21:49

标签: object lisp closures common-lisp counter

我必须编写一个面向对象的计数器。首先,函数make-object应该用内部状态0实例化对象a和b。然后调用'methods':inc,:dec和:res(增加,减少,重置)。它应该是这样的:

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

到目前为止我的解决方案看起来像这样:

(defun make-object ()
  (let ((counter 0))
    (list #'(lambda () (incf counter))
          #'(lambda () (setf counter 0))
          #'(lambda () (decf counter)))))

使用

(setq a (make-object) b (make-object))

我可以实例化a和b,并使用

调用这些方法
(funcall (first a))
(funcall (second b))
(funcall (third a))

我尝试使用“:inc”而不是“first”调用方法:

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

但是有错误

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]

有人能帮帮我吗?如何让funcall为我做正确的事?


找到了解决方案。

(defun make-object () 
  (let ((count 0))
    (lambda (msg)
      (case msg
        ((:inc) (incf count))
        ((:dec) (decf count))
        ((:res) (setq count 0))))))

这就是我想要的。

1 个答案:

答案 0 :(得分:3)

这几乎正常。

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

( ... )COND表单附加var。你需要删除它。

first(等)也是变量引用。您需要致电(first var)

一旦你开始工作,你可能想要以不同的方式编写代码。如果MAKE-OBJECT将返回单个函数而不是三个函数列表,该怎么办?怎么可能有用?

下一个问题

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

上面没有意义。您想在FIRST的结果上调用函数var。然后,这将返回一个函数,然后通过FUNCALL调用该函数。