?

Log in

Почему LISP? - Жить не можем без проблем! [entries|archive|friends|userinfo]
Жить не можем без проблем!

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Почему LISP? [Jan. 13th, 2011|02:05 pm]
Жить не можем без проблем!

ru_lisp

[aralex]

Как говорил Ворошилов, вопрос к Знатокам (к знатокам LISP-а в данном случае)! Почему таки LISP? Или, если конкретнее, вопроса три:

  1. Для каких именно задач LISP подходит больше, чем другие языки?
  2. За счёт чего для них он подходит больше?
  3. В чём именно выражается его преимущество?

Если не в лом, приведите, pls, коротенькие иллюстрации на LISP-е (или ссылочку на них). Заранее благодарен!

Исходно данный пост был размещён в сообществе ru_programming, но там Знатоков, способных ответить внятно и по сути, увы, не нашлось :(

linkReply

Comments:
[User Picture]From: grundik
2011-01-16 10:50 am (UTC)
Ты сам проверь ;)

Алан Кей, конечно, имеет авторитет, но его область применения инструментов, условия его работы, и, главное, его background сильно отличается от моего.

Ну и это, ты опять троллишь :) А именно выдаёшь свою интерпретацию слов Кея за его слова. А он ведь не говорил того, что Хаскель проще Лиспа в семантике.

Плюс товарищ Кей говорит про Лисп-2, при этом не обращая внимания на то, что есть (хотя, возможно, в то время его не было) Лисп-1 (это к вопросу о том, насколько критики Лиспа вообще в нём разбираются). Опять же, называть лисп функциональным языком есть ошибка (или сознательный троллинг). Лисп мультипарадигменен, и функционален он не больше, чем императивен или ООП-шен.

И последнее. Судя по всему, Кей говорит не про Common Lisp, а про какой-то другой лисп. Это тоже распространённый fail в спорах о лиспе, ибо лиспов дохренища, и между собой они заметно отличаются. И часто те недостатки, что есть в Common Lisp, отсутствуют, например, в scheme (или в Racket).
(Reply) (Parent) (Thread)
[User Picture]From: thesz
2011-01-16 11:06 am (UTC)
>Ну и это, ты опять троллишь :) А именно выдаёшь свою интерпретацию слов Кея за его слова. А он ведь не говорил того, что Хаскель проще Лиспа в семантике.

Вообще-то, он сказал, что упрощение Лиспа со всеми его макросами и специальными формами возможно за счёт изменения порядка вычислений на ленивый.

Правильно ли я интерпретирую его слова сейчас?

Будешь ли ты утверждать, что специальные формы и макросы не имеют отношения к семантике Лиспа?
(Reply) (Parent) (Thread)
[User Picture]From: grundik
2011-01-16 12:16 pm (UTC)
0. По-моему он просто сказал, что не понимает, зачем необходимо иметь два порядка вычислений в одном языке.
1. Я не вижу в этом серьёзного упрощения (плюс не забываем об обратной стороне, а именно о сложности компилятора). Более того, если решать со стороны receiver-а, то некоторые трюки перестают работать (это когда в процессе вычисления аргументов происходят сайд-эффекты). Ну то есть это другой язык получается уже.
2. Даже если согласиться с Кеем, из этого не следует, что сейчас Лисп сложнее Хаскеля в понимании.


PS: не сказать бы, что я не согласен с Кеем, вообще очень всё логично он говорит, но раз ты за него, то я буду против, да :)
(Reply) (Parent) (Thread)
[User Picture]From: thesz
2011-01-16 12:29 pm (UTC)
>Более того, если решать со стороны receiver-а, то некоторые трюки перестают работать (это когда в процессе вычисления аргументов происходят сайд-эффекты). Ну то есть это другой язык получается уже.

Прошу показать, как это получается.
(Reply) (Parent) (Thread)
[User Picture]From: grundik
2011-01-16 01:06 pm (UTC)
Псевдокод тупого примера:

функция A(x): записать x в файл Z, вернуть x
функция sum(): возвращает сумму аргументов

sum(A(5) + A(6) + A(7))

