Назначение синтаксиса Lisp для моделирования AST

Насколько я знаю, синтаксис Lisp представляет собой AST, но в формате высокого уровня, чтобы человек мог легко читать и изменять его, в то же время облегчая машине обработку исходного кода.

По этой причине в Лиспе говорится, что код — это данные, а данные — это код, поскольку код (s-epxression) — это, по сути, просто AST. Мы можем подключить больше AST (это наши данные, которые являются просто кодом lisp) в другие AST (код lisp) или независимо, чтобы расширить его функциональность и манипулировать им на лету (время выполнения) без необходимости перекомпилировать всю ОС для интеграции новых. код. В других языках мы должны перекомпилировать, чтобы превратить исходный код на человеческом языке в действительный AST, прежде чем он будет скомпилирован в код.

Является ли это причиной того, что синтаксис Лиспа должен быть разработан таким, какой он есть (представляет собой AST, но удобочитаемый для человека, чтобы удовлетворить как человека, так и машину) в первую очередь? Обеспечить более надежную (на лету — во время выполнения) и более простую (без перекомпиляции, более быструю) связь между человеком и машиной?

Я слышал, что машина Лиспа имеет только одно адресное пространство, в котором хранятся все данные. В операционной системе, такой как Linux, у программистов есть только виртуальное адресное пространство, и они притворяются, что это реальное физическое адресное пространство, и могут делать все, что захотят. Данные и код в Linux являются отдельными областями, потому что фактически данные — это данные, а данные — это код. В обычной ОС, написанной на C (или C-подобном языке), было бы очень грязно, если бы мы работали только с одним адресным пространством для всей системы, и смешивание данных с кодом было бы очень грязным.

В Lisp Machine, поскольку код — это данные, а данные — это код, является ли причиной того, что здесь используется только одно адресное пространство (без виртуального уровня)? Поскольку у нас есть GC и нет указателя, должно ли быть безопасно работать с физической памятью, не нарушая ее (поскольку наличие только одного пробела намного проще)?

EDIT: я спрашиваю об этом, потому что сказано, что это одно из преимуществ Лиспа является единым адресным пространством:

Безопасный язык означает надежную среду без необходимости выделения задач в отдельные области памяти.

Характерная для Unix модель «четко разделенного процесса» имеет большие преимущества при работе с программным обеспечением, которое может быть ненадежным до такой степени, что становится небезопасным, как в случае с кодом, написанным на C или C++, где доступ к недопустимому указателю может «разрушить систему». система." MS-DOS и ее наследники очень ненадежны в этом смысле, где любая программная ошибка может вывести из строя всю систему; «Синий экран смерти» и тому подобное.

Если вся система построена и закодирована на Лиспе, она так же надежна, как и среда Лиспа. Как правило, это достаточно безопасно, так как когда вы попадаете на соответствующие стандартам уровни, они становятся достаточно надежными и не предлагают прямой доступ к указателю, который позволил бы системе самоуничтожиться.

Третий закон разумных персональных компьютеров

Энергонезависимые запоминающие устройства (т. е. ОЗУ) должны служить исключительно в качестве кэша чтения/записи для энергонезависимых запоминающих устройств. С точки зрения всего программного обеспечения, кроме операционной системы, машина должна иметь единое адресное пространство, которое можно считать энергонезависимым. Ни одна компьютерная система не подчиняется этому закону, поскольку для полного восстановления своего состояния после нарушения источника питания требуется больше времени, чем для электрической лампы.

Единое адресное пространство, как указано, удерживает все запущенные процессы в одном и том же пространстве памяти. Мне просто любопытно, почему люди настаивают на том, что единое адресное пространство лучше. Я соотношу это с синтаксисом Лиспа, подобным AST, чтобы попытаться объяснить, как это соответствует модели единого пространства.


