List 如何在Scheme中复制程序?

List 如何在Scheme中复制程序?,list,scheme,List,Scheme,因此,从SICP我们知道conscar和cdr可以定义为一个过程: (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (define (cdr z) (z (lambda (p q) q))) 但是预定义的过程list,它使用参数来构建列表,使用原始的cons。这意味着,构建的列表不是我想要的过程 (car (list 1 2 3)) ;The Object

因此,从SICP我们知道
cons
car
cdr
可以定义为一个过程:

(define (cons x y)
    (lambda (m) (m x y)))

(define (car z)
    (z (lambda (p q) p)))

(define (cdr z)
    (z (lambda (p q) q)))
但是预定义的过程
list
,它使用参数来构建列表,使用原始的
cons
。这意味着,构建的列表不是我想要的过程

(car (list 1 2 3))
;The Object (1 2 3) is not applicable
所以我写下:

(define (list . l)
    (if (null? l)
        '()
        (cons (original-car l)
              (list (original-cdr l)))))

我只是想知道如何定义
原装车
原装cdr
。是否有办法在Scheme中复制程序?或者有其他方法来解决这个问题。实现中的thx列表定义为

(define (list . l) l)
然而,这使用了很多底层实现。例如,为了工作,它使用本地cons<如
SICP
中所定义的code>cons是一个思想实验,因此您的实现需要一些修正:

(define (my-cons x y)
    (lambda (m) (m x y)))

(define (my-car z)
    (z (lambda (p q) p)))

(define (my-cdr z)
    (z (lambda (p q) q)))

(define (my-list . l)
  (define (my-list-aux l)
    (if (null? l)
        '()
        (my-cons (car l)
                 (my-list-aux (cdr l)))))
  (my-list-aux l))

;; optional, update binding
(define car my-car)
(define cdr my-cdr)
(define list my-list)

我的缺点、我的车、我的cdr和我的清单都在你的问题中定义。唯一的更改是引用正确的过程(名称与方案不冲突)

实现中的列表定义为

(define (list . l) l)
然而,这使用了很多底层实现。例如,为了工作,它使用本地cons<如
SICP
中所定义的code>cons是一个思想实验,因此您的实现需要一些修正:

(define (my-cons x y)
    (lambda (m) (m x y)))

(define (my-car z)
    (z (lambda (p q) p)))

(define (my-cdr z)
    (z (lambda (p q) q)))

(define (my-list . l)
  (define (my-list-aux l)
    (if (null? l)
        '()
        (my-cons (car l)
                 (my-list-aux (cdr l)))))
  (my-list-aux l))

;; optional, update binding
(define car my-car)
(define cdr my-cdr)
(define list my-list)

我的缺点、我的车、我的cdr和我的清单都在你的问题中定义。唯一的更改是对正确过程的引用(名称与方案不冲突)

如果您需要在重新定义“原始”过程之前保存对它们的引用,只需在定义“新”过程之前创建一个别名(我想这就是“复制”它们的意思)。像这样:

(define original-cons cons)
(define original-car car)
(define original-cdr cdr)
(define original-list list)
这样,旧的过程仍然可以使用,只要我们用它们的新名称来引用它们。换句话说,
cons
car
cdr
list
作为过程的实现如下所示:

(define (my-cons x y)
  (lambda (m) (m x y)))

(define (my-car z)
  (z (lambda (p q) p)))

(define (my-cdr z)
  (z (lambda (p q) q)))

(define (my-list . els)
  (if (null? els)
      '()
      (my-cons
       (original-car els)
       (apply my-list (original-cdr els)))))
果不其然,它是有效的:

(define lst (my-list 1 2 3 4))
lst
=> #<procedure>
(my-car lst)
=> 1
(my-car (my-cdr lst))
=> 2
(定义lst(我的列表1 2 3 4))
lst
=> #
(我的车是lst)
=> 1
(我的车(我的cdr lst))
=> 2

如果需要在重新定义“原始”过程之前保存对它们的引用,只需在定义“新”过程之前创建一个别名(我想这就是“复制”它们的意思)。像这样:

(define original-cons cons)
(define original-car car)
(define original-cdr cdr)
(define original-list list)
这样,旧的过程仍然可以使用,只要我们用它们的新名称来引用它们。换句话说,
cons
car
cdr
list
作为过程的实现如下所示:

(define (my-cons x y)
  (lambda (m) (m x y)))

(define (my-car z)
  (z (lambda (p q) p)))

(define (my-cdr z)
  (z (lambda (p q) q)))

(define (my-list . els)
  (if (null? els)
      '()
      (my-cons
       (original-car els)
       (apply my-list (original-cdr els)))))
果不其然,它是有效的:

(define lst (my-list 1 2 3 4))
lst
=> #<procedure>
(my-car lst)
=> 1
(my-car (my-cdr lst))
=> 2
(定义lst(我的列表1 2 3 4))
lst
=> #
(我的车是lst)
=> 1
(我的车(我的cdr lst))
=> 2

(定义原车)
?我想我不明白你想做什么。我使用鸡肉方案,而且
(car'(1 2 3))
效果很好,就像
(car(1 2 3))
@cmt一样,它在任何情况下都会很好scheme@cmt这不是我想要的。我只想定义一个
列表
过程来调整我的lambda版本cons和car/cdr。
(定义原始汽车)
?我想我不明白你想做什么。我使用鸡肉方案,而且
(car'(1 2 3))
效果很好,就像
(car(1 2 3))
@cmt一样,它在任何情况下都会很好scheme@cmt这不是我想要的。我只想定义一个
列表
过程来适应我的lambda版本cons和car/cdr。由于某种原因,我不得不重载默认过程
car
cdr
cons
。这是我最大的问题。另一个问题是,我的过程
my list
应该是
(my list.l)
(否则
(my list 1 2 3)
会引发一个参数错误),但如果定义为
。l
,l是由原始的
cons
构建的列表,而不是我的lambda版本。所以我只想复制一份原始的
汽车
cdr
来取出物体。西尔维斯特的答案是正确的。使用他的
my list
实现。只需创建另一个名为
list
的函数,它实际上执行
(定义(list.l)(我的列表(carl))
@cmt。这不太对。我已经更新了我的答案。您可以按照您在问题中所做的操作,在他们的名字被定义为如下
(定义汽车我的汽车)后更改他们的名字
这不会改变定义中的调用,因为过程有其词汇环境。出于某种原因,我必须重载默认过程
car
cdr
cons
。这是我最大的问题。另一个问题是,我的过程
my list
应该是
(my list.l)
(否则
(my list 1 2 3)
会引发一个参数错误),但如果定义为
。l
,l是由原始的
cons
构建的列表,而不是我的lambda版本。所以我只想复制一份原始的
汽车
cdr
来取出物体。西尔维斯特的答案是正确的。使用他的
my list
实现。只需创建另一个名为
list
的函数,它实际上执行
(定义(list.l)(我的列表(carl))
@cmt。这不太对。我已经更新了我的答案。您可以按照您在问题中所做的操作,在他们的名字被这样定义后更改他们的名字
(define car my car)
,这不会改变定义中所调用的内容,因为过程有它的词汇环境。