#lisp #sicp
#lisp #sicp
Вопрос:
Я прочитал главу 4 SICP и только что обнаружил, что в первом разделе перечислены наиболее важные функции для реализации evaluator, eval
и apply
я понимаю, что это eval
очень важно, но почему apply
это так важно? Для некоторых языков совершенно не существует apply
такого, как в Javascript.
Редактировать: Извините, что я ошибаюсь насчет отсутствия apply в Javascript, пожалуйста, просто игнорируйте это.
Комментарии:
1. Я уверен, что в JavaScript есть какой-то эквивалент 🙂
2. В JavaScript есть
apply
, не так ли? Я не эксперт в JS, но что developer.mozilla.org/en/JavaScript/Reference/Global_Objects /…
Ответ №1:
Функция eval / apply в SICP (и в других местах) заключается в разделении двух основных частей evaluator. Первая часть, та, которая eval
выполняется, имеет дело с синтаксическим переводом кода в его значение — но она почти ничего не делает, кроме диспетчеризации по типу выражения. Как вы можете видеть в книге, существуют различные eval-foo
s для различных «специальных форм», поскольку каждая из них имеет свое собственное уникальное правило оценки.
Теперь наиболее важной формой, с которой должен иметь дело оценщик, является применение функции. На самом деле, так важно, чтобы для этой формы не было ключевого слова (иначе вы бы увидели apply
или что-то еще, замусоривающее схему / код lisp). Вместо этого, если форма начинается с чего-то, что не является известной специальной формой (а в реальных реализациях — не известным макросом), тогда оценщик принимает это за приложение-функцию. На этом этапе, чтобы оценить вызов функции, вам нужно оценить саму функцию (первую форму) и все ее аргументы, а затем вам нужно применить первое значение поверх остальных. Важным моментом просветления здесь является осознание того, что между этим eval
и apply
— первое по сути имеет дело с синтаксисом, а второе — с значениями.
В качестве дополнительного замечания, несколько человек перепутали это со встроенной apply
функцией, которая есть в Scheme и реализации Lisp. Почему эта функция должна быть в языке, совершенно не связано с точкой SICP (грубо говоря, она предоставляет функциональность, которую вы не можете реализовать без нее, это форма отражения реализации в языке). Я даже не думаю, что SICP evaluators даже делают apply
доступным интерпретируемый язык. Если вы ищете больше информации, выполнение этого (использование SICP meta circular evaluator и добавление apply
к интерпретируемому языку) будет хорошим упражнением в размышлении.
Ответ №2:
Это то, как вы запускаете функцию для выражения, иначе говоря, «применяете» функцию к выражению.
Обратите внимание на приведенный здесь код:
http://mitpress.mit.edu/sicp/code/ch4-mceval.scm (мертвая ссылка)
Ответ №3:
Apply оценивает вызов функции. Он принимает функцию и список аргументов: (apply fn args)
. Если у вас есть язык, который поддерживает вызовы функций, у вас, вероятно, будет функция apply в вашем интерпретаторе. Разница между Scheme и Javascript заключается в том, что Scheme предоставляет эту функцию не только интерпретатору, но и интерпретируемой программе.
Комментарии:
1. В этом контексте «оценивать» имеет особое значение, поэтому это объяснение не сильно помогает. Более того, вы говорите о
apply
функции, и то, как это связано с приложением, о котором говорится в книге, является более тонким вопросом.2. Это тонкая проблема, но мне кажется, что OP спрашивает именно об этой проблеме, потому что он упоминает, что в JS нет функции apply. Функция eval выполняет анализ случая для типа выражений, а затем каждый случай решает, как вычислить этот тип выражения. Вычислитель в SICP просто случайно преобразует код для вычисления вызова функции в другую функцию с именем apply. Это не является существенной особенностью evaluator: с тем же успехом вы могли бы встроить функцию apply в eval, хотя это может сделать код менее понятным.
3. Разница между функцией apply внутри интерпретатора и функцией apply на самом деле невелика. Функция apply может быть доступна непосредственно пользовательским программам, поместив ее в список примитивных процедур.
4. Да, смотрите мой ответ. Повторите путаницу в OPs по поводу
apply
Я согласен, что это похоже на ту же путаницу, но идти с этим, а не объяснять, не сильно поможет…