LISP 1.5. Как lisp похож на машинный язык?

Хотелось бы, чтобы Джон Маккарти был еще жив, но...

Из Руководства программиста LISP 1.5:

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

Мне нужно больше разъяснений о том, как машинный язык может использоваться для генерации программ и как это может сделать Lisp?

3 ответа

Решение

Все, что говорит о том, что машинный код может напрямую записывать машинные инструкции в память и переходить к этим инструкциям для их выполнения; на самом деле, это основа многих векторов атак для проникновения в программное обеспечение.

Дело в том, что когда вы пишете машинный код, его легко генерировать. Но когда вы пишете на скомпилированном языке, таком как C, вы не можете просто генерировать код C во время выполнения, а затем выполнять его - если ваша программа не содержит компилятор C.

Лисп - и в наши дни многие другие языки, особенно "языки сценариев", такие как Perl, Python, Ruby, Tcl, Javascript и командные оболочки - имеют возможность выполнять код, сгенерированный во время выполнения. В Лиспе, поскольку код и данные имеют одинаковую структуру, это обычно менее трудоемко, чем в других языках, где код, который должен быть оценен, обычно является строкой, которую необходимо проанализировать. (Хотя Perl обладает способностью eval блок вместо строки, что позволяет компилятору выполнять синтаксический анализ заранее для литерального кода.)

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

LISP имел это с самого начала, так как он был первоначально интерпретирован. Вы можете изменить определение функции во время работы, и весь язык всегда был доступен во время выполнения, даже eval а также define, Когда он начал компилироваться, он не был скомпилирован, как Algol, но частично позволял интерпретировать и компилировать код для смешивания одновременно. Тот факт, что его структура кода была структурой списка, а символы являются типом данных, способствовали этому.

В последнем интервью, которое я видел с Маккарти, его спросили о том, что он думает о современных языках программирования (не о семействе LISP, а о языке семейства Algol Ruby, на который, как говорят, влияет LISP), и прежде чем ответить, он спросил, могут ли они представлять код как данные (например, структура списка). Поскольку он этого не делал, Руби все еще отстает от того, что LISP был в 60-х годах, по его мнению.

В семействе Algol появляется много новых языков программирования, а некоторые из наиболее многообещающих, таких как Perl6 и Nemerle, становятся ближе к возможностям, которые LISP имел в 60-х годах.

Программы машинного языка могут заполнять области памяти произвольными байтами. Тогда они могут просто jump к началу такого региона, который, таким образом, будет выполнен сразу же.

Программы на языке Lisp могут легко создавать произвольные S-выражения в памяти, используя cons, Тогда они могут просто позвонить eval по этим S-выражениям оценивать (интерпретировать) их.

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

Другие вопросы по тегам