Левенчук пишет, что все серьёзные программисты мечтают программировать на фукнциональных языках. Не знаю, как серьёзные, а у меня лично никогда желания программировать на Лиспе не возникало. Нечеловеческий он какой-то. Пусть ворлоны на нём программируют.
Tags:
Re: ага, а вот и флейм!
создатели стандарта безусловно знали о хвостовой рекурсии, и не стандартизивовали её сознательно. не потому что не могли, а потому что не хотели.
по крайней мере я склонен интерпретировать публичные высказывания того же Кента Питмана на данную тему именно таким образом (и несложный поиск на Google Groups с соответствующими ключевыми словами мне свидетель).
если есть свидетельства обратного, то давай их сюда.
> практически все *вменяемые* компиляторы CL таки хвостовые рекурсии разворачивают
и правильно делают, ибо это вполне приятная и недорогая для компилятора оптимизация. но заметь также, что ни один *вменяемый* компилятор не производит этой оптимизации когда (> debug optimize), что характерно.
> в силу этого, ФУНКЦИОНАЛЬНО писать на CL - тоже нельзя (да и на фиг не надо)
золотые слова, в скобочках-то!
Re: ага, а вот и флейм!
Я понял так: не хотели заставлять тех, кто не может. То есть, сочли это не обязательным требованием. Откуда и вышеизложенные выводы.
> но заметь также, что ни один *вменяемый* компилятор не производит этой оптимизации когда (> debug optimize), что характерно.
Да нет, тому же OCaml по сараю, он всегда развернёт.
> золотые слова, в скобочках-то!
Так я вообще не понимаю, об что мы таки спорим. Лисп - не функциональный язык, на Лиспе и нельзя писать чисто функционально, да и не для того он нужен, чтоб чисто функционально писать. С этими утверждениями тут хоть кто-то не согласен?!?
Re: ага, а вот и флейм!
вполне возможно, что кто-то и не мог.
факта явно осознанного предпочтения это не отменяет.
> тому же OCaml по сараю
а кто говорит про, прости оссподи, O'Caml?
> Так я вообще не понимаю, об что мы таки спорим
а мы не то чтобы и спорим. просто я пытаюсь пояснить тебе явную неуместность мелкого сектантского миссионерства в данном контексте. плюс по поводу данной конкретной темы слегка наболело: откуда, по-твоему, у человека ¨знания¨ о лиспе на уровне ¨всюду списки, рекурсия и скобочки¨? от таких вот умников, которые вместо того чтобы рассказать что-нибудь существенное, с блеском в глазах гонят телеги про хвостовую рекурсию и прочую откровенную (для девственной аудитории) эзотерику.
no subject
Лисп в вышеуказанном тексте можно заменить на любой извод Лиспа или любою производную его типа Схемы, по желанию.
no subject
http://www.gigamonkeys.com/book/
no subject
миссионерства я зело не люблю, и считаю что покуда человека изнутри не припекло, морочить ему голову совершенно не нужно и даже бесполезно.
так, зашёл на огонёк, указал на фактические ошибки в посте, а тут ксендзы подтянулись... :)
no subject
Это позволяет нам расширять язык, используя функции, выполняющиеся во время компиляции - то есть, макры.
К примеру, если мы хотим ввести в язык новую конструкцию
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.
no subject
no subject
Пример (действующий) - http://dslengine.sourceforge.net/
no subject
Ну, я примерно так себе и представлял дело, хотя меня тут разубеждают, что это совсем не так. ;)
то мы просто говорим:
Вот слово "просто" меня тут немного смущает. Т.е. я понимаю, что для вас, судя по всему - человека, который на этом деле собаку сьел - это просто. Но для меня, например, это не очень просто. Это, в частности, то, что мне в Лиспе изрядно мешает - через его синтаксис надо продираться. Вы, конечно, можете сказать, что это от недостатка опыта. Возможно, и так. И скажете, что это всё можно поменять как угодно - статью я прочитал, да. Ну, так почему не поменяли, а? Почему вы не написали тот же appright в более человекопонятной форме?
Но в целом, мне кажется, я уловил вашу мысль - что в Лиспе правила, по которым ведётся разбор выражений на языке, поддаются модификации. Вернее, думаю, всё же расширению? Или полной модификации? И что среда исполнения Лисп включает в себя компилятор и исполнитель кода (что, понятно, не есть уникальное свойство Лиспа).
no subject
Не надо. У Лиспа - минимальный синтаксис. S-выражения. Это, с одной стороны, плохо - человекам, или некоторым из них, сложно воспринимать S-выражения или
тот же XML, но с другой стороны это замечательно, потому как синтаксис совпадает с AST языка. Мы видим ровно то, что у него внутри, уже распарсенное.
> Ну, так почему не поменяли, а?
Да поменяли - к примеру, RLisp, весьма известная фишка... Просто это никому не надо - синтаксис S-выражений, на самом деле, близок к идеальному. Это я утверждаю, как полиглот, программировавший практически на всех языках, какие только когда либо существовали, и собственноручно реализовавший множество языков под разные цели. Да, синтаксис того же Хаскелля может завораживать, казаться немерянно удобочитаемым и красивым, синтаксис Java может быть привычным, но по сумме критериев S-выражения лидируют.
> Почему вы не написали тот же appright в более человекопонятной форме?
Потому как тогда там или пришлось бы splice-образную семантику неявно использовать, или явно прописать генерацию S-выражений, что затруднило бы понимаение. Когда и макра, и исходный код, и результат - в одном синтаксисе, понять, что происходит, несколько проще.
> Но в целом, мне кажется, я уловил вашу мысль - что в Лиспе правила, по которым ведётся разбор выражений на языке, поддаются модификации. Вернее, думаю, всё же расширению?
Не только разбор. Ещё и все этапы компиляции и оптимизации. Изменять (не только расширять, но и ограничивать) можно абсолютно всё.
> И что среда исполнения Лисп включает в себя компилятор и исполнитель кода (что, понятно, не есть уникальное свойство Лиспа).
Не совсем так. Компилятор Лиспа включает в себя среду исполнения. Обратное не обязательно (ну да, есть любители попользовать eval, но я не из их числа).
no subject
По-моему, это получается таки плохо. Что есть язык программирования? Способ сокрытия сложности задачи/решения (кривой перевод complexity encapsulation, ага). Если язык Лисп-VM не скрывает сложности этой самой VM, так ли это хорошо? Т.е. у ассемблера есть свои многочисленные прелести, но есть также и вышеописаный существенный недостаток.
синтаксис S-выражений, на самом деле, близок к идеальному
Идеальному - для чего? Или вы скажете, что существует синтаксис, идеальный для описания - чего угодно?
но по сумме критериев S-выражения лидируют.
А какие, опять же, критерии-то?
no subject
Поскольку существенная часть Лисп-программы - это код, который читает Лисп-программы и пишет Лисп-программы, то однозначность отображения синтаксиса на AST тут весьма полезна.
> Или вы скажете, что существует синтаксис, идеальный для описания - чего угодно?
Существует синтаксис, *достаточный* для описания чего угодно. Это - S-выражения. Аналог, ужасно громоздкий и нелепый, но столь же универсальный - XML. Не знаю, на фига XML придумали, когда были S-выражения, ну да ладно...
При этом, такой синтаксис относительно легко воспринимается человеком - он вполне естественный, и, что немаловажно, примитивный, его легко изучить и легко читать.
> А какие, опять же, критерии-то?
- Универсальность - не должно быть конструкций, принципиально невыразимых в этом синтаксисе, и не должно быть конструкций, которые было бы сложно отобразить на такой синтаксис.
- Ортогональность. Не должно быть взаимозаменяемых элементов.
- Минимальность. Лишние элементы только отвлекают.
- Возможности для редактора или IDE проявить немерянный интеллект. Для S-выражений их - полно, для сложных синтаксисов - приходится bovinator-ы всякие рисовать - кошмар...
- Однозначность отображения на внутреннее представление. S-выражения тривиально переводятся в двоичные деревья, и наоборот.
no subject
Ну, с этим я могу согласиться.
Не знаю, на фига XML придумали, когда были S-выражения, ну да ладно...
Человеком XML воспринимается проще, мне кажется.
он вполне естественный, и, что немаловажно, примитивный, его легко изучить и легко читать.
Очевидно, дело привычки, хотя выражения вида (+ 1 (* 3 4)) мне не кажутся естественными.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
CL-USER(4): (APPRIGHT + 1 2 3 4 5)
Error: Attempt to take the value of the unbound variable `ARGS'.
[condition type: UNBOUND-VARIABLE]
Софт - Allegro CL.
no subject
(defmacro appright (fn &rest args) (if (null (cdr args)) (car args) `(,fn ,(car args) (appright ,fn ,@(cdr args)))))
no subject
no subject
Re: ага, а вот и флейм!
опять об тоже место
угу.
> в Лиспе нельзя не пользоваться императивными возможностями
а каким боком циклы обязательно "императивны", не подскажешь?
(то есть про необходимость как-то ¨деструктивно¨ апдейтить переменные, в которых сидит loop state, я вполне понимаю. но считать на данном основании любой цикл императивным — чистой воды академическое крючкотворство, и ты это, надеюсь, прекрасно понимаешь. если подходить с подобной логикой, то функциональных языков вообще в природе нету, поскольку всё в конце концов превращается в ни разу не функциональный Мойшинный Кодъ).
> Предложение не пугать человека хвостовыми рекурсиями выглядит в этом контексте, мягко гойворя, странным
и пойчему? показывать собственную образованность — это одно, а пытаться что-то действительно объяснить (в смысле так чтобы поняли и не ушли в несущественные дебри) — другое.
Re: опять об тоже место
Таким, что неимперативный цикл сводится к хвостовой рекурсии.
> но считать на данном основании любой цикл императивным — чистой воды академическое крючкотворство, и ты это, надеюсь, прекрасно понимаешь.
Это крючкотворство абсолютно необходимо, когда ты пишешь компиляторы. Практика требует. Есть в конструкции сайд-эффект - теряем сразу огромное количество возможностей статического анализа и оптимизаций, нет сайд-эффектов - делаем с ней всё, что угодно.
> если подходить с подобной логикой, то функциональных языков вообще в природе нету, поскольку всё в конце концов превращается в ни разу не функциональный Мойшинный Кодъ).
Зависит от того, на каком этапе компиляции эта неиллюзорная мойшинная императивность вылезает. Разница чисто практическая, в удобстве анализа и оптимизации.
Re: опять об тоже место
что является типичным времяпровождением любого практикующего программиста, не так ли?
Re: опять об тоже место
Каждая большая задача лучше всего решается именно таким образом: придумывается язык, заточенный под предметную область этой задачи, пишетя абы какая его реализация, задача в пол-пинка решается, заказчик почти-доволен, пишем эффективную реализацию языка.
Интересно, что ты считаешь за среднестатическое промышленное программирование?
Re: опять об тоже место
тут надо с 17-го году начинать, видимо.
накатаю отдельный пост, вот только ребёнка спать отложу...
Re: опять об тоже место
> Каждая большая задача лучше всего решается именно таким образом: придумывается язык, заточенный под предметную область этой задачи
исходя из моего опыта, могу сказать что дело выглядит так: для большой задачи выдумывается подходящая ей нотация. я не употребляю здесь слово "язык" намеренно, поскольку термин это нагруженный и будящий ассоциации с "Тьюринг-полнотой". каковой полноты во всех выдуманных за мою карьеру 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++.
Re: опять об тоже место