Scheme car计划的实施

Scheme car计划的实施,scheme,racket,Scheme,Racket,我正在尝试自己编写scheme中的cons函数。我编写了以下代码: (define (car. z) (z (lambda (p q) p))) 我试着跑: (car. '(1 2 3)) 我希望得到数字1,但它不能正常工作。当您实现语言数据结构时,您需要提供符合合同的构造函数和访问器: (car (cons 1 2)) ; ==> 1 (cdr (cons 1 2)) ; ==> 2 (pair? (cons 1 2)) ; ==> 2 以下是一个例子

我正在尝试自己编写scheme中的
cons
函数。我编写了以下代码:

(define (car. z)
    (z (lambda (p q) p))) 
我试着跑:

(car. '(1 2 3))

我希望得到数字
1
,但它不能正常工作。

当您实现语言数据结构时,您需要提供符合合同的构造函数和访问器:

(car (cons 1 2))   ; ==> 1
(cdr (cons 1 2))   ; ==> 2
(pair? (cons 1 2)) ; ==> 2
以下是一个例子:

(define (cons a d)
  (vector a d))
(define (car p)
  (vector-ref p 0))
(define (cdr p)
  (vector-ref p 1))
现在,如果您进行了一个实现,您将实现
读取
,以符合这种配对方式,以便
'(1 2 3)
将创建正确的数据结构。上面的简单规则仍然相同

car
看,我想象
cons
是这样的:

(define (cons a d)
  (lambda (p) (p a d)))
它与闭包一起工作。现在Scheme的堆栈机实现将分析通过其作用域的自由变量的代码,从而将它们创建为框。包含
a
d
的闭包与向量没有太大区别


我敦促您实现一个最低限度的方案解释器。因为您可以使用宿主语言,所以先使用Scheme,然后使用与lisp语言不同的语言。你甚至可以这样做,但这是非常耗时的

西尔维斯特的回答很好。下面是
null
null?
cons
car
cdr
-

(define null 'null)

(define (null? xs)
  (eq? null xs))

(define (cons a b)
  (define (dispatch message)
    (match message
      ('car a)
      ('cdr b)
      (_ (error 'cons "unsupported message" message))
  dispatch)

(define (car xs)
  (if (null? xs)
      (error 'car "cannot call car on an empty pair")
      (xs 'car)))

(define (cdr xs)
  (if (null? xs)
      (error 'cdr "cannot call cdr on an empty pair")
      (xs 'cdr)))
它是这样工作的-

(define xs (cons 'a (cons 'b (cons 'c null))))

(printf "~a -> ~a -> ~a\n"
        (car xs)
        (car (cdr xs))
        (car (cdr (cdr xs))))
;; a -> b -> c
在这些场景中会出现错误-

(cdr null)
; car: cannot call car on an empty pair

(cdr null)
; cdr: cannot call cdr on an empty pair

((cons 'a 'b) 'foo)
;; cons: unsupported dispatch: foo

如果你喜欢甜食,就加一点糖-

(define (cons a b)
  (define/match (dispatch msg)
    (('car) a)
    (('cdr) b)
    (('pair?) #t)
    ((_) (error 'cons "unsupported dispatch: ~a" msg)))
  dispatch)

((cons 1 2) 'car)   ;; 1
((cons 1 2) 'cdr)   ;; 2
((cons 1 2) 'pair?) ;; #t
((cons 1 2) 'foo)   ;; cons: unsupported dispatch: foo

在您对
car的定义中。
参数z用作应用于另一个函数的函数。在调用中,您传递的是一个列表,而不是函数。
car。
想要一个“lambda编码”列表,而不是方案列表。您需要实现相应的
cons.
操作,以便创建此类列表。正如@molbdnilo在评论中所说,您必须决定是将列表表示为功能对象(函数
car.
的定义),还是表示为数据结构(如在您的调用中),并统一操作。如果将列表表示为功能对象,则必须首先定义
cons
,并将此函数的结果传递给
car.
。实际上,真正的
car
cdr
cons
都是内置的(必须是内置的)。阅读Queinnec的@user10853826,您可以在中找到所有内容。或者看看这个例子