March 2026

S M T W T F S
12 34567
891011121314
151617 18192021
22232425262728
293031    

Style Credit

Expand Cut Tags

No cut tags
Thursday, May 5th, 2005 12:10 am
Левенчук пишет, что все серьёзные программисты мечтают программировать на фукнциональных языках. Не знаю, как серьёзные, а у меня лично никогда желания программировать на Лиспе не возникало. Нечеловеческий он какой-то. Пусть ворлоны на нём программируют.
Tags:
Friday, May 6th, 2005 04:11 pm (UTC)
> Я понял так: не хотели заставлять тех, кто не может.

вполне возможно, что кто-то и не мог.
факта явно осознанного предпочтения это не отменяет.

> тому же OCaml по сараю

а кто говорит про, прости оссподи, O'Caml?

> Так я вообще не понимаю, об что мы таки спорим

а мы не то чтобы и спорим.  просто я пытаюсь пояснить тебе явную неуместность мелкого сектантского миссионерства в данном контексте.  плюс по поводу данной конкретной темы слегка наболело: откуда, по-твоему, у человека ¨знания¨ о лиспе на уровне ¨всюду списки, рекурсия и скобочки¨?  от таких вот умников, которые вместо того чтобы рассказать что-нибудь существенное, с блеском в глазах гонят телеги про хвостовую рекурсию и прочую откровенную (для девственной аудитории) эзотерику.
Friday, May 6th, 2005 04:51 pm (UTC)
вот отличный (а также модерновый и практический, что приятно) текст:
http://www.gigamonkeys.com/book/
Friday, May 6th, 2005 05:02 pm (UTC)
да, и ещё, дабы мне не ощущать себя в настолько идиоцком положении: моей целью в данном треде не являлось кому-либо что-либо продать или кого-либо в чём-либо убедить и направить на путь истинный.
миссионерства я зело не люблю, и считаю что покуда человека изнутри не припекло, морочить ему голову совершенно не нужно и даже бесполезно.
так, зашёл на огонёк, указал на фактические ошибки в посте, а тут ксендзы подтянулись... :)
Friday, May 6th, 2005 05:12 pm (UTC)
Основная идея Лиспа в том, что списки одновременно являются и абстрактным синтаксическим деревом самого Лиспа - то есть, программа по сути неотличима от данных.

Это позволяет нам расширять язык, используя функции, выполняющиеся во время компиляции - то есть, макры.

К примеру, если мы хотим ввести в язык новую конструкцию
APPRIGHT, такую, что код

(APPRIGHT + 1 2 3 4 5) будет компилироваться как
(+ 1 (+ 2 (+ 3 (+ 4 5)))), то мы просто говорим:

(defmacro appright (f &rest args)
(if (null (cdr args)) `(car args)
`(,f ,(car args) (appright ,f ,@(cdr args)))
))

То есть - мы расширяем сам *компилятор* языка. Не нравятся скобочки? Можем заменить синтаксис - см. мою статью, там, правда, Схема, но это без разницы, если кому интересно, дам то же самое для CL.
Friday, May 6th, 2005 07:36 pm (UTC)
В какой статье? Покажи плз пример замены синтаксиса для лиспа.
Friday, May 6th, 2005 10:55 pm (UTC)
В этом треде уже давал ссылку.

Пример (действующий) - http://dslengine.sourceforge.net/
Friday, May 6th, 2005 11:03 pm (UTC)
> через его синтаксис надо продираться.

Не надо. У Лиспа - минимальный синтаксис. S-выражения. Это, с одной стороны, плохо - человекам, или некоторым из них, сложно воспринимать S-выражения или
тот же XML, но с другой стороны это замечательно, потому как синтаксис совпадает с AST языка. Мы видим ровно то, что у него внутри, уже распарсенное.

> Ну, так почему не поменяли, а?

Да поменяли - к примеру, RLisp, весьма известная фишка... Просто это никому не надо - синтаксис S-выражений, на самом деле, близок к идеальному. Это я утверждаю, как полиглот, программировавший практически на всех языках, какие только когда либо существовали, и собственноручно реализовавший множество языков под разные цели. Да, синтаксис того же Хаскелля может завораживать, казаться немерянно удобочитаемым и красивым, синтаксис Java может быть привычным, но по сумме критериев S-выражения лидируют.

