2014-10-03 1 views
1

Вот функция, которая задает число и возвращает значение, если его тип действительно число и еще раз выполняет функцию:Сложность понимания вложенных выражений в Лисп

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

Я понимаю, что после того, как значение считывается, он обозначается как val, а целое ((val (read))) является аргументом let. Я не понимаю, почему if-statement вложен в let. Я предположил бы, что программа должна быть примерно такой:

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

, который приводит к ошибке. Я не знаю, почему это происходит.

ответ

4

Причина if находится внутри let, что val вы создали с let действует только в пределах let; как только вы выходите из let, val больше не существует.

let является синтаксический сахар для создания и мгновенно вызывая выражение lambda, поэтому ваше выражение let в основном так же, как:

((lambda (val) 
    (if (numberp val) 
     val 
     (ask-number))) 
(read)) 
+3

По аналогии с программой C, вы не могли бы сделать 'недействительным Foo (int x) {x = 3; } printf ("% d", x); "Эта переменная больше не находится в области видимости.' let' вводит область видимости, как это делает определение функции. Вы можете * сделать это, хотя: '(let ((val nil)) (set! val (read)) (если (числоp val) ...)) '. –