Скільки примітивів потрібно для побудови машини LISP? Десять, сім чи п’ять?


80

На цьому сайті кажуть, що є 10 примітивів LISP. Примітиви є: atom, quote, eq, car, cdr, cons, cond, lambda, label, apply.

http://hyperpolyglot.wikidot.com/lisp#ten-primitive

Стіві вважає, що їх сім (або п’ять):

Це частина чистоти ідеї LISP: вам потрібно лише сім (або це п’ять?) Примітивів, щоб створити повну машину. http://steve-yegge.blogspot.com/2006/04/lisp-is-not-acceptable-lisp.html

Яка мінімальна кількість примітивів для побудови машини LISP (тобто щось, що може запускати функцію eval / value на коді LISP)? (А які це?)

(Я розумію, ти міг би жити без atom, label and apply)

Відповіді:


58

Основні предикати / F-функції

McCarthy «s Елементарні S-функції і предикати були:

  1. atom

    Що було необхідно, оскільки автомобіль та компакт-диск визначені лише для списків, а це означає, що ви не можете розраховувати на будь-яку відповідь, щоб вказати, що відбувалося, якщо ви дали carатом.

  2. eq

    Для перевірки рівності між атомами.

  3. car

    Для повернення першої половини (адреси) комірки мінусів. (Зміст адресного реєстру).

  4. cdr

    Для повернення другої половини (зменшення) комірки мінусів. (Зміст реєстру декрементів).

  5. cons

    Для створення нової комірки "мінус", половина адреси якої містить перший аргумент "мінуси", а половина зменшення містить другий аргумент.

Зв’язування: S-функції

Потім він додав до свого основного позначення, щоб дати можливість писати те, що він називав S-функціями:

  1. quote

    Представити вираз без його оцінки.

  2. cond

    Основний умовний, який буде використовуватися з раніше описаними предикатами.

  3. lambda

    Для позначення функції.

  4. label

    Хоча йому це не потрібно для рекурсії, він, можливо, не знав про Y-комбінатор ( за Полом Грем ), але він додав це для зручності та для полегшення рекурсії.


Тож ви бачите, що він насправді визначив 9 основних "операторів" для своєї машини Lisp. У попередній відповіді на ще одне з ваших запитань я пояснив, як ви можете представляти і оперувати числами за допомогою цієї системи.

Але відповідь на це питання насправді залежить від того, що ви хочете від своєї машини Lisp. Ви можете реалізувати такий без labelфункції, оскільки ви можете просто функціонально скласти все і отримати рекурсію, застосувавши Y-Combinator.

atomможе бути відкинуто, якщо ви визначили carоперацію з поверненням атомів NIL.

Ви могли б по суті мати машину LISP Маккарті з 7 із цих 9 визначених примітивів, але ви могли б нібито визначити більш стислу версію залежно від того, скільки незручностей ви хочете заподіяти собі. Мені дуже подобається його машина, або багато примітивів на нових мовах, таких як Clojure.


19
Видається, що Маккарті не знав про Y-Combinator, помилково. На сторінці 7 "Рекурсивних функцій ..." Маккарті пише: Існує позначення операторів, які називаються комбінаторами для об'єднання функцій без використання змінних. На жаль, комбінаційні вирази для цікавого поєднання функцій, як правило, є тривалими і нечитабельними.
luser droog

1
Тут чогось не вистачає. Така шепелявість не могла додати два числа або навіть зрозуміти, що 12 - це число.
Альберт ван дер Горст,

1
Це справді може! Я також написав до нього публікацію в блозі. blog.isaachodes.io/p/set-theory-and-lisp
Ісаак

1
Звичайно, він не використовував би традиційне машинне представлення цілих чисел, і в результаті був би досить неефективним.
Ісаак

14

Найкращий спосіб насправді це точно знати, якщо ви це впровадите. Я використав 3 літа, щоб створити Zozotez, який представляє собою Маккартіський іспит, що працює на Brainfuck .

Я спробував з’ясувати, що мені потрібно, і на форумі ви знайдете тему, яка говорить, що вам потрібна лише лямбда. Таким чином, ви можете скласти цілий LISP в лямбда-числення, яке вам подобається. Мені це було цікаво, але навряд чи це шлях, якщо ви хочете щось, що з часом має побічні ефекти і працює в реальному світі.

Для повного ЛІСП Тьюрінга я використав пояснення Пола Гремем про роботу Маккарті, і все, що вам насправді потрібно:

  • символ-оцінка
  • спеціальна форма цитата
  • спеціальна форма, якщо (або умовна)
  • спеціальна форма лямбда (подібна до цитати)
  • функція екв
  • функція атом
  • функційні мінуси
  • функціональний автомобіль
  • функція cdr
  • функція-відправка (список-лямбда)

Це 10. На додаток до цього, щоб мати реалізацію, яку ви можете протестувати, а не лише на кресленні:

  • читання функції
  • запис функції

Це 12. У своєму Zozotez я також реалізував set і flambda (анонімні макроси, як лямбда). Я міг би подати його в бібліотеку, що реалізує будь-який динамічний пов'язаний lisp (Elisp, picoLisp), за винятком файлового вводу-виводу (оскільки базовий BF не підтримує його крім stdin / stdout).