> Почему вы не написали тот же appright в более человекопонятной форме?

Потому как тогда там или пришлось бы splice-образную семантику неявно использовать, или явно прописать генерацию S-выражений, что затруднило бы понимаение. Когда и макра, и исходный код, и результат - в одном синтаксисе, понять, что происходит, несколько проще.

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

Не только разбор. Ещё и все этапы компиляции и оптимизации. Изменять (не только расширять, но и ограничивать) можно абсолютно всё.

> И что среда исполнения Лисп включает в себя компилятор и исполнитель кода (что, понятно, не есть уникальное свойство Лиспа).

Не совсем так. Компилятор Лиспа включает в себя среду исполнения. Обратное не обязательно (ну да, есть любители попользовать eval, но я не из их числа).
Friday, May 6th, 2005 11:34 pm (UTC)
> Если язык Лисп-VM не скрывает сложности этой самой VM, так ли это хорошо?

Поскольку существенная часть Лисп-программы - это код, который читает Лисп-программы и пишет Лисп-программы, то однозначность отображения синтаксиса на AST тут весьма полезна.

> Или вы скажете, что существует синтаксис, идеальный для описания - чего угодно?

Существует синтаксис, *достаточный* для описания чего угодно. Это - S-выражения. Аналог, ужасно громоздкий и нелепый, но столь же универсальный - XML. Не знаю, на фига XML придумали, когда были S-выражения, ну да ладно...

При этом, такой синтаксис относительно легко воспринимается человеком - он вполне естественный, и, что немаловажно, примитивный, его легко изучить и легко читать.

> А какие, опять же, критерии-то?

- Универсальность - не должно быть конструкций, принципиально невыразимых в этом синтаксисе, и не должно быть конструкций, которые было бы сложно отобразить на такой синтаксис.

- Ортогональность. Не должно быть взаимозаменяемых элементов.

- Минимальность. Лишние элементы только отвлекают.

- Возможности для редактора или IDE проявить немерянный интеллект. Для S-выражений их - полно, для сложных синтаксисов - приходится bovinator-ы всякие рисовать - кошмар...

- Однозначность отображения на внутреннее представление. S-выражения тривиально переводятся в двоичные деревья, и наоборот.


Sunday, May 8th, 2005 08:33 am (UTC)
> Человеком XML воспринимается проще, мне кажется.

человеком с привычкой к HTML'ю, натурально.

были уже, кстати, полушуточные предложения заменить в Лиспе круглые скобочки на угольные, типа вот так:

<+ 1 <* 3 4/>/>

