2016-12-29 8 views
2

Я новичок в Схеме; Я пишу программу, которая рекурсивно определяет умножение в терминах многократного добавления:Scheme - Unbound variable: unquote

(define multiply 
    (lambda (a b) 
    (if (= b 0) 
     0 
     (+ a (multiply(a, (- b 1))))))) 

Однако, когда я пытаюсь запустить программу я получаю сообщение об ошибке:

;Unbound variable: unquote 

Что такое сообщение об ошибке ссылаясь на, и как я могу его исправить?

ответ

5

Поскольку вы знакомы с языком Алгол семьи (Python) Я могу сказать вам LISP семья имеет другой синтаксис:

fun(a, b, c) 

написано так:

(fun a b c) 

Таким образом, источник ваша ошибка заключается в том, что запятая и скобки интерпретируются на разных языках.

Какое сообщение об ошибке относится к? В семействе lisp вы можете иметь код как данные, добавляя символы, которые вместо букв кода. Таким образом, '(fun a b c) становится (fun a b c) в качестве структуры данных после оценки, так как у вас есть ' перед этим, и он работает, как если бы вы использовали code(a,b,c) в python и окружили его котировками вроде 'code(a,b,c)'. Python оценил бы это как строку, а не код правильно? Хорошо lisp языки делают то же самое с литеральными структурами данных. Есть еще 2 дополнительных. quasiquote` и unquote,. Знакомый, не так ли? Ну как ассимиляция нормальная quote похожа на одинарные кавычки, где строка точно буквальна, а quasiquote - это как двойные кавычки, а unquote - для интерполяции для кода, так что то, что остается в структуре, является результатом этих выражений. Вот пример:

`(a b ,(+ 3 4))) 
; ==> (a b 7) 

Сейчас в LISP языках читатель обычно преобразует это в время чтения, так что код, который получает интерпретированы никогда не увидеть '`, или ,. стандартная схема не говорит, что он должен быть назван так это реализация определена, однако большинство языков используют эти:

''`(a b ,(+ 3 4)) 
; ==> (quote (quasiquote (a b (unquote (+ 3 4))))) 

Только внешняя цитата оценивается так как в этом случае другие цитаты, которые вы видите в результате это данные и не является частью кода.Реализация свободна, чтобы показать короткую форму при представлении структуры данных таким образом, чтобы:

'(quote (unquote quote)) 
; ==> ',quote 
; ==> (quote (unquote quote)) 

Это фактически то же самое значение, а то, как они показывают, что это изменение, если вы должны были принять car этого было бы представить символ quote, так как это действительно вторая структура, которая является реальной стоимостью.

В своем коде выражение (a, (- b 1)) читается как (a (unqote (- b 1))) и после успешного вычитания функция unquote должна быть применена, то функция a должна быть применена к его результат. Ни один из них не будет работать, но поскольку аргументы должны быть оценены перед приложением, порядок будет установлен таким образом, что Scheme будет сначала жаловаться на unquote, а затем a, если вы удалите запятую.

+0

Как вы закончили знакомство с алгол-иш-языками? –

+0

@ScottHunter OP имеет два вопроса python и 'multiply (a, ...)' выглядит очень знакомым. – Sylwester

+0

Спасибо, этот ответ был очень информативным. – skeletonsaurus

1

Схема использует пробелы для разделения аргументов, а не запятых (оператор unquote, о котором говорится в сообщении об ошибке).

+1

На всякий случай это было не очевидно: удалите запятую из вашей программы. –

3

В дополнение к полностью правильному ответу выше: когда вы учитесь программировать, одним из наиболее важных навыков является изучение того, как изолировать ваши ошибки, удаляя части вашей программы, которые можно удалить, не изменяя ошибку, чтобы получить наименьшую возможную программу, которая показывает ошибку. Это сэкономит вам много времени в долгосрочной перспективе!