Roy
Roy

Reputation: 783

Scheme problem with 'let'

I am trying to write a scheme program to read in 2 numbers and display their addition, but am having problem with the 'let' expression

(define (add-two)
  (let* ((first ((display "Enter first number:")
                (read)))
        (second ((display "Enter second number:")
                 (read))))
        (sum (+ first second))
        )
    (display "total is " sum)
    )

After reading the first number, the program crashes...and points to the let expression, the compiler reports

'procedure application: expected procedure, given: #; arguments were: 4'

I'm not sure how to fix this..What do you think is wrong?

thanks in adv!

Upvotes: 1

Views: 235

Answers (2)

Greg Hewgill
Greg Hewgill

Reputation: 992857

It looks like you have a mismatched set of parentheses. Try:

(define (add-two) 
  (let* ((first (begin
                  (display "Enter first number:") 
                  (read))) 
         (second (begin
                   (display "Enter second number:") 
                   (read)))
         (sum (+ first second)))
    (display "total is " sum)))

In the let* form, the first parentheses group the new bindings together, then the rest of them (just display in this example) is the body. In general:

(let* ((a1 x1) (a2 x2) ...) body ...)

Upvotes: 3

ffriend
ffriend

Reputation: 28492

The problem is not in let, but in procedure application. Look at your first let expression:

(first ((display "Enter first number:")
                 (read)))

You try to bind to the symbol first result of expression ((display "Enter first number:") (read)). I understand you expect this will do 2 actions: display message and read input, but it will not. First expression (i.e. (display "Enter first number: ")) will be evaluated to void#. Second expression will give an input. After 2 arguments will be evaluated, Scheme will see an expression (void# 4). But this a procedure application! And Scheme tells you about it with your error message.

To avoid this you can do 2 things: show message before let expression:

(define (add-two) 
   (display "Enter first number:")
   (let (first (read))
      (display "Enter second number:")
      (let second (read))
         ...

Or use begin procedure to evaluate expressions sequentially:

(define (add-two)
   (let* ((first (begin (display "Enter first number:")
                        (read)))
          (second (begin (display "Enter second number:")
                         (read))))
          ...

Upvotes: 3

Related Questions