JackStone 发表于 2022-7-6 07:49:59

生成计数器:公共Lisp?

大家晚上好。
 
我最近开始看Abelson Sussman麻省理工学院关于计算机科学的讲座(主要是因为我觉得它们很有趣,不是因为它们与我的工作有很多关系),我偶然发现了这段代码来创建一个计数器:
 
(define make-counter
(lambda (N)
   (lambda ()
   (set! N (1+ N))
   N)))

(define c1 (make-counter 1))
(define c2 (make-counter 10))
关于上述代码的解释大约从48分钟开始。
 
我认为,语法既不是AutoLISP的语法,也不是Common Lisp的语法,主要是因为它是一篇演讲中的片段,上面代码的编写方式有很好的理由。
 
无论如何,当你第一次运行(c1)时,你会得到一个2;这是你第二次得了3等分。;当你运行(c2)时,你得到(无论何时运行(c1))11;下次你得到12等。
 
我试图将其翻译为AutoLISP:
 
问题是这不起作用。当我试图在N为零的情况下计算它时,我得到了一个错误。如果N预设为某个整数/实数,则无论调用c1或c2,它都将递增。
 
我想知道我是否做错了什么,或者这是我在AutoLISP中无法完成的事情。这段代码能像苏斯曼在演讲中展示的那样运行吗?这里有陷阱吗?
 
显然,这不是生死攸关的问题,我对另一段作为计数器的代码不感兴趣(尽管我很高兴看到你们提出的任何一个代码),因为这是我可以轻松解决的问题。我只想知道这是否可以在AutoLISP中工作,如果可以,如何工作。
 
谢谢大家!

marko_ribar 发表于 2022-7-6 08:28:13

使用完(c1)和(c2)后,必须将变量m和n置零,以使(c1)和(c2)可以重新开始。。。
 

(defun make-counter (N)
((lambda (N) (setq N (1+ N))) N)
)

(defun c1 nil
(if n (setq n (1+ n)) (setq n 1))
(make-counter n)
)

(defun c2 nil
(if m (setq m (1+ m)) (setq m 10))
(make-counter m)
)

(defun nil-mn nil
(setq n nil m nil)
)

 
M、 R。

Lee Mac 发表于 2022-7-6 08:41:58

嗨,杰克,
 
在您的示例中,由于符号“N”是“make counter”函数的参数,因此其作用域将位于“make counter”函数内。调用此函数时,参数“N”将继承传递给函数的值,然后,当“make counter”函数完成执行时,符号“N”将恢复其在调用“make counter”函数之前保留的任何值。
 
Marko的示例使用了全局变量,这些变量不局限于任何函数,因此位于文档命名空间中,并且适用于所有非局部变量或参数的函数。

JackStone 发表于 2022-7-6 08:52:37

先生们,
 
谢谢你的帮助。然而,我对使用全局变量(而不是计数器函数本身的名称)使这个计数器成为可能感到不满意。
 
我把这个问题放在一边一段时间,但就在昨天,我发现了关于函数defun-q、defun-q-list-ref和defun-q-list-set的内容,我的脑海中似乎再次出现了make counter例程。
 
在使用这些功能几个小时后,我终于做到了我想要的。我的代码看起来一点也不像Abelson-Sussman,这是肯定的,但我相信我已经通过每次调用函数c1和c2时重写它们来模拟一个帧。
 
 
每次需要重置调用boot的计数器时-*CounterName*。从那时起,每次调用计数器(例如(c1))时,它都会递增,c1函数本身也会被重写。计数器c1和c2(以及您想要创建的任何其他计数器)独立工作。
 
我把代码贴在这里,这样我可以得到你的意见。我以前从来没有写过这样的东西,所以我需要知道它是buggy还是什么。
 
感谢大家抽出时间与我们合作。
 
编辑:略有改进。
 
4
 
使用这些例程,您可以创建一个计数器,并使用引导计数器以任何名称重新引导。我没有添加任何选项从零开始,但这很容易做到。
页: [1]
查看完整版本: 生成计数器:公共Lisp?