1

Here's a function that asks a number and returns the value if its type is indeed a number and else executes the function again:

(defun ask-number ()
  (format t "Please enter a number.~%")
  (let ((val (read)))
    (if (numberp val)
        val
        (ask-number))))

I understand that after the value is read, it is labelled as val and the whole ((val (read))) is an argument of let. What I don't understand is, why the if-statement is nested within let. I would have assumed that the program should be something like this:

(defun ask-number ()
  (format t "Please enter a number.~%")
  (let ((val (read))))
  (if (numberp val)
      val
      (ask-number)))

which leads to an error. I am not sure why this happens.

1 Answer 1

4

The reason the if is inside the let is that the val you've created with the let is only valid within the let; once you exit the let, val doesn't exist any more.

let is syntactic sugar for creating and instantly calling a lambda expression, so your let expression is basically the same as:

((lambda (val)
   (if (numberp val)
       val
       (ask-number)))
 (read))
Sign up to request clarification or add additional context in comments.

1 Comment

As an analogy with a C program, you couldn't do void foo(int x) { x = 3; } printf("%d", x);" The variable is no longer in scope. let` introduces scope, just like a function definition does. You could do this, though: (let ((val nil)) (set! val (read)) (if (numberp val) ...)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.