Чи все ще у Lisp є якась особлива функція, яку НЕ прийняли інші мови програмування?


35

Чи все ще у Lisp є якась особлива функція, яку НЕ прийняли інші мови програмування?

Під Лісом я маю на увазі всі мови програмування Lisp в цілому. Мені сказали, як дивовижний Лісп і знаю, що багато мов надихнули Ліса. Але чи все ж у Lisp є якась ексклюзивна функція дизайну, яку просто неможливо зробити жодною іншою мовою?

Причиною, що я поставив запитання, є те, що останнім часом, будучи самодіяльним програмістом, я почав вивчати Clojure просто заради задоволення, і результат полягає в тому, що я знайшов безліч публікацій і коментарів, пов’язаних з Lisp, сказавши, але одне: "Lisp унікальний ", але інші сучасні мови програмування вже прийняли та вкрали багато ідей з Lisp, як умовні умови, рекурсії та функції як першокласного громадянина. І навіть метапрограмування можна виконати багатьма мовами.

Чи щось я пропустив і чи «Лисп все ще відрізняється»?

Або мені пощастило, тому що інші сучасні мови вкрали всі хороші частини з Ліспа, так що не потрібно копатися у дужках Лісп світу , а "Лісп був іншим".


3
Обмін дослідженнями допомагає всім. Розкажіть, що ви пробували і чому це не відповідало вашим потребам. Це свідчить про те, що ви знайшли час, щоб спробувати допомогти собі, це позбавляє нас від повторення очевидних відповідей, а найбільше це допомагає вам отримати більш конкретну та релевантну відповідь. Також дивіться Як просити
gnat

3
@gnat Thx за порадою, і я оновив своє питання :)
iceX

10
Одна з проблем полягає в тому, що, коли мова має певний підмножина функцій Lisp (наприклад, S-вирази та макроси), люди стверджують, що це Lisp. Що, звичайно, має наслідком того, що (на думку цих людей) жодна неліспійська мова не може мати цих особливостей.

9
Я думаю, немає іншої мови, де круглі дужки є єдиною формою групування для всього :-)
Doc Brown

Лисп як сім'я може бути не надзвичайно унікальним, але багато діалектів, що бавляться (Racket, CL, Scheme, Clojure), все ж пропонують багато корисних / унікальних особливостей.
Даніель Гратцер

Відповіді:


28

Канонічне посилання на цей тип запитань - це те, що зробив Лісп Пола Грема . Дві основні особливості Lisp, які не є широко доступними, відповідно до цієї статті на момент її написання, є:

8. Позначення коду з використанням дерев символів.

9. Вся мова завжди доступна. Немає реального розмежування між часом читання, часом компіляції та часом виконання. Ви можете компілювати або запускати код під час читання, читання або запуску коду під час компіляції та читання або компілювання коду під час виконання.

Коментар стосується кожної точки та називає популярні мови, де ця функція доступна.

8, що (з 9) є тим, що робить макроси Ліспа можливими, на сьогоднішній день все ще унікальний для Ліспа, можливо, тому що: (а) він вимагає цих парен, або щось настільки ж погано, і (б) якщо додати цей остаточний приріст сили , ви більше не можете стверджувати, що винайшли нову мову, а лише створили новий діалект Ліспа; -)

Зауважте, що ця стаття востаннє була переглянута у 2002 році, і за останні 11 років з'явилося велике різноманіття нових мов, деякі з яких можуть включати всі ці функції Lisp у свій дизайн.


2
Ці функції не характерні лише для Lisp (і безпосередньо виведених варіантів), і вже не дуже давно.
Дональні стипендіати

21
@iceX: Різниця між JavaScript та такими мовами, як Lisp, Smalltalk, Self, Newspeak, APL, Factor, Forth тощо полягає в тому, що в JavaScript програми "мертві". Вони є текстовими файлами. Ви вбиваєте запущену програму, редагуєте текстовий файл, а потім запускаєте абсолютно нову копію програми. У тих інших (так званих "жвавих" середовищах) ви ніколи не зупиняєте запущену програму, сама запущена програма - це набір об'єктів у пам'яті, якими ви маніпулюєте так само, як ви маніпулюєте будь-яким іншим об'єктом, поки він працює . (Примітка. Це не так для Clojure, але більшість старших Lisps роблять це саме так.)
Jörg W

2
@ JörgWMittag Нічого собі ... Отже, мови програмування, такі як Clojure, Clojurescript, lispyscript, насправді не є "справжнім lisp", оскільки вони не можуть змінити свій код так, як це робить Old-School Lisp, як Common Lisp. Але ... якщо вони не можуть його змінити ... навіщо турбуватися використовувати S-вираз, який я вважав, для маніпуляції кодом ... (таке відчуття, що я просто впав у глибоку темну кролячу дірку)
IceX

