Как `let` работает в Scheme?

#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 " "))))