DrRacket中的简单嵌套评估

时间:2013-05-22 10:38:16

标签: lisp scheme racket r5rs

所以我正在为我的编程语言类解决一些练习问题,其中一个任务就是创建一个脚本“MyEval”,它允许你进行简单的嵌套加法和乘法。 因此,例如程序将能够执行此操作(MyEval '(1 +(3 *4)))或更深,但无需进行减法或超过2个数字和运算符。所以不那么复杂。然而,我的思绪是炒的,我会喜欢一些指导。 这就是我到目前为止所拥有的

#lang racket
(define ns (make-base-namespace))
(define (MyEval lis)
  (cond
    [(and ; neither is a list and can be evaluated
     (not(list? (car lis)))
     (not(list? (caddr lis)))
       )
    (eval (cons (cadr lis) (list (car lis) (caddr lis)) ) ns)]

    [(list? (car lis))
     (MyEval (car lis))]

    [(list? (caddr lis))
     (MyEval (caddr lis))]      

   ) ;end of cond
 ) ;end of define

但是你们可能会注意到这只会解决最后的内部括号,所以如果我(MyEval '(1 + (1 + 2)))我得到3而不是4。 任何指导或提示都表示赞赏,我不知道我的标题有多准确,但如果不合适请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:5)

通常一个好的计划是首先编写一些单元测试。函数应该返回某些输出的示例。试着考虑边界或角落的情况。例如:

(require rackunit)
(check-equal? (my-eval '(1 + (3 * 4)))
              13)
(check-equal? (my-eval '(20 + 20))
              40)
(check-equal? (my-eval 1) 
              1)

当然这些都会在最初失败。但你的目标是让他们通过。

接下来,您不需要使用eval,也不应该使用eval。你几乎不想在现实生活中使用eval。 (另外,实施match所实现的(某些)是不是你的练习的全部要点?)

最后,除非你有一个禁止它的课程作业,否则我建议使用car代替cadrmatch等。使用(define (my-eval x) (match x [(list lhs '* rhs) (* (my-eval lhs) (my-eval rhs))] [(list lhs '+ rhs) (+ (my-eval lhs) (my-eval rhs))] [(list) (list)] [_ x])) ,它只是:

match

您还可以对(define (my-eval x) (match x [`(,lhs * ,rhs) (* (my-eval lhs) (my-eval rhs))] [`(,lhs + ,rhs) (+ (my-eval lhs) (my-eval rhs))] [`() `()] [_ x])) 模式使用准引用,我通常会发现它更清晰。等价的,就是这样:

`

虽然有些人不喜欢所涉及的,list,但我更喜欢那些{{1}} s。