что означает «пусть *» (пусть звездочка) в elisp

12

Я использовал letраньше, но никогда не использовал let* то, что let*(пусть звездочка) означает в elisp?

К сожалению, это было трудно гуглить из-за звездочки.

Американский ниндзя-воин
источник

Ответы:

17

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

Для let(без звездочки) нельзя предположить, что ни одна из привязок происходит раньше, чем любая другая (переменные в принципе могут быть связаны параллельно).

Таким образом, (let ((a 42) (b a))...b)может возникнуть ошибка, потому что он пытается привязать bк значению a, и a(по крайней мере, конкретное, aчто связано в этом let) нельзя предполагать, что он был привязан к значению.

[Если какой -либо другой (например , глобальная) переменная a связана со значением, например, 5, то это letвыражение будет связывать его (локальный) , aчтобы 42и привязать bк значению глобальной a, то есть 5.]

Но (let* ((a 42) (b a))...b)возвращает, 42потому что aпривязывается к, 42 а затем b привязывается к значению a.

См. Руководство Elisp, узел Локальные переменные .


Обновление от напоминания @ DoMiNeLa10 в комментарии:

В дополнение к руководству вы также можете использовать команды справки . Из всех различных способов «спросить Emacs» они являются одними из первых и наиболее полезными.

И для C-h f let*говорит нам, кратко:Each VALUEFORM can refer to the symbols already bound by this VARLIST.


Хотя нет ничего плохого в том, чтобы спрашивать здесь, вы бы сделали себе одолжение, если бы задавали Emacs такие вопросы. Просто используйте, C-h iчтобы открыть информационный браузер руководств, выберите Elispруководство и используйте i let*для поиска let*в указателе (с завершением). Это приведет вас прямо к узлу, который покрывает это.

(И руководство обычно охватывает вещи лучше, чем будет сделано здесь, поскольку тысячи участников приложили много времени и усилий, чтобы сделать это правильно: правильно и полно.)


Вы также можете искать на этом сайте вопросы и ответы, которые используют тег let-binding: Просто [let-binding]введите в поле поиска. (Я сделаю это сейчас, чтобы проверить, не является ли этот вопрос дубликатом ...)

Нарисовалась
источник
в приведенном выше примере есть опечатка, когда bравно 5, потому что он связан с глобальным a. Это следует читать letвместоlet*
Цзюэ
@jue: верно; Спасибо.
Дрю
Также можно спросить о функциях с F1 f.
DoMiNeLa10
@ DoMiNeLa10: Действительно; хорошая точка зрения. Поскольку комментарии могут быть удалены в любое время, я обновил ответ, чтобы упомянуть об этом. Спасибо.
Дрю
5

let*это как рекурсивное letзначение:

(let* ((var1 VAL1)
       (var2 VAL2))
  ...)

как

(let ((var1 VAL1))
  (let ((var2 VAL2))
    ...))

Таким образом, использование заглавных букв для VAL1и VAL2указывает, что они также могут быть выражениями.

Рекурсивное letсвязывание имеет последствия, если VAL2зависит от var1. Эффект уже описан в ответе Дрю .

Тобиас
источник