4
@iceX: Багато мов мають evalчи подібні, і досить багато хто може зробити метапрограмування, наприклад, шаблон Haskell Haskell. (Можливо) унікальна річ у Lisp полягає в тому, що представлення даних, коду та мета-коду однакове - не тільки в синтаксисі, але це дійсно те саме.
tdammers

2
@iceX Eval - це лише одна її частина, але не вся. У Lisp ви можете виконати код під час компіляції. Ви можете виконати код у час читання. Так, clojure підтримує весь динамізм Ліспа, він має макроси, макроси читання та eval, а також можливість приєднати REPL до запущеної програми для зміни її на льоту.
каменеметал

15

На це питання важко відповісти, оскільки хтось повинен знати всі мови для того, щоб знати, що жодна інша не має певної функції, доступної в Lisp, тому наступне базується на мовах, з якими я маю досвід.

У верхній частині голови умови , які я не бачив жодної іншої мови. Подумайте "винятки", але де стек викликів не розкручений і де абонент може надіслати значення відновлення на винятковий сайт, але не порушуючи стек викликів між обробником та джерелом винятку. Справедливо кажучи, це справді просто спеціальне застосування продовжень, тому Ruby та Scheme (принаймні) можуть це зробити.

Макросистема Lisp виграє від регулярності / гомоконічності, але Scala планує включити їх як стабільну особливість у 2.12, а Template Haskell вимагає подібних особливостей. Я б стверджував, що вони будуть більш синтаксично складними, ніж у Lisp, але генерування коду часу компіляції існує незалежно.

Подумайте, однак, пряма побудова форм - це лише один вид макросів, доступних у Lisp: я ніде більше не бачив еквівалента макросів компілятора чи читача.

Здатність деяких діалектів (наприклад, SBCL ) зберігати повноцінне, відновлюване процес зображення є класною, але знову ж таки не унікальною: Smalltalk займається цим десятиліттями.

Багато інших мов дозволяють присвоювати деструктуризацію при поверненні масивів, але підхід # 'значень та #' багатозначне прив'язування / нехай-значення все ще здається специфічним для загальної програми Lisp та Schema (яка все ще може робити "регулярне" руйнування також ). "Wantarray" Perl дозволяє функції визначати, чи викликається він у скалярному, списку чи недійсному контексті, щоб він міг регулювати своє повернене значення аналогічним (-ish) способом, але я не бачив "справжніх" кількох повернених значень зовні схеми / ЗР.

Щодо мовних особливостей, то, мабуть, не так багато, що Lisp може зробити, що інші мови не можуть (Turing повнота є такою, якою є). Що це , однак, є мовою , де код виражається в термінах своїх власних структур даних, що робить велику ідею ™ -Ось коди даних то , що відносно легко працювати.


3
Макроси Scala набагато менш потужні, ніж макроси Lisp, а також TH макроси, гігієнічні макроси схеми тощо. Не менш потужну систему можна знайти в MetaLua та Converge.
SK-логіка

4

Після стількох десятиліть я не думаю, що в Ліспі є щось виняткове. Але навіть сьогодні є багато цікавого, що важко знайти за межами Ліпса. Кілька речей, які спадають на думку:

  • Якісна об'єктна система зі складними мета-протоколами (тобто CLOS) не є популярною віддалено.
  • багато методів час від часу спливають десь, але більшість людей ніколи про них не чули.
  • Як зазначали інші, система умов є досить складною порівняно з популярними механізмами обробки виключень.
  • Компактне представлення семантики мови (eval), розширення можливостей підходу до визначення мови та надання її доступності для прямого глибокого адаптації (див. SICP ) - "eval" функції сучасних популярних мов просто не мають однакових властивостей.

Нарешті, з Ліспу можна дізнатися багато іншого, що стосується не самої мови, але стала частиною історії Ліспа та загубилася в часі. Наприклад, Interlisp, Symbolics Genera і т. Д. ... якщо ви ніколи не покладете руки на Genera, перегляньте цю тему comp.lang.lisp, де Кент Пітман описує, як "Emacs - лише бліда тінь Zmacs Genera" - що все було включено наявність потужної системи Lisp, до складу якої входив Zmacs, яка працювала на машині Lisp.


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

Вони мають важливі відмінності. Якщо у вас виникли проблеми з пошуком ресурсу, ви завжди можете створити тут нове запитання ..
Thiago Silva

