emacs - 使用 elisp 实现流

标签 emacs elisp sicp

我正在阅读 SICP 的第 3.5 节书,我正在努力实现 使用 Elisp 的流。本书使用Scheme语言实现流如下:

流的核心结构是一对,car是序列的当前值,cdr是评估下一项的 promise ,实现了具有以下构造:

(define (cons-stream a b) (cons a (delay b)))

其中 (delay b) 等同于 (lambda () b)

当计算这对的cdr时,它会强制计算流的延迟元素,以便我们可以获得下一个元素,实现如下:

(define (stream-cdr stream) (force (cdr stream)))

其中(force delayed-object)只是(delayed-object)的执行。

通过这种构造,我们现在可以轻松地透明地构建带有流的递归过程,就好像它们是 map 中的常规列表一样:

(define (stream-map proc stream)
    (if (stream-null? stream)
        the-empty-stream
      (cons-stream (proc (stream-car s))
                   (stream-map p (stream-cdr s)))))

我正在尝试使用 Elisp 编写类似的流实现,但我还没有找到实现 delay 的方法,以便它允许我以与 Scheme 类似的方式编写递归过程,目前我的解决方法是将延迟作为 lambda 表达式放在递归过程中,如下所示:

(defun stream-map (proc stream)
  (lexical-let ((p proc)
                (s stream))
    (if (stream-null? stream)
        the-empty-stream
      (cons-stream (funcall p (stream-car s))
                   (lambda ()
                     (stream-map p (stream-cdr s)))))))

这显然不像 Scheme 实现那么好。

这些是我创建流的核心函数的 Elisp 版本:

(defun cons-stream (a b) (cons a b))
(defun stream-cdr (stream) (sicp-force (cdr stream)))
(defun sicp-force (exp) (funcall exp))

如何编写 delay 和其他流函数,这样我就不必将 lambda 放在递归过程中?

最佳答案

感谢@Gerstmann 的建议,我能够编写出我正在寻找的结构。新的实现现在看起来像:

(setq the-empty-stream nil)
(defun stream-null? (s) (eq s the-empty-stream))
(defun my/sicp-delay (exp) `(lambda () ,exp))
(defun my/sicp-force (exp) (funcall exp))

(defmacro my/cons-stream (a b) (list 'cons a (my/sicp-delay b)))
(defun my/stream-car (stream) (car stream))
(defun my/stream-cdr (stream) (my/sicp-force (cdr stream)))

现在我可以编写看起来和 Scheme 实现一样干净的过程:

(defun my/stream-enumerate-interval (low high)
  (lexical-let ((l low)
                (h high))
    (if (> l h)
        the-empty-stream
      (my/cons-stream low
                      (my/stream-enumerate-interval (1+ l) h)))))

; this returns 12
(my/stream-car (my/stream-cdr (my/stream-cdr (my/stream-enumerate-interval 10 20))))

关于emacs - 使用 elisp 实现流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28979606/

相关文章:

Emacs 父模式列表

node.js - 我可以使用swank-js在js2模式下完成node.js API吗?

java - 需要专门学习Scheme了解Java和Python

Stack Overflow 的 Markdown 的 Emacs 模式

emacs - 将 hl-line 放在 Emacs 背景堆栈的最后

emacs - 在 emacs 中的 term-mode 中,退格在 ssh 中不起作用

Emacs/Emacs Lisp : can I insert advice before interactive form? 或者如何智能预设编译命令?

sql - 在 Emacs 中以另一种主要模式缩进 SQL

iteration - SICP - 我对阶乘迭代过程的递归定义不好吗?

python - 用 python 进行 SICP 的 Material ?