Я использую следующий код модифицированный из Solving Infix Arithmatic in LISP с определением атома из Check if an argument is a list or an atom иметь инфиксную арифметический решатель:Eval не работает в Ракетке
(define atom? (or/c number? symbol? boolean? string?))
(define (solve expression)
(define templist '())
(println expression)
(if (atom? expression)
expression
(begin
(set! templist (list (second expression)
(solve (first expression))
(solve (third expression)) ))
(println templist)
(eval templist))))
(solve '(3 + 2))
Выход выглядит следующим образом:
'(3 + 2)
3
2
'(+ 3 2)
+: unbound identifier;
also, no #%app syntax transformer is bound in: +
Следовательно , templist создается справа (+ 3 2), но на уровне eval есть ошибка. Почему «+» рассматривается как «несвязанный идентификатор»? Функция Eval иначе работает хорошо в командной строке в DrRacket:
> (eval '(+ 3 2))
5
Где проблема и как она может быть решена? Благодарю.
Я использовал набор! и templist только для отладки кода, в противном случае требуется только «eval (list (второе выражение) ...». Почему он установлен на языке, если он вообще не используется? Спасибо за хорошо объясненный ответ. – rnso
@ rnso Возможно, но ваш 'set!' вообще ничего не делает. Даже если ваш исходный код вы могли бы использовать только локальную привязку, я бы сказал, что пока вы не будете очень комфортно с Scheme/Racket, * никогда не используйте 'set!', даже не для отладки. Представьте, что этого не существует. –
@rnso 'set!' полезно для реализации некоторых низкоуровневых конструкций в Scheme, но это не то, что полезно в большинстве пользовательских кодов. Обычно вы можете избежать мутации вообще, и если вы действительно хотите что-то изменить, вы можете использовать поля вместо этого (но я бы тоже избежал их, если вы на 100% не уверены, что они вам нужны). –