Lisp DrRacket中的简单嵌套求值
所以我正在为我的编程语言课做一些练习题,其中一个作业是创建一个脚本“MyEval”,它允许你做简单的嵌套加法和乘法。 例如,该程序可以执行Lisp DrRacket中的简单嵌套求值,lisp,scheme,racket,r5rs,Lisp,Scheme,Racket,R5rs,所以我正在为我的编程语言课做一些练习题,其中一个作业是创建一个脚本“MyEval”,它允许你做简单的嵌套加法和乘法。 例如,该程序可以执行(MyEval'(1+(3*4))或更深层的操作,但不必执行减法或两个以上的数字和一个运算符。没那么复杂。然而,我的思想是油炸的,我希望得到一些指导。 这就是我目前所拥有的 #lang racket (define ns (make-base-namespace)) (define (MyEval lis) (cond [(and ; neithe
(MyEval'(1+(3*4))
或更深层的操作,但不必执行减法或两个以上的数字和一个运算符。没那么复杂。然而,我的思想是油炸的,我希望得到一些指导。
这就是我目前所拥有的
#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。
任何指导或提示都非常感谢,我不知道我的标题有多准确,但如果不合适,请让我知道
谢谢大家! 通常一个好的计划是先编写一些单元测试。函数应为某些输出返回的示例。试着想想边界或拐角的情况。例如:
(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
,cadr
等。使用match
,它只是:
(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]))
虽然有些人不喜欢所涉及的
`
和,
s,但我更喜欢这些,而不是所有的列表。通常一个好的计划是先编写一些单元测试。函数应为某些输出返回的示例。试着想想边界或拐角的情况。例如:
(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
,cadr
等。使用match
,它只是:
(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]))
尽管有些人不喜欢所涉及的`
和,
s,但我更喜欢这些,而不是所有的列表。注意:不要使用环境的底层评估。如果您这样做,您就误解了任务。注意:不要使用您环境的基础eval
。如果你这样做,你就误解了任务。