Целта на синтаксиса на Lisp за моделиране на AST

Синтаксисът на Lisp представлява AST, доколкото знам, но във формат на високо ниво, за да позволи на човека лесно да чете и модифицира, като в същото време улеснява машината да обработва и изходния код.

Поради тази причина в Lisp се казва, че кодът е данни и данните са код, тъй като кодът (s-epxression) е просто AST по същество. Можем да включим повече AST (които са нашите данни, които са просто код на lisp) в други AST (код на lisp) или независимо, за да разширим функционалността му и да го манипулираме в движение (по време на изпълнение), без да се налага да прекомпилираме цялата операционна система, за да интегрираме нови код. На други езици трябва да прекомпилираме от, за да превърнем изходния код на човешки език във валиден AST, преди да бъде компилиран в код.

Това ли е причината синтаксисът на Lisp да бъде проектиран такъв, какъвто е (представлява AST, но е четим от човека, за да задоволи както човека, така и машината) на първо място? За да активирате по-силна (в движение - по време на изпълнение), както и по-опростена (без повторно компилиране, по-бърза) комуникация между човек-машина?

Чух, че машината Lisp има само едно адресно пространство, което съдържа всички данни. В операционна система като Linux, програмистите имат само виртуално адресно пространство и се преструват, че е истинското физическо адресно пространство и могат да правят каквото си искат. Данните и кодът в Linux са разделени региони, защото на практика данните са данни и данните са код. В нормална операционна система, написана на C (или език, подобен на C), би било много объркващо, ако работим само с едно адресно пространство за цялата система и смесването на данни с код би било много объркано.

В Lisp Machine, тъй като кодът е данни и данните са код, това ли е причината да има само едно адресно пространство (без виртуалния слой)? Тъй като имаме GC и нямаме указател, трябва ли да е безопасно да работим с физическа памет, без да я разбиваме (тъй като наличието на само 1 единично пространство е много по-малко сложно)?

РЕДАКТИРАНЕ: Питам това, защото се казва, че едно от предимствата на Lisp е единично адресно пространство:

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

Моделът на „ясно отделен процес“, характерен за Unix, има мощни предимства при работа със софтуер, който може да е ненадежден до степен да е опасен, какъвто е случаят с код, написан на C или C++, където невалиден достъп до указател може да „свали система." MS-DOS и неговите наследници са много ненадеждни в този смисъл, където почти всеки програмен бъг може да свали цялата система; "Син екран на смъртта" и други подобни.

Ако цялата система е конструирана и кодирана на Lisp, системата е толкова надеждна, колкото и средата на Lisp. Обикновено това е доста безопасно, тъй като след като стигнете до съвместимите със стандартите слоеве, те са доста надеждни и не предлагат директен достъп до указател, който би позволил на системата да се самоунищожи.

Третият закон за разумни лични компютри

Енергонезависимите устройства за съхранение (т.е. RAM) трябва да служат изключително като кеш за четене/запис за енергонезависими устройства за съхранение. От гледна точка на целия софтуер, с изключение на операционната система, машината трябва да представя едно адресно пространство, което може да се счита за енергонезависимо. Никоя компютърна система не се подчинява на този закон, който отнема повече време, за да възстанови напълно състоянието си след прекъсване на източника на захранване, отколкото на електрическа лампа.

Единното адресно пространство, както е посочено, държи всички работещи процеси в едно и също пространство на паметта. Просто съм любопитен защо хората настояват, че едно адресно пространство е по-добро. Свързвам го с подобен на AST синтаксис на Lisp, за да се опитам да обясня как се вписва в единичния пространствен модел.


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 Добре, мисля, че трябва да науча повече за макросите. В момента, също и идеята за разширяване на Lisp чрез макрос, виждам само опростени примери, които могат да бъдат директно използвани от функции вместо това. Отново, ако не е така, каква е ползата от въвеждането на скоби и 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), които определят ограничения върху различни части от програмната памет.

Връщайки се към Lisp, доколкото ми е известно, исторически форматът на S-израз е бил използван от създателите на Lisp, защото са искали да се концентрират върху семантиката на езика, оставяйки синтаксиса настрана за известно време. Имаше план в крайна сметка да се създаде някакъв синтаксис за Lisp (вижте M-изрази) и имаше някои базирани на Lisp езици, които имаха малко повече синтаксис, като Dylan. Но като цяло общността на Lisp беше стигнала до консенсуса, че ползите от S-изразите надвишават техните недостатъци, така че останаха.

Що се отнася до кода като данни, това не е строго обвързано със S-изрази, тъй като друг код също може да се третира като данни. Целият този подход се нарича мета-програмиране и се поддържа на различни нива и с различни механизми от много езици. Всеки език, който поддържа eval (Perl, JavaScript, Python) позволява да се третира кодът като данни, просто представянето е почти винаги низ, докато в Lisp е дърво, което е много по-удобно и улеснява напреднали неща, като макроси .

person Vsevolod Dyomkin    schedule 04.07.2012
comment
Зависи как гледате на нивото на ОС. Разбира се, операционната система оперира с паметта, като използва страниците като основна единица, но оформлението на паметта е организирано по същия модел: един сегмент за код, един сегмент за данни, един сегмент за bss, един за стек и един за купчина. Това е същото, само че е във физическото пространство. - person Amumu; 04.07.2012
comment
Първоначално имаше S изрази и M изрази. M изразите бяха предназначени да бъдат използвани от програмиста, с компонент, който ги превежда във (вътрешния) формат на S израз. Изразите M бяха счетени за важни, но предвидени за внедряване по-късно и това по-късно никога не пристигна. - person Vatine; 04.07.2012
comment
@Amumu тези сегменти се дефинират от програмата за зареждане. Повечето съвременни операционни системи използват плосък модел на паметта, така че сегментите не се нанасят на сегменти на паметта (в смисъл на модела за сегментиране на паметта), те просто се нанасят на страници по един или друг начин и страниците се маркират по подходящ начин. Напълно възможно е да създадете различна програма за зареждане, която ще използва страниците по различен начин - person Vsevolod Dyomkin; 05.07.2012