<смайлик direction="left" nosy="false"/>

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 09:20 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 10:31 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 11:11 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 11:22 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 11:42 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 12:23 pm (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-10 05:48 pm (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-10 06:29 pm (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-09 06:46 pm (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-10 10:09 am (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-10 11:33 am (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-09 06:44 pm (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 11:19 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-08 11:32 am (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-09 06:41 pm (UTC) - Expand

(no subject)

[identity profile] mauhuur.livejournal.com - 2005-05-10 11:26 am (UTC) - Expand

(no subject)

[identity profile] cmm.livejournal.com - 2005-05-10 05:11 pm (UTC) - Expand
Friday, May 6th, 2005 11:05 pm (UTC)
Похоже, опечатка где-то, не проверял, когда писал. Гарантированно работает вот это:

(defmacro appright (fn &rest args) (if (null (cdr args)) (car args) `(,fn ,(car args) (appright ,fn ,@(cdr args)))))
Friday, May 6th, 2005 05:02 pm (UTC)
Блин. Тема такая - Лисп - ни разу не функциональный язык, и в Лиспе нельзя не пользоваться императивными возможностями. Это - ответ на вопрос тов. stas-а. Предложение не пугать человека хвостовыми рекурсиями выглядит в этом контексте, мягко гойворя, странным.
Friday, May 6th, 2005 05:15 pm (UTC)
> Лисп - ни разу не функциональный язык

угу.

> в Лиспе нельзя не пользоваться императивными возможностями

а каким боком циклы обязательно "императивны", не подскажешь?
(то есть про необходимость как-то ¨деструктивно¨ апдейтить переменные, в которых сидит loop state, я вполне понимаю.  но считать на данном основании любой цикл императивным — чистой воды академическое крючкотворство, и ты это, надеюсь, прекрасно понимаешь.  если подходить с подобной логикой, то функциональных языков вообще в природе нету, поскольку всё в конце концов превращается в ни разу не функциональный Мойшинный Кодъ).

> Предложение не пугать человека хвостовыми рекурсиями выглядит в этом контексте, мягко гойворя, странным

и пойчему?  показывать собственную образованность — это одно, а пытаться что-то действительно объяснить (в смысле так чтобы поняли и не ушли в несущественные дебри) — другое.
Friday, May 6th, 2005 05:21 pm (UTC)
> а каким боком циклы обязательно "императивны", не подскажешь?

Таким, что неимперативный цикл сводится к хвостовой рекурсии.

> но считать на данном основании любой цикл императивным — чистой воды академическое крючкотворство, и ты это, надеюсь, прекрасно понимаешь.

Это крючкотворство абсолютно необходимо, когда ты пишешь компиляторы. Практика требует. Есть в конструкции сайд-эффект - теряем сразу огромное количество возможностей статического анализа и оптимизаций, нет сайд-эффектов - делаем с ней всё, что угодно.

> если подходить с подобной логикой, то функциональных языков вообще в природе нету, поскольку всё в конце концов превращается в ни разу не функциональный Мойшинный Кодъ).

Зависит от того, на каком этапе компиляции эта неиллюзорная мойшинная императивность вылезает. Разница чисто практическая, в удобстве анализа и оптимизации.
Friday, May 6th, 2005 05:30 pm (UTC)
> Это крючкотворство абсолютно необходимо, когда ты пишешь компиляторы

что является типичным времяпровождением любого практикующего программиста, не так ли?
Friday, May 6th, 2005 05:42 pm (UTC)
В идеале так и должно быть.

Каждая большая задача лучше всего решается именно таким образом: придумывается язык, заточенный под предметную область этой задачи, пишетя абы какая его реализация, задача в пол-пинка решается, заказчик почти-доволен, пишем эффективную реализацию языка.

Интересно, что ты считаешь за среднестатическое промышленное программирование?
Friday, May 6th, 2005 05:56 pm (UTC)
ОК, тупик, пора хорошенько определиться с терминами.
тут надо с 17-го году начинать, видимо.
накатаю отдельный пост, вот только ребёнка спать отложу...
Friday, May 6th, 2005 10:25 pm (UTC)
хотя ладно, в общих чертах укладывается в коммент (или пару).

> Каждая большая задача лучше всего решается именно таким образом: придумывается язык, заточенный под предметную область этой задачи

исходя из моего опыта, могу сказать что дело выглядит так: для большой задачи выдумывается подходящая ей нотация.  я не употребляю здесь слово "язык" намеренно, поскольку термин это нагруженный и будящий ассоциации с "Тьюринг-полнотой".  каковой полноты во всех выдуманных за мою карьеру lisp-based "little languages" не наблюдалось и в помине.  соответственно, никакой нетривиальной компиляции тоже не требовалось.  что и правильно, поскольку language design & implementation есть дело тонкое, сурьёзное и чрезвычайно трудоёмкое (ага, придумал язык, не преобразующийся тривиально в CL, а требующий компиляции с интерпретацией?  молодец!  а как насчёт отладчик к нему написать?  а профилятор не хотите ли?  ну, понятно), и к вящей радости CL позволяет до этого не доводить.

теперь по поводу моей несколько, видимо, странно выглядящей бурной реакции на твой первый коммент.  дело в том, что ты ухитрился нажать сразу на несколько моих любимых кнопочек (либо мне показалось, что ты это сделал, тады типа извини).

напоминаю: ты заявил, что отсутствие хвостовой рекурсии является "бядой" CL.  в данной коротенькой фразе содержится следующий комплект раздражающих утверждений:

1. функциональное программирование — это хорошо, а если совсем функционально нельзя, то это плохо.

2. (в контексте разговора с человеком, ничего ни про Лисп, ни про функциональное программирование, окроме общепринятого мудового фольклора, не знающем) CL говно, потому что не гарантирует хвостовую рекурсию.

3. автор утверждения — академик.

тему номер 3 я развивать здесь далее не намерен, с твоего позволения; она большая слишком и отдельная.

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

номер 1 требует небольшого экскурса в суть.  функциональное программирование продаётся как хорошая вещь, поскольку сильно ограничивает возможности программиста пальнуть себе в ногу.  именно продаётся: недаром при этом используются качественные определения типа "pure functional".  pure — это ведь так хорошо!  а impure — уже не так хорошо, правда ведь?

тогда как на деле ФП — это всего лишь один из способов увести программирование в сторону декларативности и (как следствие) простоты.  есть и другие способы упростить нотацию, которые не требуют обязательного отказа от side effects (как это по-русски, а?).  более того, во многих случаях нарочитый отказ от этих самых side effects лишь запутывает логику программы, ибо в т.н. "реальной жизни" большинство программ не высчитывают результаты волосатых математических формул, а манипулируют разного рода сохраняемую информацию: т.е. смысл их существования и ядро их логики — это именно эти вот самые side effects.

взамен незамутнённому практикой функциональному программированию CL предлагает нечто куда более ценное: возможность структурировать эти самые неизбежные в т.н. "реальной жизни" side effects посредством протоколов и возможность создавать специализированную декларативную нотацию для конкретных задач посредством макросов.  ценность CL именно в том и состоит, что я не должен выгибать логику программы в сторону чистого ФП, или в сторону чистого predicate calculus типа как в Прологе, или в сторону message-passing "OOP" типа как в Смолтоке и Жабе, или в сторону total fucking nightmarish brain damage как в C++.
Friday, May 6th, 2005 11:20 pm (UTC)
Увы, увы... Компилятор CL - могуч, но иногда надо создавать языки с настолько далёкой от него семантикой, что приходится отдельные элементы компилятора переделывать самостоятельно. Отсюда и моя нежная любовь ко всем тем свойствам языка, которые способствуют удобству оптимизации.

По поводу 1) - этого я нигде не утверждал. ФП - лишь одна из семантик, применимая далеко не для каждой предметной области.

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

3) С какой это радости? Вот уж кем я себя никогда не считал. Даже когда я работал в науке, это было чисто индустриальное программирование - в экспериментальной физике высоких энергий и в феноменологии как-то нет смысла заниматься академическим computer science, задачи там сугубо практические и крайне суровые. Сейчас же я и вовсе в абсолютно коммерческой индустрии работаю. С академическим computer science сильно не дружу, во многом по тем же причинам, что и Пол Грэхем - уж больно они все подвинулись на типах...

> есть и другие способы упростить нотацию, которые не требуют обязательного отказа от side effects (как это по-русски, а?).

Советую не забывать и про удобство для статического анализа кода - иногда это - фатальное требование. Отследить сайд-эффекты (никогда не знал русского аналога!) автоматом - лучше сразу застрелиться... Dataflow-analisys - задача дико нетривиальная и ресурсоёмкая.

> т.е. смысл их существования и ядро их логики — это именно эти вот самые side effects.

Часто есть смысл отказаться от рассмотрения предметной области в столь низкоуровневых терминах, как какие-то там хранилища данных и транзакции над ними. Логика процессов в реальном мире декларативна. Естественно, я не призываю заворачивать ввод-вывод в монады, и радоваться, какое всё чистенькое-функциональненькое - пусть оно на низком уровне остаётся понятным и императивным. На уровне описания логики лучше обходиться без императивных конструкций - там они становятся неестественными.

С последним абзацем - абсолютно согласен. У меня вообще поверх CL иногда дикая каша получается - ленивый функциональный язык для написания макр (ну удобно компиляторы писать на таких языках, там никакого I/O, сплошной pattern matching), целевой язык - нечто фортообразное и отдельно прологообразное, с оптимизирующей компиляцией (всё - на уровне макр) в тот же Common Lisp и SQL.

Ещё смешнее, что я сейчас достраиваю аналогичную систему поверх Java. Благо, динамически генерять код там легко, а интерпретатор ленивой функциональщины в пол-пинка делается. И стала Жаба в результате неотличима от Common Lisp-а, он получается одним из промежуточных языков...