Джулія має мультиметоди, а параметричний поліморфізм Хаскелла схожий на багатометоди. Існують способи моделювання багатометодів багатьма мовами. Система стану - це те, чого я дуже хочу особливо (редагувати та продовжувати, хоча я це бачив для налагоджувачів C #).
aoeu256

4

Це не обов'язково певна одна особливість . Це весь зовнішній вигляд і те, як певні набори функцій працюють разом.

У JavaScript або Java є багато можливостей Lisp (віртуальна машина, компілятор / оцінювач, збирання сміття тощо). Але JavaScript, наприклад, не має символічної частини програмування, йому не вистачає математичних можливостей (внутрішньо він лише плаває), йому не вистачає обробки помилок тощо.

Багато звичайних систем Lisp оптимізовано для способу розробки, де поширюється нове програмне забезпечення поступово, розширюючи мову Lisp в різних вимірах за допомогою різних методів метапрограмування - без тривалого перезавантаження програмного забезпечення. Таким чином, він повинен бути гнучким і розтяжним, але в той же час він повинен бути надійним. Зміна мови (макроси - це в основному спосіб для користувача розширити компілятор) без збоїв програми.

Тепер щось на зразок JavaScript також використовується для розширення програми, як правило, веб-браузера. Але більшу частину часу в програмі JavaScript не дуже багато мета-програмування - крім деяких хакерів OOP .

Приклад:

Можна реалізувати загальне вдосконалене програмне забезпечення з математики для домену комп'ютерної алгебри в основному двома способами: записувати двигун на C зі спеціалізованою мовою вгорі (наприклад, Mathematica ) або на якомусь більш досконалому діалекті Lisp. Macsyma / Maxima у звичайному Lisp, зменшення у стандартному Lisp, Axiom у Common Lisp.

(Також є один або кілька написаних на Python.)

Існує не так багато систем, які пропонують набір функцій на кшталт Axiom , який працює на вершині Common Lisp.

Що зробило Lisp привабливим для таких типів додатків - це сукупність функцій: розширені основні математики (bignums, коефіцієнти, ...), символічні обчислення, інтерактивний компілятор тощо. Ці речі цілком можливо отримати, реалізуючи їх у низькому режимі, рівень мови. Таким чином, введено 50% або більше типової системи Lisp.


2

Не наскільки я знаю. Forth легко настільки ж динамічний, як і Lisp, можливо, тим більше, що динамічний код у Forth виглядає як звичайний код Forth, тоді як макроси Lisp, як правило, використовують інші функції, ніж звичайний код Lisp (у Clojure принаймні я ніколи не використовував цитату синтаксису поза макросом) і в результаті вони виглядають по-справжньому відмінними від звичайного коду Lisp. Як приклад того, наскільки динамічним є Forth, ось спосіб реалізації коментарів у Forth :

: (   41 word drop ; immediate
( That was the definition for the comment word. )
( Now we can add comments to what we are doing! )

1
Наскільки весело, як здається, Форт, я завжди вважав це безнадійно непрозорим і незручним, можливо, тому, що він заснований на стеках і все перевернуто.
Роберт Харві

2
Що з цікавості, що ви розумієте під "відокремленою від основної частини мови"? Макроси в Ліспі мають повний доступ до всіх функцій, визначених у момент визначення макросу, будь-яка з яких може бути використана для створення форми, до якої макрос розширюється. Це може включати інформацію, отриману з бази даних та / або сервера. Ваш приклад коментаря може бути визначений як: (коментар defmacro (& відпочинок)), чи не так?
Danny Woods

1
@DannyWoods Я маю на увазі макроси не схожі на звичайний код. Принаймні, у clojure ви можете сказати макрокод з звичайного коду, оскільки він сильно використовує цитату синтаксису, без цикла спланування тощо, що незвично в звичайному коді. Цей приклад з даного коду, який я дав, виглядає як звичайний код до тих пір, поки ви не побачите негайного. Читаючи мою відповідь, це просто погано виражено.
каменеметал

1
@stonemetal Не хвилюйтесь, але варто зауважити, що в цитаті синтаксису немає нічого макроспеціального, як у Common Lisp, так і Clojure. Іноді зручно мати зворотні вирази у звичайних визначеннях функцій, а макроорганізми можна будувати вручну за допомогою простих списків (хоча це потрібно робити лише один раз або два рази, щоб вирішити, що цитата синтаксису - це добре!)
Danny Woods

1
Для справедливості те саме можна зробити і в Lisp, зареєструвавши макрос зчитуваного користувачем.
fjarri

2

Лісп має багато діалектів, і кожен з них має свій набір особливостей. Моя улюблена особливість, яка навряд чи буде прийнята будь-якою іншою мовою, - це "стек спагетті" від Interlisp .

Стек спагетті - це як закриття, але на стероїдах. Це зберігає не тільки поточну функцію, але і весь контекст до вершини стеку. Щось на зразок спільного розпорядку , за винятком того, що ви можете їх створювати довільно, внаслідок чого з'являється ієрархія контекстів стека.


Не знав цього, перевірю, дякую за вашу відповідь :)
iceX

7
Це те саме, що продовження схеми?
Nicola Musatti

1
@NicolaMusatti, "стек спагетті" - це загальна стратегія реалізації для подібних схем продовжень (яку можна викликати після повернення функції, яка їх створила).
Алекс Д
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.