#scheme
#схема
Вопрос:
Я использую let
для создания временной переменной, а затем использую эту временную переменную в следующем операторе. Однако DrScheme пожаловался,
let: bad syntax (not an identifier and expression for a binding) in: temp
Это мой фрагмент кода:
(define (case-one-helper str)
(let (temp (substring str ( 3 (string-contains str "my"))))
(substring temp (string-contains temp " "))))
Интересно, должно ли значение переменной, созданной let
, быть известно во время компиляции?
Правка, которую я только что выяснил, отсутствует ()
.
Спасибо,
Ответ №1:
Хотя это не совсем проблема, с которой вы столкнулись, но отступление, основанное на вашем вопросе о последовательности вычисления аргументов, let
также является «синтаксическим сахаром» для лямбда-выражения, за которым следуют его аргументы, которые сначала вычисляются, а затем передаются в лямбда-выражение, которое затем вычисляется.
Например:
(let ((a (list 1 2 3))
(b (list 4 5 6)))
(cons a b))
это то же самое, что:
((lambda (list-a list-b) (cons list-a list-b)) (list 1 2 3) (list 4 5 6))
Итак, если вы когда-нибудь задумывались о последовательности вычислений, аргументы полностью вычисляются до вычисления тела (и один аргумент не может ссылаться на аргумент, предшествующий ему … используйте let*
для чего-то, что требует подобных привязок).
Комментарии:
1. Смотрите раздел «Правда о Let» в people.eecs.berkeley.edu / ~bh/ssch9/lambda.html
2. Интересное чтение … просматривая свой ответ здесь, я бы сказал и да, и нет, в том смысле, что
let
может быть реализовано как лямбда-выражение с вызовом этого лямбда-выражения, но это нечто большее. Если вы напишете интерпретатор scheme с нуля, как в SICP, вы увидите, чтоlet
с ним связано много бухгалтерского учета, поскольку вы называете результат выражения.
Ответ №2:
Вам нужно поместить другой набор круглых скобок вокруг ваших let
объявлений:
(define (case-one-helper str)
(let ((temp (substring str ( 3 (string-contains str "my")))))
(substring temp (string-contains temp " "))))