Когда у нас говорится, что порядок вычислений аппликативный, и что компилятор вычисляет слева-направо, то в файле получим "567".

Если A будет сама вычислять свои аргументы, то что мы получим в файле - хз, зависит от конкретной функции А.


То, что так делать нельзя из-за майнтенабилити - это вопрос совсем другой. Подобного рода "решения" я видел в реальности, в промышленном коде. На лиспе тоже видел (ну, на всяких лиспах, особенно на common lisp, говнокода написано немало, да).

Более хитрый пример можешь сам придумать :)
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
From: (Anonymous)
2011-01-16 03:41 pm (UTC)
> Вообще-то, он сказал, что упрощение Лиспа со всеми его макросами и специальными формами возможно за счёт изменения порядка вычислений на ленивый.

При всем уважении к Алану Кею - мало ли, что он сказал? Вот если бы он предоставил научную работу с семантикой lazy-lisp, из которой четко следует, что, ага, все стало проще - был бы другой разговор, а пока это только пустопорожний треп о том, что ему показалось. Да, пару спецформ можно было бы исключить, что упростило бы семантику, но это все. Семантика макросов в данном случае никак не упрощается, как и семантика оставшихся спецформ, зато вот некоторые вещи были бы очень веселыми. Например (let ...)-формы. В ряде диалектов let выражается через lambda, если биндинги в let обрабатываются лениво, то поведение формы будет совершенно алогичным, значит надо что? Правильно - вводить let-спецформой, отлично, хорошо, годно упростили семантику, спецформы не было - пришлось ввести, и это только один тривиальный пример.
(Reply) (Parent) (Thread)
[User Picture]From: thesz
2011-01-16 03:46 pm (UTC)
>Семантика макросов в данном случае никак не упрощается, как и семантика оставшихся спецформ, зато вот некоторые вещи были бы очень веселыми.

Дело в том, что в этом случае макросов, как таковых, и не было бы.

В той же Agda2 if определён, как функция:
-- подчёркиваниями обозначаются места для аргументов.
if_then_else_ : {A : Set} -> Bool -> a -> a -> a
if True t e = t
if False t e = e

Макрос строит выражение на основе выражения и окружения. Это отлично выражается в большей части случаев функциями высших порядков.
(Reply) (Parent) (Thread)
From: (Anonymous)
2011-01-16 04:09 pm (UTC)
if обычно определяется не как макрос, а как спецформа (или макрос над другой условной спецформой, не суть важно). if - это, вообще говоря, самый очевидный пример упрощения, но вот больше я так навскидку подобных примеров и не назову. Хотя тут все зависит от набора спецформ, конечно.
Макросы были бы, потому что семантика вычисления формы (f arg ...) где f - макрос не совпадает и не может совпадать с семантикой вычисления формы (f arg ...), где f - ленивая функция. Причем она не то что не совпадает, а принципиально отличается, дело в том, что макрос не строит выражение на основе окружения, в макросе выполняется вообще произвольный код. Который только должен _вернуть_ некое выражение.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
[User Picture]From: thesz
2011-01-16 03:47 pm (UTC)
И вдогонку.

Супротив высказывания grundik мнение Алана Кея пойдёт. Если бы сюда пришёл SPJ и сказал, что ленивый Лисп фигня (а он говорил про то, что "следующий Хаскель" будет энергичным), мне бы пришлось писать статью.
(Reply) (Parent) (Thread)
From: (Anonymous)
2011-01-16 04:38 pm (UTC)
Так операционную семантику хаскеля где-нибудь можно найти? А то можно было бы сравнить со схемой, например.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
[User Picture]From: thesz
2011-01-16 11:07 am (UTC)
>И последнее. Судя по всему, Кей говорит не про Common Lisp, а про какой-то другой лисп. Это тоже распространённый fail в спорах о лиспе, ибо лиспов дохренища, и между собой они заметно отличаются. И часто те недостатки, что есть в Common Lisp, отсутствуют, например, в scheme (или в Racket).

А вот теперь ты уводишь разговор в сторону.

