如何获取 SICP、Scheme、练习 2.78 等中的 put 和 get 函数

发布于 2024-10-29 18:37:15 字数 166 浏览 1 评论 0 原文

我正在尝试在 SICP 中做练习 2.78,但 put 和 get 函数未知。我尝试过多种语言,比如相当大、racket、r5rs、mit-scheme、mzscheme等。我什至下载了SICP支持(http://www.neilvandyke.org/sicp-plt/),但没有成功。我怎样才能让这些功能发挥作用?

I am trying to do exercise 2.78 in SICP, but the functions put and get are unknown. I have tried multiple languages, like pretty big, racket, r5rs, mit-scheme, mzscheme, etc. I even downloaded the SICP support (http://www.neilvandyke.org/sicp-plt/), to no avail. How can I get these functions to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清引 2024-11-05 18:37:15

是的,我发现 SICP 有时因为这样的事情有点烦人。假设存在但实际不存在的函数使得尝试示例变得更加困难。我像这样编写了自己的 (get) 和 (put)(这是 GNU guile 中的):

(define global-array '())

(define (make-entry k v) (list k v))
(define (key entry) (car entry))
(define (value entry) (cadr entry))

(define (put op type item)
  (define (put-helper k array)
    (cond ((null? array) (list(make-entry k item)))
          ((equal? (key (car array)) k) array)
          (else (cons (car array) (put-helper k (cdr array))))))
  (set! global-array (put-helper (list op type) global-array)))

(define (get op type)
  (define (get-helper k array)
    (cond ((null? array) #f)
          ((equal? (key (car array)) k) (value (car array)))
          (else (get-helper k (cdr array)))))
  (get-helper (list op type) global-array))

从本书后面的角度来看,这可能是一个幼稚的实现,但相当简单且工作正常。

Yes, I found SICP a little annoying sometimes because of stuff like this. Functions that are assumed to exist but don't actually exist make it harder to try to the examples. I wrote my own (get) and (put) like so (this was in GNU guile):

(define global-array '())

(define (make-entry k v) (list k v))
(define (key entry) (car entry))
(define (value entry) (cadr entry))

(define (put op type item)
  (define (put-helper k array)
    (cond ((null? array) (list(make-entry k item)))
          ((equal? (key (car array)) k) array)
          (else (cons (car array) (put-helper k (cdr array))))))
  (set! global-array (put-helper (list op type) global-array)))

(define (get op type)
  (define (get-helper k array)
    (cond ((null? array) #f)
          ((equal? (key (car array)) k) (value (car array)))
          (else (get-helper k (cdr array)))))
  (get-helper (list op type) global-array))

Probably a naive implementation from the perspective of later in the book, but fairly simple and worked fine.

吻安 2024-11-05 18:37:15

伊莱·本德斯基
这些功能可以使用内置 基本哈希表操作。这是我对 Eli 代码的修改版本,以便与 MIT-Scheme 版本 9.1.1 正常工作。

(define *op-table* (make-hash-table))

(define (put op type proc)
  (hash-table/put! *op-table* (list op type) proc))

(define (get op type)
  (hash-table/get *op-table* (list op type) '()))

更新

我在一段时间后发现了上述代码的错误。空列表在Scheme的条件子句中被解释为true,因此正确的get实现应该如下:

(define (get op type)
  (hash-table/get *op-table* (list op type) #f))

There is an implementation of put and get by Eli Bendersky.
These functions could be implemented using builtin Basic Hash Table Operations. Here is my modified version of Eli's code to work properly with MIT-Scheme Release 9.1.1.

(define *op-table* (make-hash-table))

(define (put op type proc)
  (hash-table/put! *op-table* (list op type) proc))

(define (get op type)
  (hash-table/get *op-table* (list op type) '()))

UPDATED:

I've found bug with above mentioned code after time. Empty lists are interpreted as true in conditional clauses by Scheme, so correct get implementation should be following:

(define (get op type)
  (hash-table/get *op-table* (list op type) #f))
够钟 2024-11-05 18:37:15

如果您使用 Racket 编程语言,请使用这些:

(define *op-table* (make-hash))

(define (put op type proc)
  (hash-set! *op-table* (list op type) proc))

(define (get op type)
  (hash-ref *op-table* (list op type) '()))

If you use Racket programming language please use these:

(define *op-table* (make-hash))

(define (put op type proc)
  (hash-set! *op-table* (list op type) proc))

(define (get op type)
  (hash-ref *op-table* (list op type) '()))
旧情勿念 2024-11-05 18:37:15

3.3.3表示表创建本地表小节中,有一个实现。

In subsection Creating local tables of 3.3.3 Representing Tables, there is an implementation.

橘香 2024-11-05 18:37:15

mit-scheme 有一个可供您使用的内置全局表。

http://www.gnu .org/software/mit-scheme/documentation/mit-scheme-ref/The-Association-Table.html

只需定义 get 和 put 即可:

(define get 2d-get)
(define put 2d-put!)

mit-scheme has a built-in global table that you can use.

http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/The-Association-Table.html

simply define get and put to:

(define get 2d-get)
(define put 2d-put!)
Smile简单爱 2024-11-05 18:37:15

@Shen Yang 提到的,第 366~367 页的 3.3.3 表示表部分有一个实现

(define operation-table (make-table)) 
(define get (operation-table 'lookup-proc)) 
(define put (operation-table 'insert-proc!))

正如 “make-table”定义为:

(define (make-table)
  (let ((local-table (list '*table*)))
    (define (lookup key-1 key-2)
      (let ((subtable
             (assoc key-1 (cdr local-table))))
        (if subtable
            (let ((record
                   (assoc key-2 (cdr subtable))))
              (if record (cdr record) false))
            false)))
    (define (insert! key-1 key-2 value)
      (let ((subtable
             (assoc key-1 (cdr local-table))))
        (if subtable
            (let ((record
                   (assoc key-2 (cdr subtable))))
              (if record
                  (set-cdr! record value)
                  (set-cdr! subtable
                            (cons (cons key-2 value)
                                  (cdr subtable)))))
            (set-cdr! local-table
                      (cons (list key-1 (cons key-2 value))
                            (cdr local-table)))))
      'ok)
    (define (dispatch m)
      (cond ((eq? m 'lookup-proc) lookup)
            ((eq? m 'insert-proc!) insert!)
            (else (error "Unknown operation: TABLE" m))))
    dispatch))

there is an implementation in section 3.3.3 Representing Tables, on Page 366~367, as mentioned by @Shen Yang

(define operation-table (make-table)) 
(define get (operation-table 'lookup-proc)) 
(define put (operation-table 'insert-proc!))

and the "make-table" is defined as:

(define (make-table)
  (let ((local-table (list '*table*)))
    (define (lookup key-1 key-2)
      (let ((subtable
             (assoc key-1 (cdr local-table))))
        (if subtable
            (let ((record
                   (assoc key-2 (cdr subtable))))
              (if record (cdr record) false))
            false)))
    (define (insert! key-1 key-2 value)
      (let ((subtable
             (assoc key-1 (cdr local-table))))
        (if subtable
            (let ((record
                   (assoc key-2 (cdr subtable))))
              (if record
                  (set-cdr! record value)
                  (set-cdr! subtable
                            (cons (cons key-2 value)
                                  (cdr subtable)))))
            (set-cdr! local-table
                      (cons (list key-1 (cons key-2 value))
                            (cdr local-table)))))
      'ok)
    (define (dispatch m)
      (cond ((eq? m 'lookup-proc) lookup)
            ((eq? m 'insert-proc!) insert!)
            (else (error "Unknown operation: TABLE" m))))
    dispatch))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文