Подтвердить что ты не робот

Может ли скомпилированный язык быть homoiconic?

По определению слово homoiconic означает:

Такое же представление кода и данных

В LISP это означает, что вы можете иметь кавычек и оценивать его, поэтому (car list) будет функцией и (cdr list) аргументами. Это может произойти при компиляции или во время выполнения, однако для этого требуется интерпретатор.

Возможно ли, что скомпилированные языки без интерпретатора времени компиляции могут быть гомоиконимичными? Или понятие гомоконичности ограничено устными переводчиками?

4b9b3361

Ответ 1

"Homoiconic" - своего рода неопределенная конструкция. 'code is data' немного понятнее.

В любом случае первое предложение в Wikipedia для Homoiconic не так уж плохо. В нем говорится, что язык должен иметь исходное представление, используя его структуры данных. Если мы забываем "строки" как исходное представление (что тривиально и не полезно использовать полезную концепцию "homoiconic" ), то Lisp имеет списки, символы, числа, строки и т.д., Которые используются для представления исходного кода. Интерфейс функции EVAL определяет, какое именно исходное представление работает над языком. В этом случае Lisp это не строка. EVAL ожидает, что обычное разнообразие структур данных и правила оценки Lisp определяют, что строка оценивает себя (и, следовательно, не будет интерпретироваться как выражение программы, а просто строковые данные). Число также оценивает себя. Список (sin 3.0) - это список символов и числа. Правила оценки говорят, что этот список с символом, обозначающим функцию как первый объект, будет оцениваться как приложение функции. Для данных, специальных операторов, макроприложений и функциональных приложений существует несколько правил оценки. Что это.

Чтобы было ясно: в Lisp функция EVAL определена над структурами данных Lisp. Он ожидает структуру данных, оценивает ее в соответствии с ее правилами оценки и возвращает результат - снова используя свои структуры данных.

Это соответствует определению homoiconic: исходный код имеет собственное представление с использованием типов данных Lisp.

Теперь интересная часть: не имеет значения, как реализован EVAL. Все, что имеет значение, это то, что он принимает исходный код с использованием структур данных Lisp, что он выполняет код и возвращает результат.

Итак, , вполне законно, что EVAL использует компилятор.

(EVAL code)  =  (run (compile-expression code))

Как работает несколько Lisp, у некоторых даже нет интерпретатора.

Итак, "Homoiconic" говорит, что код SOURCE имеет представление данных. Он НЕ говорит, что во время выполнения этот исходный код должен быть интерпретирован или что выполнение основано на этом исходном коде.

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

Lisp также предоставляет примитивную функцию READ, которая преобразует внешнее представление (S-выражения) данных во внутреннее представление данных (Lisp данных). Таким образом, он также может использоваться для преобразования внешнего представления исходного кода во внутреннее представление исходного кода. Lisp не использует специальный синтаксический анализатор для исходного кода - поскольку код является данным, есть только READ.

Ответ 2

да. lisp может быть скомпилирован в нативный двоичный файл

Ответ 3

Мне кажется странным вопрос:

Во-первых, гомоиконная часть представляет собой представленный интерфейс программисту. Точка языков состоит в том, что они абстрагируют функциональность более низкого уровня, которая сохраняет ту же семантику, что и представление более высокого уровня (хотя и другое средство).

точка машинного кода dsm - хорошая точка, но при условии:

  • Представленный синтаксис и семантика являются гомомиксовыми
  • Перевод в форму нижнего уровня (машинный код или интерпретируемый или иным образом) не удаляет исходную семантику, а затем

Почему здесь имеет значение реализация более низкого уровня?

также:

скомпилированные языки без интерпретатора времени компиляции

Без какой-либо программы, интерпретирующей его, требуется, чтобы он был родным для ЦП, поэтому родной язык ЦП должен был быть homoiconic (или виртуальной машиной, исполняющей код).

Языки без интерпретации времени компиляции... были бы довольно ограниченными... поскольку они не были бы компилироваться вообще.

Но я не эксперт, и, возможно, не хватает смысла.

Ответ 4

В самой буквальной форме C является гомоиконической. Вы можете получить доступ к представлению функции с помощью &functionName и выполнить данные с помощью somePtrCastToFnPtr(SomeArgs). Однако это на уровне машинного кода и без какой-либо поддержки библиотеки вам будет очень сложно работать. Какой-то встраиваемый компилятор (я, кажется, помню, что LLVM может это сделать) сделает его более практичным.

Ответ 5

Lisp обычно скомпилирован. Были реализации с JIT-компиляторами вместо интерпретаторов.

Следовательно, нет необходимости иметь интерпретатор (в смысле "не компилятор" ) для языков данных кода.

Ответ 6

Машинный код сам по себе гомоиконный, поэтому да.

Данные или инструкции - это всего лишь семантика (и, возможно, сегмент памяти, в котором они лежат).

Ответ 7

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

У интерпретаторов (и виртуальных машин) нет этой проблемы, так как они могут обрабатывать всю программу как данные, причем единственным "кодом" является интерпретатор.

Ответ 8

Да; вам просто нужно вставить копию компилятора в язык выполнения. Chez Scheme является одним из многих прекрасных компиляторов, которые делают именно это.

Ответ 9

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

Вот почему некоторые реализации Lisp могут не иметь intepreters. Функция EVAL может скомпилировать код и затем перейти к нему. EVAL и COMPILE не должны иметь различные режимы работы. (Clozure, Corman Lisp, SBCL являются примерами "только для компилятора" Lisps.)

Часть данных в начале является ключом к тому, что язык является гомоиконным, а не то, выполняется ли оптимизация выполнения кода путем компиляции. "Код - это данные" означает "исходный код - это данные", а не "исполняемый код - это данные". (Конечно, исполняемый код - это данные, а под данными мы подразумеваем крайне предпочтительное представление кода, который мы хотим манипулировать.)

Ответ 10

Языки, построенные поверх VM (.net clr, jre ect), могут использовать передовые технологии, которые позволяют генерировать код генерации мух. Один из них - ткачество ИЛ. Хотя, это не так ясно, как eval из ECMAScript/ Lisp/Scheme, но это может в какой-то мере подражать такому поведению.

Для примера проверьте Castle DynamicProxy и для более интерактивного примера проверьте LinqPAD, F # Interactive, Scala interactive.