Присутствует ли указанный Кеем недостаток в Scheme, CL и других известных тебе Лиспах? Присутствуют ли там макросы и специальные формы?
(Reply) (Parent) (Thread)
[User Picture]From: grundik
2011-01-16 12:09 pm (UTC)
Если честно, я вообще не понял, что конкретно не нравится Кею, кроме того, что по записи (qwe a b c) нельзя сказать, что такое qwe и когда будут вычисляться a, b и с - до передачи в qwe или после.

Макросы и спецформы есть в любом лиспе (ибо какой же лисп без них), однако Кей, по-моему, комплейнит не на их наличие, а на наличие "обычных" функций, аргументы которых вычисляются перед передачей в функцию. Ну то есть он комплейнит на аппликативный порядок вычислений.

Итого, отвечая на твой вопрос - ленивые лиспы существуют, да. Например, Lazy Racket. Судя по документации, реализовано как раз так, как спрашивает Кей.


Но вообще, конечно, можешь это моё замечание засчитать за демагогию/троллинг, ога. Но напомню, у меня там оно не одно.
(Reply) (Parent) (Thread)
From: (Anonymous)
2011-01-16 11:10 am (UTC)
То, что лисп мультипарадигменный - заблуждение, если только не считать способы декомпизиции (функциональная, объектная и т.д.) парадигмами, ну а тогда все языки мультипарадигменные. Парадигма там одна - императивное программирование. Декларативно в лиспе писать нельзя (нет, в теории можно встроить декларативный язык, но на практике никто так не делает и делать не будет, потому как все библиотеки императивные и вообще инфраструктура не способствует), а вот Хаскель поддерживает обе парадигмы.
(Reply) (Parent) (Thread)
[User Picture]From: grundik
2011-01-16 11:48 am (UTC)
Ээээ... На лиспе можно писать так, как хочется.
Декларативно - это как, по-вашему? Как в прологе? Lisa работает, я проверял.

Но в общем неважно. Важно, что лисп не функциональный язык.
(Reply) (Parent) (Thread)
From: (Anonymous)
2011-01-16 12:36 pm (UTC)
"Ээээ... На лиспе можно писать так, как хочется."
Ну понятно, настоящий коммунизм - сегодня в колбасе потребности нет, сегодня декларативно писать в лиспе не хочется.

Декларативность - это просто. Когда мы получаем один результат вне зависимости от пути редукции. В декларативном языке, например,
map f . map g == map (f . g)
В императивном - так может быть в зависимости от везения и фазы луны, но в общем случае, разумеется:
map f . map g != map (f . g)
Потому что f и g не функции и процедуры и могут изменять глобальные переменные, читать файлы, запускать межконтинентальные ракеты.

И, конечно, это не как в Прологе. Пролог - императивный, хоть и имеет декларативное подмножество. Но помимо этого красные каты, императивные как бы предикаты, да там можно из "базы знаний" викидывать и добавлять предикаты прямо во время выполнения - о какой декларативности вообще разговор.

"Важно, что лисп не функциональный язык."
Не всякий. Коммон лисп, конечно, не функциональный. А схема - функциональный, но императивный. Как СМЛ или, ха-ха, сишарп.
(Reply) (Parent) (Thread)
[User Picture]From: grundik
2011-01-16 01:26 pm (UTC)
Эммм... Зачем нужен софт, который ничего не делает? Ну то есть в файлы не пишет, ракеты не запускает? Это на тему "в колбасе потребности нет", ога.

По остальному комментировать не хочу, ибо жонглирование терминами таки не мой конёк.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
From: (Anonymous)
2011-01-16 03:57 pm (UTC)
> Декларативность - это просто. Когда мы получаем один результат вне зависимости от пути редукции. В декларативном языке, например,
map f . map g == map (f . g)

Если map и . чистые (что гарантируется исключительно реализацией языка, хоть в хаскеле, хоть в лиспе) то это равенство будет выполняться, при условии, что вычисления энергичны и порядок выполнения аргументов фиксирован. Например, в Common Lisp оно выполняется.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
[User Picture]From: love5an
2011-01-17 03:43 pm (UTC)
ой, блядь.
ну вот это такая хуйня, что я пройти мимо не могу.