person Amumu    schedule 04.07.2012    source источник
comment
Данные никогда не бывают кодом, распространенное заблуждение.   -  person leppie    schedule 04.07.2012
comment
Короткий ответ: макросы. Наличие такого синтаксиса значительно упрощает генерацию кода в макросах и перевешивает все возможные недостатки. И все это не имеет ничего общего с реальной моделью памяти. Скомпилированный код Lisp в любом случае не имеет ничего общего с S-выражениями, так же как скомпилированный код C не имеет ничего общего со всеми этими фигурными скобками.   -  person SK-logic    schedule 04.07.2012
comment
@SK-logic Что касается макросов, я изучаю только основы. Не пробовал многое из этого, так как он должен быть для продвинутых Lispers. Я часто слышал, что синтаксис Lisp удобен для компилятора, и я имею в виду машину Lisp, которая изначально поддерживает Lisp, поэтому синтаксис должен иметь какое-то отношение к скобкам.   -  person Amumu    schedule 04.07.2012
comment
@Amumu, машины Lisp никоим образом не будут интерпретировать ваши S-выражения изначально. Они отличаются от других ISA только набором инструкций и аппаратным сборщиком мусора. Вы увидите то же самое и в процессорах, ориентированных на Java или Ada. Никакой связи с синтаксисом нет. Синтаксис Lisp удобен для компилятора в том смысле, что он позволяет легко расширять компилятор (с помощью макросов). Без макросов это не имеет особого смысла, поскольку синтаксический анализ в любом случае дешев и прост, он может стать проблемой, только если вы попытаетесь ввести какую-либо форму квазицитирования.   -  person SK-logic    schedule 04.07.2012
comment
@SK-logic Хорошо, думаю, мне нужно больше узнать о макросах. В настоящее время также идея расширения Лиспа с помощью макросов, я вижу только упрощенные примеры, которые вместо этого могут напрямую использоваться функциями. Опять же, если это не так, то какой смысл вводить скобки и AST в язык?   -  person Amumu    schedule 04.07.2012
comment
@Amumu, взгляните, скажем, на макрос LOOP в Common Lisp. Или, как еще одна крайность, полная переработка языка, сделанная поверх макросов: bit.ly/vqqvHU   -  person SK-logic    schedule 04.07.2012


Ответы (1)


Ваш вопрос не очень точно отражает реальность, особенно в части разделения кода/данных в Linux и других ОС. На самом деле это разделение осуществляется не на уровне ОС, а компилятором/загрузчиком программы. На уровне ОС есть только страницы памяти, для которых могут быть установлены разные биты защиты (например, исполняемый файл, доступ только для чтения и т. д.), а выше этого уровня существуют различные исполняемые форматы (например, ELF в Linux), которые определяют ограничения для различных частей программной памяти.

Возвращаясь к Лиспу, насколько я знаю, исторически формат S-выражения использовался создателями Лиспа, потому что они хотели сконцентрироваться на семантике языка, отложив на некоторое время в сторону синтаксис. Был план в конечном итоге создать некоторый синтаксис для Лиспа (см. М-выражения), и были некоторые языки на основе Лиспа, которые имели дополнительный синтаксис, например Dylan. Но в целом сообщество Лиспа пришло к единому мнению, что преимущества S-выражений перевешивают их недостатки, поэтому они застряли.

Что касается кода как данных, это не связано строго с S-выражениями, поскольку другой код также может рассматриваться как данные. Весь этот подход называется метапрограммированием и поддерживается многими языками на разных уровнях и с помощью различных механизмов. Каждый язык, поддерживающий eval (Perl, JavaScript, Python) позволяет обращаться с кодом как с данными, просто представление почти всегда представляет собой строку, тогда как в Лиспе это дерево, что намного удобнее и упрощает сложные вещи, такие как макросы. .

person Vsevolod Dyomkin    schedule 04.07.2012
comment
Это зависит от того, как вы смотрите на уровень ОС. Конечно, ОС оперирует памятью, используя в качестве базовой единицы страницы, но структура памяти организована по той же модели: один сегмент для кода, один сегмент для данных, один сегмент для bss, один для стека и один для кучи. Это то же самое, только в физическом пространстве. - person Amumu; 04.07.2012
comment
Изначально были выражения S и выражения M. Выражения M предназначались для использования программистом с компонентом, переводящим их в (внутренний) формат выражения S. М-выражения считались важными, но их планировалось реализовать позже, а позже они так и не появились. - person Vatine; 04.07.2012
comment
@Amumu эти сегменты определяются загрузчиком программы. Большинство современных операционных систем используют плоскую модель памяти, поэтому сегменты не сопоставляются с сегментами памяти (в смысле модели сегментации памяти), они просто тем или иным образом сопоставляются со страницами, и страницы помечаются соответствующим образом. Вполне возможно создать другую программу-загрузчик, которая будет использовать страницы по-другому. - person Vsevolod Dyomkin; 05.07.2012