Search code examples
schemepostfix-notation

Scheme with postfix


Does anyone can help me to deal with the problem? I tried for many times, but it still has the error information. This is my code(scheme) Thanks!!!

(define (postfix l s)
  (cond(
        ((null? l)(car s))
        (else (postfix (cdr l) update-s((car s)))))))
(define (update-s x s)
  (cond(((number? x) (cons x s))
        (else (cons (eval '(x (car s) (cadr s))) (scheme-report-environment 5) (cdr(cdr s)))))))

And this is the error inform:

else: not allowed as an expression in: (else (postfix (cdr l) update-s ((car s) s)))

Solution

  • Next time, don't forget to add a description of your problem (what should this code do?), expected inputs and outputs, and a version of Scheme you use.

    You should also use better names for variables (no l, s, x) and describe their meaning and expected type in your question.

    If I understand correctly, you were trying to create a calculator which uses reverse Polish/ postfix notation, where:

    • l is a list of numbers or symbols
    • s is a stack with results, represented as a list of numbers
    • x can be a number or symbol representing some function

    From (scheme-report-environment 5) I guess you use r5rs Scheme.

    Now some of your errors:

    • you should define update-s before function postfix
    • your cond has some additional parentheses
    • if cond has only two branches, you should use if instead
    • this part (postfix (cdr l) update-s((car s))) should be (postfix (cdr l) (update-s (car l) s)
    • (cdr(cdr s)) should be (cddr s)
    • as for eval, I understand why it's here, you were trying to get a function from the symbol, but you should be always careful, as it can also evaluate code provided by user. Consider this example: (postfix '(1 2 (begin (write "foo") +)) '()). Maybe it could be better to don't expect this input: '(1 2 +), but this: (list 1 2 +) and get rid of eval.

    The whole code:

    (define (update-s object stack)
      (if (number? object)
          (cons object stack)
          (cons ((eval object (scheme-report-environment 5))
                 (car stack) (cadr stack))
                (cddr stack))))
    
    (define (postfix lst stack)
      (if (null? lst)
          (car stack)
          (postfix (cdr lst)
                   (update-s (car lst) stack))))
    

    Example:

    > (postfix '(1 2 +) '())
    3
    

    Solution without eval with different input:

    (define (update-s object stack)
      (if (number? object)
          (cons object stack)
          (cons (object (car stack) (cadr stack))
                (cddr stack))))
    
    (define (postfix lst stack)
      (if (null? lst)
          (car stack)
          (postfix (cdr lst)
                   (update-s (car lst) stack))))
    

    Example:

    > (postfix (list 1 2 +) '())
    3