pg.gimran.org

Lisp-тің ерекшелігі неде болды

Желтоқсан 2001 · Барлық эсселер

Пол Грэмнің «Lisp-тің ерекшелігі неде болды» эссесінің аудармасы. Түпнұсқа: https://paulgraham.com/diff.html. Машиналық аударма (Gemini).

Translation of Paul Graham's essay 'What Made Lisp Different'. Original: https://paulgraham.com/diff.html. Machine translation (Gemini).

(2002 жылдың мамырында қайта қаралған)

(Бұл мақала LL1 тарату тізіміндегі кейбір сұрақтарға жауап ретінде пайда болды. Қазір ол Revenge of the Nerds («Ботаниктердің кегі») мақаласына енгізілген.)

Маккарти 1950 жылдардың соңында Lisp тілін жасаған кезде, ол бұрыннан бар тілдерден түбегейлі өзгеше болды, олардың ішіндегі ең маңыздысы Fortran еді.

Lisp өзіне тоғыз жаңа идеяны біріктірді:

1. Шартты өрнектер (conditionals). Шартты өрнек — бұл if-then-else құрылымы. Қазір біз бұған үйреншікті нәрсе ретінде қараймыз. Оларды Lisp-ті әзірлеу барысында Маккарти ойлап тапқан. (Ол кезде Fortran-да негізгі аппараттық құралдың тармақталу нұсқауына қатты тәуелді шартты goto ғана болған.) Algol комитетінің мүшесі болған Маккарти шартты өрнектерді Algol-ға енгізді, сол жерден олар басқа тілдердің көбіне таралды.

2. Функция типі. Lisp-те функциялар бірінші дәрежелі объектілер (first class objects) болып табылады — олар бүтін сандар, жолдар және т.б. сияқты кәдімгі деректер типі, олардың литералдық көрінісі бар, оларды айнымалыларда сақтауға, аргумент ретінде беруге және сол сияқты әрекеттер жасауға болады.

3. Рекурсия. Әрине, рекурсия Lisp-ке дейін де математикалық ұғым ретінде болған, бірақ Lisp оны қолдаған алғашқы бағдарламалау тілі болды. (Бұл шамасы функцияларды бірінші дәрежелі объектілерге айналдырудың салдарынан өздігінен туындаған.)

4. Айнымалылардың жаңа тұжырымдамасы. Lisp-те барлық айнымалылар іс жүзінде сілтегіштер (pointers) болып табылады. Типтер айнымалыларға емес, мәндерге тиесілі, ал айнымалыларды тағайындау немесе байланыстыру олар меңзеп тұрған нәрсені емес, сілтегіштерді көшіруді білдіреді.

5. Қоқыс жинау (Garbage-collection).

6. Өрнектерден құралған бағдарламалар. Lisp бағдарламалары — бұл әрқайсысы мән қайтаратын өрнектер ағашы. (Кейбір Lisp диалектілерінде өрнектер бірнеше мән қайтара алады.) Бұл өрнектер мен нұсқауларды (statements) ажырататын Fortran және одан кейінгі тілдердің көпшілігіне қарама-қайшы келеді.

Бұл айырмашылықтың Fortran-да болуы табиғи нәрсе еді, өйткені (енгізу форматы перфокарталар болған тіл үшін бұл таңқаларлық емес) тіл жолдарға бағытталған еді. Нұсқауларды бірінің ішіне бірін кірістіру мүмкін емес еді. Сондықтан математикалық амалдардың жұмыс істеуі үшін өрнектер қажет болғанымен, басқа ешнәрсені мән қайтаратындай етудің мәні болмады, өйткені оны күтіп алатын ешнәрсе жоқ еді.

Бұл шектеу блок құрылымды тілдердің келуімен жойылды, бірақ ол кезде тым кеш еді. Өрнектер мен нұсқаулар арасындағы айырмашылық берік орнығып қалған болатын. Ол Fortran-нан Algol-ға, ал одан екеуінің де мұрагерлеріне таралды.

Тіл толығымен өрнектерден тұрған кезде, сіз өрнектерді қалауыңызша құрастыра аласыз. Сіз мына түрде де жаза аласыз (Arc синтаксисін қолдана отырып):

(if foo (= x 1) (= x 2))

немесе

(= x (if foo 1 2))

7. Символ типі (symbol type). Символдардың жолдардан (strings) айырмашылығы — теңдікті жай ғана сілтегішті салыстыру арқылы тексеруге болады.

8. Символдар ағашын қолданатын код жазбасының жүйесі (нотация).

9. Бүкіл тілдің әрқашан қолжетімді болуы. Оқу уақыты (read-time), компиляция уақыты (compile-time) және орындалу уақыты (runtime) арасында нақты шекара жоқ. Сіз оқу кезінде кодты компиляциялай аласыз немесе іске қоса аласыз, компиляция кезінде кодты оқи аласыз немесе іске қоса аласыз, және орындалу уақытында кодты оқи аласыз немесе компиляциялай аласыз.

Кодты оқу уақытында іске қосу пайдаланушыларға Lisp синтаксисін қайта бағдарламалауға мүмкіндік береді; компиляция уақытында кодты іске қосу — макростардың негізі; орындалу уақытында компиляциялау — Emacs сияқты бағдарламаларда Lisp-ті кеңейту тілі ретінде пайдаланудың негізі; ал орындалу уақытында оқу бағдарламаларға жақында XML түрінде қайта ойлап табылған идея — s-өрнектерді қолдану арқылы байланысуға мүмкіндік береді.

Lisp алғаш рет ойлап табылған кезде, бұл идеялардың барлығы 1950 жылдардың соңындағы қолжетімді аппараттық құралдармен анықталған қарапайым бағдарламалау тәжірибесінен тым алыс еді.

Уақыт өте келе, бірқатар танымал тілдер арқылы көрініс тапқан негізгі бағдарламалау тілі бірте-бірте Lisp-ке қарай дамыды. 1–5 пункттер қазір кеңінен таралған. 6-пункт негізгі ағымда пайда бола бастады. Python-да 7-нің белгілі бір түрі бар, бірақ оған арналған арнайы синтаксис жоқ сияқты. Lisp макростарын жүзеге асыруға мүмкіндік беретін 8-пункт (9-бен бірге) осы уақытқа дейін тек Lisp-ке ғана тән болып қалып отыр, мүмкін бұған (a) оның сол жақшаларды немесе соған ұқсас қолайсыз бірдеңені талап ететіні, және (b) егер сіз осы соңғы қуатты қоссаңыз, сіз енді жаңа тіл ойлап таптым деп айта алмайсыз, тек Lisp-тің жаңа диалектісін жасадым дей аласыз ; -)

Қазіргі бағдарламашылар үшін пайдалы болғанымен, Lisp-ті басқа тілдер қабылдаған кездейсоқ амалдардан айырмашылығы тұрғысынан сипаттау оғаш көрінеді. Маккарти бұл туралы олай ойламаған болуы мүмкін. Lisp Fortran-дағы қателіктерді түзету үшін жасалмаған; ол көбінесе есептеуді аксиоматизациялау әрекетінің жанама өнімі ретінде пайда болды.