参数存储为对而不是数字?

时间:2014-11-26 00:32:02

标签: scheme lisp

在大学,我们正在为Scheme建立一个Scheme Interpreter。在下面的代码中,您可以看到plus运算符的实现。

#lang racket

(define (EVAL e)
    (if (pair? e) ;if its a pair its a function -> call EVALFunctionCall
        (EVALFunctionCall e)
        (null))) ;null - other cases are not implemented

(define (EVALFunctionCall e)
    (if (eq? (car e) '+) ;if its + its addition -> call EVALPlus
        (EVALPlus (cdr e))
        (null))) ;null - other cases are not implemented

(define (EVALPlus argList) 
    ;for debugging
    (display (car argList))(display "\n")
    (display (cdr argList))(display "\n")
    (display (car (cdr argList)))(display "\n")
    (display (cdr (cdr argList)))(display "\n")

    (+ (car argList) (cdr argList)))

(EVAL '(+ 1 2))应评估为3。但事实并非如此。相反,我得到一个错误。 这是因为(cdr argList)(我传递给+ -function的第二个参数)不是数字而是一对。我为调试添加的显示打印出来:

1
(2)
2
()

我很确定这是教授在课程中展示的代码(有效)。那我错了什么?我的教授是否有可能使用另一种方案 - 方言'(+ 1 2)保存(+(1 2))而不是(+(1(2 null)))

2 个答案:

答案 0 :(得分:1)

您的代码中有一点错误,请在EVALPlus程序中尝试此操作:

(+ (car argList) (car (cdr argList)))

请记住cdr检索下一个列表,而不是下一个元素。获得下一个列表后,我们调用car来获取它的第一个元素。

答案 1 :(得分:0)

嗯,显而易见的解决方案是:

(define (EVALPlus argList)
   (apply + argList))

但是,由于练习是关于实现Scheme解释器,这可能是作弊; - )

那么简单的累积总和如何:

(define (EVALPlus argList)
   (cond ((null? argList) 0)
         ((null? (cdr argList)) (car argList))
         (#t (+ (car argList) (EVALPlus (cdr argList))))))

或者,如果您不被允许cond

(define (EVALPlus argList)
   (if (null? argList) 0
      (if (null? (cdr argList)) (car argList)
         (+ (car argList) (EVALPlus (cdr argList))))))

一如既往,要注意特殊情况:

(EVAL '(+)) ; no argument
=> 0
(EVAL '(+ 42)) ; only one argument
=> 42
(EVAL '(+ 1 3 5 7 9)) ; n arguments
=> 25

希望它有所帮助。