我正在使用著名的《如何设计程序》一书。更具体地说,第一版(我有实体版)。
在第6章中,有一些关于结构的练习。其中之一,您需要模拟交通灯并使用效果(突变)来改变它们。
我指的是在练习 练习6.2.5有关函数next是想给你红绿灯的一个颜色。
书中提供的答卷为:
(start 50 160)
(draw-solid-disk (make-posn 25 30) 20 'red)
(draw-circle (make-posn 25 80) 20 'yellow)
(draw-circle (make-posn 25 130) 20 'green)
; -------------------------------------------------------------------------
;; clear-bulb : symbol -> true
;; to clear one of the traffic bulbs
(define (clear-bulb color)
(cond
[(symbol=? color 'red)
(and (clear-solid-disk (make-posn 25 30) 20)
(draw-circle (make-posn 25 30) 20 'red))]
[(symbol=? color 'yellow)
(and (clear-solid-disk (make-posn 25 …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
在第7章的进阶部分,作者建议使用trace功能。这无疑是一个非常有价值的工具。我很高兴看到它起作用了。
然而,显然,我的工具并不能完全像作者介绍的那样工作。
做如下定义后:
(defun find-first-odd (x)
(find-if #’oddp x))
Run Code Online (Sandbox Code Playgroud)
并在 REPL 上运行:
> (dtrace find-first-odd oddp)
Run Code Online (Sandbox Code Playgroud)
他得到:
> (find-first-odd ’(2 4 6 7 8))
----Enter FIND-FIRST-ODD
| X = (2 4 6 7 8)
| ----Enter ODDP
| | NUMBER = 2
| \--ODDP returned NIL
| ----Enter ODDP
| | NUMBER = 4
| \--ODDP returned NIL
| ----Enter ODDP
| | NUMBER = 6
| \--ODDP …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 10 章结束时,作者讨论了有用的 break 函数。为了提供背景上下文,他提出了这个有问题的函数:
(defun analyze-profit (price commission-rate)
(let* ((commission (* price commission-rate))
(result
(cond ((> commission 100) 'rich)
((< commission 100) 'poor))))
(format t "~&I predict you will be: ~S"
result)
result))
Run Code Online (Sandbox Code Playgroud)
该函数按预期工作,在 REPL 中使用以下参数调用:
> (analyze-profit 1600 0.15)
I predict you will be: RICH
RICH
> (analyze-profit 3100 0.02)
I predict you will be: POOR
POOR
Run Code Online (Sandbox Code Playgroud)
但是,当commission正好是 100时,它会显示错误的结果:
> (analyze-profit 2000 0.05)
I predict you …Run Code Online (Sandbox Code Playgroud) 我正在尝试安装这个名为 Next browser 的软件。在brew.sh上有一个关于它的页面。
当我在Ubuntu 18.04 LTS终端上运行 homebrew 网页上显示的命令时:
$ brew install --cask next
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
Updating Homebrew...
Error: Cask 'next' is unavailable: No Cask with this name exists.
Run Code Online (Sandbox Code Playgroud)
观察,我能够成功安装其他软件包,例如:
brew install hello
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
有没有办法来解决这个问题?
我习惯了 Racket,我正在努力学习 Common Lisp。在 Racket 中,符号对自身进行评估,如 Dr Racket 的 REPL 所示:
> 'racket
'racket
Run Code Online (Sandbox Code Playgroud)
根据文献,在 Common Lisp 中,符号也会对自身求值。
实际上,引用对象的评估规则是:
带引号的对象计算为对象本身,不带引号。
在使用 REPL(Common Lisp、SBCL 和 Slime)时,我得到:
> 'common-lisp
common-lisp
Run Code Online (Sandbox Code Playgroud)
我觉得我需要接受有关两种语言设计之间对比的教育。
为什么会这样?考虑到 CL 的设计作为一种语言,这样做有什么意义?
我是否错过了关于 CLOS 的深刻见解?
我仍在为在不久的将来更好地了解 CLOS 打下基础。
谢谢
我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 8 章的结尾,作者将调试器介绍为 lisp 编程的重要工具之一。然后,为了展示它,他break在类似阶乘的函数定义中使用了命令:
(defun fact-debugging (n)
(cond ((zerop n) (break "N is zero."))
(t (* n (fact-debugging (- n 1))))))
Run Code Online (Sandbox Code Playgroud)
在 REPL 中调用函数后:
CL-USER> (fact-debugging 4)
Run Code Online (Sandbox Code Playgroud)
我得到了控制堆栈。. 我特别好奇回溯部分:
N is zero.
[Condition of type SIMPLE-CONDITION]
Restarts:
0: [CONTINUE] Return from BREAK.
1: [RETRY] Retry SLIME REPL evaluation request.
2: [*ABORT] Return to SLIME's top level.
3: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
在第 8 章的高级部分,作者介绍了labels特殊功能。实际上,他将在顶层(主函数和辅助函数)上定义事物与label在函数内部使用表达式进行了对比。
例如,这将是一个reverse使用顶级方法进行尾调用的列表函数:
(defun reverse-top-level-helper (xs-left accu)
(cond ((null xs-left) accu)
(t (reverse-top-level-helper (cdr xs-left)
(cons (car xs-left)
accu)))))
(defun reverse-top-level-main (xs)
(reverse-top-level-helper xs nil))
Run Code Online (Sandbox Code Playgroud)
另一方面,下面的代码将使用labels:
(defun reverse-labels (xs)
(labels ((aux-label (xs-left accu)
(cond ((null xs-left) accu)
(t (aux-label (cdr xs-left)
(cons (car xs-left) accu))))))
(aux-label xs nil)))
Run Code Online (Sandbox Code Playgroud)
因此,标签方法避免了人们将顶层的辅助函数搞砸的机会。与顶级方法不同,标签方法可以访问主函数的局部变量。
不幸的是,根据作者的说法,在大多数 lisp 实现中,没有办法跟踪标签表达式中的函数。这似乎是我的情况,因为我是从 REPL 得到的:
CL-USER> (trace aux-label)
WARNING: COMMON-LISP-USER::AUX-LABEL is undefined, …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过《Common Lisp:符号计算的温和介绍》一书来学习 Common Lisp 。此外,我正在使用 SBCL、Emacs 和 Slime。
到第 10 章结束时,在高级部分有这个问题:
10.9. 编写一个破坏性函数 CHOP,将任何非 NIL 列表缩短为一个元素的列表。(CHOP '(FEE FIE FOE FUM)) 应该返回 (FEE)。
这是答题纸的解决方案:
(defun chop (x)
(if (consp x) (setf (cdr x) nil))
x)
Run Code Online (Sandbox Code Playgroud)
我理解这个解决方案。但是,在查看官方解决方案之前,我尝试过:
(defun chop (xs)
(cond ((null xs) xs)
(t (setf xs (list (car xs))))))
Run Code Online (Sandbox Code Playgroud)
使用它作为测试的全局变量:
(defparameter teste-chop '(a b c d))
Run Code Online (Sandbox Code Playgroud)
我试过 REPL:
CL-USER> (chop teste-chop)
(A)
Run Code Online (Sandbox Code Playgroud)
如您所见,该函数返回预期结果。
不幸的是,不会发生改变原始列表的副作用:
CL-USER> teste-chop
(A B C D)
Run Code Online (Sandbox Code Playgroud)
为什么它没有改变?
由于我将整个列表的字段 (setf) 设置为仅将其汽车包装为新列表,因此我希望原始列表的 cdr …
我正在阅读Sonja Keene 的《Common Lisp 中的面向对象编程》一书。
在第 2 章中,作者说:
确定调用哪些方法然后调用它们的过程称为泛型调度。每当调用通用函数时,它都会自动发生。
这让我想起了 Dynamic Dispatch 定义(根据Wikipedia):
动态分派是选择在运行时调用多态操作的哪个实现的过程。它通常用于面向对象的编程语言和系统,并被认为是面向对象的编程语言和系统的主要特征。
不幸的是,维基百科目前不具备有关条目的通用调度。
因此,我想问:
1 - 动态调度和通用调度基本上是一回事吗?有哪些相似之处?
2 - 有什么区别?由于 CLOS 的灵活性,动态调度是否是通用调度的某种子集?
我正在使用 Slime (Emacs) 和 Common Lisp (SBCL)。计算表达式后,REPL 返回 CL 对象列表:
(#<BOOKMARK-ENTRY {1009AFB963}> #<BOOKMARK-ENTRY {1009AFD5A3}>
#<BOOKMARK-ENTRY {1009AFDB53}> #<BOOKMARK-ENTRY {1009AFE0E3}>
#<BOOKMARK-ENTRY {1009AFE683}> #<BOOKMARK-ENTRY {1009AFEC23}>
#<BOOKMARK-ENTRY {1009AFF173}> #<BOOKMARK-ENTRY {1009AFF753}>
#<BOOKMARK-ENTRY {1009AFFCD3}> #<BOOKMARK-ENTRY {1009B00233}>
#<BOOKMARK-ENTRY {1009B00783}> #<BOOKMARK-ENTRY {1009B00CE3}>
#<BOOKMARK-ENTRY {1009B01253}> #<BOOKMARK-ENTRY {1009B01823}>
#<BOOKMARK-ENTRY {1009B01DD3}> #<BOOKMARK-ENTRY {1009B02393}>
#<BOOKMARK-ENTRY {1009B028B3}> #<BOOKMARK-ENTRY {1009B02E13}>
#<BOOKMARK-ENTRY {1009B03373}> #<BOOKMARK-ENTRY {1009B03903}>
#<BOOKMARK-ENTRY {1009B03EB3}> #<BOOKMARK-ENTRY {1009B04453}>
#<BOOKMARK-ENTRY {1009B049F3}> #<BOOKMARK-ENTRY {1009B04F23}>
#<BOOKMARK-ENTRY {1009B054A3}> #<BOOKMARK-ENTRY {1009B05AB3}>
#<BOOKMARK-ENTRY {1009B05FF3}> #<BOOKMARK-ENTRY {1009B06513}>
#<BOOKMARK-ENTRY {1009B06A83}> #<BOOKMARK-ENTRY {1009B07133}>
#<BOOKMARK-ENTRY {1009B076B3}> #<BOOKMARK-ENTRY {1009B07C13}>
#<BOOKMARK-ENTRY {1009B08213}>)
Run Code Online (Sandbox Code Playgroud)
如果我单击检查列表,则会打开一个新窗口,其中列出了所有对象:
#<CONS {1009AFCBB7}>
-------------------- …Run Code Online (Sandbox Code Playgroud) common-lisp ×8
slime ×3
debugging ×2
racket ×2
trace ×2
break ×1
clos ×1
evaluation ×1
homebrew ×1
htdp ×1
in-place ×1
installation ×1
mutability ×1
oop ×1
recipe ×1
sbcl ×1
scheme ×1
stack-frame ×1
symbols ×1
types ×1