Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lisp DrRacket中的简单嵌套求值_Lisp_Scheme_Racket_R5rs - Fatal编程技术网

Lisp DrRacket中的简单嵌套求值

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”,它允许你做简单的嵌套加法和乘法。 例如,该程序可以执行
(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
。如果你这样做,你就误解了任务。