0

我使用的球拍/drSCHEME 版本不允许我使用(R5RS)语言使用内部定义

像这两个下面的例子给我错误信息

定义:不允许在表达式上下文中:(定义 inp(读取命令))

(define repl 
 (lambda() 
 (display "\nUofL>") 
 (define inp (read-command)) 
 (define lengtha (length com)) 
      (cond 
        ((equal? inp "CLEAR")(set! lista '())(repl)) 
        ((equal? inp "REV")(set! lista (cdr lista))(set! lista (rev lista))(repl)) 
        ((equal? inp "STACK")(set! lista (cdr lista))(display lista)(repl)) 
        ((equal? inp "SWAP")(set! lista (cdr lista))(set! lista (append (list (cadr lista)) (list (car lista)) (cddr lista)))(repl)) 
        ((equal? (car lista) "EXIT") (display "Bye.")(set! lista (cdr lista))) 
        ((equal? inp "DROP")(set! lista (cddr lista))(repl)) 
        ((equal? (car lista) "POP") 
         (set! lista (cdr lista)) 
         (cond 
           ((null? lista)(display "Empty Stack")(repl)) 
           ((string->number (car lista))(set! pop (car lista))(set! lista (cdr lista))(repl) ) 
           ((search (car lista) sym symval) 
            (cond 
              ((null? (cdr lista)) (set! lista (cdr lista)) 
              (display "Empty Stack") (repl)) 
              (else 
               (addsym (car lista) (cadr lista)) 
               (set! pop (cadr lista)) 
               (set! lista (cddr lista)) 
               (repl)))) 

           (else 
            (set! lista (cdr lista)) 
            (display "Var not declared")(repl)))) 

        ((equal? inp "SAVE") 
         (set! lista (cdr lista)) 
         (cond 
           ((equal? pop "")(display "Can't SAVE null")) 
           (else  (set! lista (append (list pop) lista))(set! pop ""))) 
         (repl)) 
        ((equal? inp "DUP")(set! lista (cdr lista))(set! lista (append (list (car lista)) lista))(repl)) 
        ((equal? (op? (car lista)) ".")(set! lista (cdr lista)) 
        (cond 
          ((equal? lengtha 1)(if (null? lista) (display "Empty Stack") (display (car lista)))(repl)) 
          (else (displayn (- lengtha 1))(repl)))) 
        ((string->number (car lista)) 
         (cond 
           ((null? (cdr lista))(repl)) 
           ((op? (cadr lista))(repl)) 
           (else (set! lista (cleanup-eval lista))(repl)))) 
        ((equal? (car lista) "define") 
         (set! lista (cdr lista)) 
         (set! sym (append (list (car lista)) sym)) 
         (set! lista (cdr lista)) 
         (cond 
           ((string->number (car lista)) 
            (set! symval (append (list (string->number (car lista))) symval))) 
           (else 
            (set! symval (append (list (car lista)) symval)))) 


         (set! lista (cdr lista)) 
         (repl) ) 
        (else 
         (cond 
           ((search (car lista) sym symval)(set! lista (append (list (cadr res)) (cdr lista))) 
           (if (number? (car lista)) (set! lista (append (list(number->string (car lista))))))) 
           (else 
            (display (car lista))(set! lista (cdr lista)))))) 
            (repl)))) 

编辑:对于上述定义,我尝试这样做作为替代方案,但它只会导致我的堆栈,rev 和另一个命令只是打印出他们自己的名字......

(define repl
             (lambda()
              (display "\nUofL>")
              (let ((inp (read-command))
                    (lengtha (length com))
4

2 回答 2

1

define如果您已阅读 R5RS 圣经,您就会知道在任何其他表达式之后不允许使用 local 。因此:

(define (read-command) 
  (set! com '( '() ))             ;; illegal needs to go after ret1 define
  (set! wl (read-as-list))        ;; illegal needs to go after ret1 define
  (define ret1 (list->string wl))
  (commRead) 
  ret1) 

我不确定全局变量comw1用于什么,但您可以稍后设置它们。事实上你根本不需要define

(define (read-command) 
  (let* ((tmp-w1 (read-as-list))
         (ret1 (list->string tmp-wl)))
    (set! com '( '() ))
    (set! wl tmp-w1)
    (commRead) 
    ret1))

编辑

这里也是一个重写repl

(define (repl) 
  (display "\nUofL>") 
  (let* ((inp (read-command)) 
         (lengtha (length com))) 
    (cond 
      ((equal? inp "CLEAR")(set! lista '())(repl)) 
      ((equal? inp "REV")(set! lista (cdr lista))(set! lista (rev lista))(repl)) 
      ((equal? inp "STACK")(set! lista (cdr lista))(display lista)(repl)) 
      ((equal? inp "SWAP")(set! lista (cdr lista))(set! lista (append (list (cadr lista)) (list (car lista)) (cddr lista)))(repl)) 
      ((equal? (car lista) "EXIT") (display "Bye.")(set! lista (cdr lista))) 
      ((equal? inp "DROP")(set! lista (cddr lista))(repl)) 
      ((equal? (car lista) "POP") 
       (set! lista (cdr lista)) 
       (cond 
         ((null? lista)(display "Empty Stack")(repl)) 
         ((string->number (car lista))(set! pop (car lista))(set! lista (cdr lista))(repl) ) 
         ((search (car lista) sym symval) 
          (cond 
            ((null? (cdr lista)) (set! lista (cdr lista)) 
                                 (display "Empty Stack") (repl)) 
            (else 
             (addsym (car lista) (cadr lista)) 
             (set! pop (cadr lista)) 
             (set! lista (cddr lista)) 
             (repl)))) 

         (else 
          (set! lista (cdr lista)) 
          (display "Var not declared")(repl)))) 

      ((equal? inp "SAVE") 
       (set! lista (cdr lista)) 
       (cond 
         ((equal? pop "")(display "Can't SAVE null")) 
         (else  (set! lista (append (list pop) lista))(set! pop ""))) 
       (repl)) 
      ((equal? inp "DUP")(set! lista (cdr lista))(set! lista (append (list (car lista)) lista))(repl)) 
      ((equal? (op? (car lista)) ".")(set! lista (cdr lista)) 
                                     (cond 
                                       ((equal? lengtha 1)(if (null? lista) (display "Empty Stack") (display (car lista)))(repl)) 
                                       (else (displayn (- lengtha 1))(repl)))) 
      ((string->number (car lista)) 
       (cond 
         ((null? (cdr lista))(repl)) 
         ((op? (cadr lista))(repl)) 
         (else (set! lista (cleanup-eval lista))(repl)))) 
      ((equal? (car lista) "define") 
       (set! lista (cdr lista)) 
       (set! sym (append (list (car lista)) sym)) 
       (set! lista (cdr lista)) 
       (cond 
         ((string->number (car lista)) 
          (set! symval (append (list (string->number (car lista))) symval))) 
         (else 
          (set! symval (append (list (car lista)) symval)))) 

由于您使用的是 R5RS,因此我let*也在这里使用,以防有副作用。Alet不一定会从左到右评估它的论点,尽管我希望 PLT 实现能够做到这一点。

我相信你可以在这里没有很多副作用。您可以直接传递它们,而不是依赖全局变量。这将使您的程序更容易测试和调试。

于 2015-04-07T23:38:22.163 回答
1

内部定义只能在过程的开头(或隐式过程上下文,如let主体)。在任何情况下,它们都是letrec*表单的语法糖,你总是可以根据它重写。

于 2015-04-07T23:39:01.190 回答