Декларативность это когда для того, чтобы что-то получить мы описываем не процесс получения этого самого, а просто то, что, собственно, мы хотим получить.

Так вот макросы позволяют настолько декларативно писать, что никакие хаскели и рядом не лежали.

Кроме того, см. хотя бы в википедию на тему того, что такое "парадигма программирования" - http://en.wikipedia.org/wiki/Programming_paradigm
чтобы не нести больше такого бреда
(Reply) (Parent) (Thread)
From: (Anonymous)
2011-01-17 04:26 pm (UTC)
"ой, блядь.
ну вот это такая хуйня, что я пройти мимо не могу."

Дышите глубже, вы взволнованы.

"Декларативность это когда для того, чтобы что-то получить мы описываем не процесс получения этого самого, а просто то, что, собственно, мы хотим получить."

Забавно, и, наверное, годится для объяснения детям или введение в заблуждение менеджеров. Правда отдает какой-то схоластикой, дальше наверное следует переход к спору о терминах и о том, сколько ангелов помещается на кончике иглы. С тем определением, что я привел, конечно так не получится. Если мы принимаем, что декларативность - это независимость результата от порядка вычислений, то, например, имея теорему Черча-Россера сразу получаем что лямбда-исчисление (без расширений, например, мутабельными ячейками) декларативно. Флеймоемкость нулевая. А из вашего получится настоящий вечный огонь.

"Так вот макросы позволяют настолько декларативно писать, что никакие хаскели и рядом не лежали."

А, извините, не признал. Конечно, конечно. Лисп луччей! Не беспокойтесь, я с вами спорить не стану.
(Reply) (Parent) (Thread)
[User Picture]From: love5an
2011-01-17 06:13 pm (UTC)
Декларативность это независимость не только от порядка вычислений, но и от вида вычислений, от структур данных, в вычислениях используемых, и так далее. Это вообще независимость от вычислений.

Декларативная конструкция - описание, спецификация объекта предметной области.

Хаскель не декларативен. CL, в базовой форме - тоже. Но, в отличие от хаскеля, CL позволяет вводить декларативные конструкции, макросами. Хаскель же ограничен теми сущностями, которыми он оперирует. Типами, монадами, функциями, туплами, списками и так далее. Если подумать, хаскель намного более императивен, чем CL.

Лямбда-исчисление тоже дофига императивно. Описывает процесс вычислений потому что.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
From: (Anonymous)
2011-01-18 09:28 am (UTC)
> Если мы принимаем, что декларативность - это независимость результата от порядка вычислений, то, например, имея теорему Черча-Россера сразу получаем что лямбда-исчисление (без расширений, например, мутабельными ячейками) декларативно.

А если не принимаем, то не получаем. Поскольку общепринятому определению декларативности придуманное вами определение не соответствует, то я предпочту не принимать. А то так можно до чего угодно наприниматься, вот, например, если принять, что 5 - это 4, то 2*2=5. Отсюда и из аксиом арифметики сразу следует, что все числа равны нулю.
(Reply) (Parent) (Thread) (Expand)
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
(no subject) - (Anonymous) Expand
From: ext_55374
2011-01-17 06:01 pm (UTC)
> Так вот макросы позволяют настолько декларативно писать, что никакие хаскели и рядом не лежали.

Постановку задачи — может быть. Процесс решения — ну никак, нужна имперетивщина и explicit функциональщина.

Простейший пример: решение полиномиального уравнения с одной переменной. Декларативная постановка: «найти такой x, что x^10 - 2 * x ^ 7 + 4 = 0». И всё, тупик. Нужен солвер, который уже реализует перебор, деление пополам или метод Ньютона.

Толку с такой «декларативности без процесса», если это одна строчка, и не самая важная?
(Reply) (Parent) (Thread) (Expand)
[User Picture]From: love5an
2011-01-17 07:28 pm (UTC)
ну да, декларативность это не серебряная пуля
(Reply) (Parent) (Thread)
(no subject) - (Anonymous) Expand
(Deleted comment)