Я рекомендую будь-кому застосувати інтерпретатор LISP1 як в LISP, так і (не в LISP), щоб повністю зрозуміти, як реалізована мова. LISP має дуже простий синтаксис, тому він є хорошою відправною точкою для синтаксичного аналізатора. Зараз я працюю над компілятором схем, написаним у схемі з різними цілями (наприклад, Сталін для цілі С), сподіваюся, BF як одна з них.


3
Що стосується використання нічого, крім лямбда-сигналу, порівняйте з "Комп’ютером з одним набором інструкцій", "логікою NAND", "Обчисленням комбінатора
лиж

2
@ ajm475du Все це те саме, що "вам потрібна лише лямбда". Це повна версія, але майже неможлива у використанні через відсутність вводу-виводу. BF потрібно лише 6 інструкцій, щоб бути повним. решта, якщо зробити це практичним.
Sylwester

1
Хм Що робити, якщо ви підключите stdin / stdout інтерпретатора bf до іншої програми, яка може інтерпретувати команди file / io? Тоді bf-lisp міг писати запити, а потім читати з запитуваного файлу.
luser droog

2
@luserdroog Ви пропонуєте використовувати stdin / stdout як шину повідомлень для якоїсь програми / ОС для реалізації системних викликів. Я насправді думаю зробити це для мого компілятора, який буде компілювати в BF. Напр. якщо ви використовуєте більше операцій вводу-виводу, ніж читання / запис, програма надсилає магічний рядок вимог, і API надасть рукостискання майже так само, як ви отримували помилки під час запуску програм Windows у DOS ще в 90-х. Зверніть увагу, що BF все ще повинен надати термінал, отже, для початку введення / виведення це просто подальше розширення.
Sylwester

10

Маккарті використовували сім операторів для визначення оригінального Lisp: quote, atom, eq, car, cdr, consі cond. Ця стаття відтворює його кроки.


1
Він насправді також використовував label, хоча цього не потрібно було мати.
Ісаак

2
І йому теж потрібно було lambda.
Ісаак

9
Спочатку мене це також бентежило, але він насправді визначає lambdaі labelз точки зору наведених семи примітивів. Він просто вводить, що він має на увазі, перед тим, як evalнавести їх реалізацію, у визначенні в розділі 4. Ви можете бачити, що реалізація evalзабезпечує підтримку lambda/ listбез себе, залежно від того, що.
сплав

8

У цьому запитанні зазначено:

Не існує єдиного "найкращого" мінімального набору примітивів; все залежить від реалізації. Наприклад, навіть щось таке базове, як числа, не обов’язково має бути примітивним, і воно може бути представлене як списки. Один із можливих наборів примітивів може включати CAR, CDR та CONS для маніпулювання S-виразами, READ та PRINT для введення / виводу S-виразів та APPLY та EVAL для кишок інтерпретатора. Але тоді ви можете додати LAMBDA для функцій, еквалайзер для рівності, COND для умовних, SET для призначення і DEFUN для визначень. ЦИТАТА також може стати в нагоді.

Це походить від Школи комп’ютерних наук, веб-сайту Carnegie Melon.



2

Вам просто потрібна MOVінструкція x86 .

"M / o / Vfuscator (коротке" o ", звучить як" mobfuscator ") компілює програми в інструкції" mov "і лише інструкції" mov ". Арифметика, порівняння, переходи, виклики функцій та все інше, що потрібно програмі все виконується за допомогою операцій mov; немає самомодифікуючого коду, немає обчислень, викликаних транспортом, і жодної іншої форми обману без руху. "

Хоча серйозно, ці примітиви не реалізують Lisp Machine. Машині потрібні такі засоби, як введення / виведення та збір сміття. Не кажучи вже про механізм виклику функції! Гаразд, у вас є сім примітивів, які є функціями. Як машина викликає функцію?

Правильне розуміння того, що ці примітиви роблять можливим, полягає в тому, що вони розкривають набір інструкцій універсальної машини Тьюрінга . Оскільки ці вказівки є "Ліспі", за допомогою ковзання мови (розмовляючи Лиспа) ми підступно називаємо це "Машиною Ліспа". "Універсальний" означає, що машина програмована: за допомогою деяких комбінованих інструкцій, що застосовуються до Універсальної машини Тьюрінга, ми можемо створити екземпляр будь-якої машини Тьюрінга. Але поки що все це суто математична конструкція.

Щоб насправді змоделювати цю UTM - реалізувати її фізично, щоб дослідити на комп’ютері, нам потрібна машина, яка забезпечує нам спосіб фактичного введення тих форм, які створюють машини Тьюрінга з комбінацій цих семи інструкцій Ліспа. І нам також потрібна якась форма виводу; машина, як мінімум, зможе сказати нам "так", "ні" або "Зачекай, я все ще працюю".

Іншими словами, єдиний спосіб, яким ці сім інструкцій можуть практично працювати, - це якщо вони розміщені у більшій машині, яка забезпечує середовище.

Також зауважте, що сім примітивів hamрема не мають явної підтримки чисел, тому вам доведеться будувати їх з функцій (техніка "церковні цифри"). Жодна реалізація Lisp не робить такого шаленого.


1
Любіть це. Я хотів би задати питання про UTM, але, думаю, ви це вже розбили. Я намагаюся продумати питання, що стосується обчислювальної техніки 8, але обчислювальної техніки, UTM та Lisp.
hawkeye
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.