Вы правы (почти): если вы реализуете чисто функциональное подмножество Scheme (т.е. не set!
, set-car!
, set-cdr!
), тогда любое выражение, кроме последнего в let
, будет иметь их возвращаемое значение отбрасывается, и, поскольку вы гарантированно не будете иметь побочных эффектов, не стоит молча игнорировать их.
Однако, есть один маленький случай, который вам нужно рассмотреть, и это когда предшествующие выражения define
s:
(let ((x 3))
(define y 4)
(+ x y))
Это и законно, и функционально. Однако есть и хорошие новости - внутри блока (например, let
) вы должны иметь все свои define
наверху. То есть, это не считается законной схемой:
(let ((x 3))
(+ 2 3)
(define y 4)
(+ x y))
Это означает, что при оценке блока все, что вам нужно сделать, это отсканировать верхнюю часть на define
s и обернуть их в эквивалентное выражение letrec
, а затем продолжить игнорировать все, кроме последнего выражения (которое вы бы сделали затем вернитесь).
edit: antti.huima дает отличное замечание о call / cc. Если вы собираетесь включить продолжения в свою реализацию, вы действительно не сможете сделать много предположений о том, когда что-то будет оцениваться.