0

version of racket/drSCHEME i use does not allow me to use internal definitions using (R5RS) language

like these two for examples below give me error messages

define: not allowed in an expression context in: (define inp (read-command))

(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)))) 

edit: for the above definition, i tried doing this as an alternative, but it just results in my stack,rev and the other command just printing out their own names...

(define repl
             (lambda()
              (display "\nUofL>")
              (let ((inp (read-command))
                    (lengtha (length com))
Greg Hendershott
  • 16,100
  • 6
  • 36
  • 53

2 Answers2

1

If you have read your R5RS bible you know it's not allowed to have local define after any other expressions. Thus:

(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) 

I'm not sure what the global variables com or w1 are for, but you can set them later. In fact you don't need define at all:

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

EDIT

Here is a rewrite for repl as well:

(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)))) 

Since you are using R5RS I used let* here too in case there are side effects. A let won't necessarily evaluate it's argument left to right though I expect PLTs implementation to do that.

I'm sure you could do without a lot of side effects here. Instead of relying on global variables you could just pass them along. It would make your program easier to test and debug.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
  • ah ok, how would i do it for the second definition though (inp, lengtha), when i did it it messed up my output results, none of my input variables went into stack, inp is for my store input – user3465992 Apr 07 '15 at 23:47
  • @user3465992 Updated. I use `let*` to ensure evaluation order since you use a lot of mutation. BTW Editing away part of your code in the question makes my answer look off. – Sylwester Apr 07 '15 at 23:59
  • ok thanks, when i tried running full code, STACK command is terminating my program, instead of printing out the current content of the stack, from the top to the bottom – user3465992 Apr 08 '15 at 00:07
  • @user3465992 Then you have a bug somewhere and all the mutation makes it difficult so you need to step through with the debugger. – Sylwester Apr 08 '15 at 01:08
1

Internal definitions can only be at the beginning of a procedure (or implicit-procedure contexts, like let bodies). In any case, they're syntactic sugar for letrec* forms, and you can always rewrite in terms of that.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435