乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 37|回复: 3

[编程交流] 生成计数器:公共Lisp?

[复制链接]

10

主题

21

帖子

11

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
50
发表于 2022-7-6 07:49:59 | 显示全部楼层 |阅读模式
大家晚上好。
 
我最近开始看Abelson Sussman麻省理工学院关于计算机科学的讲座(主要是因为我觉得它们很有趣,不是因为它们与我的工作有很多关系),我偶然发现了这段代码来创建一个计数器:
 
  1. (define make-counter
  2. (lambda (N)
  3.    (lambda ()
  4.      (set! N (1+ N))
  5.      N)))
  6. (define c1 (make-counter 1))
  7. (define c2 (make-counter 10))

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

使用道具 举报

5

主题

1334

帖子

1410

银币

限制会员

铜币
-20
发表于 2022-7-6 08:28:13 | 显示全部楼层
使用完(c1)和(c2)后,必须将变量m和n置零,以使(c1)和(c2)可以重新开始。。。
 
  1. (defun make-counter (N)
  2. ((lambda (N) (setq N (1+ N))) N)
  3. )
  4. (defun c1 nil
  5. (if n (setq n (1+ n)) (setq n 1))
  6. (make-counter n)
  7. )
  8. (defun c2 nil
  9. (if m (setq m (1+ m)) (setq m 10))
  10. (make-counter m)
  11. )
  12. (defun nil-mn nil
  13. (setq n nil m nil)
  14. )

 
M、 R。
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

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

使用道具 举报

10

主题

21

帖子

11

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
50
发表于 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还是什么。
 
感谢大家抽出时间与我们合作。
 
编辑:略有改进。
 
  1. 4

 
使用这些例程,您可以创建一个计数器,并使用引导计数器以任何名称重新引导。我没有添加任何选项从零开始,但这很容易做到。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-9 21:58 , Processed in 0.452192 second(s), 60 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表