Pull to refresh

Comments 241

Нет, спасибо.
Функционального программирования мне, пожалуй, хватило еще при обучении.
Не слабак, я же предмет осилил и сдал. Более того, еще немного потом пописал «для фана» на лиспе несколько несложных программ.
Просто если постоянно не пишешь на нем, то вникнуть очень сложно и занимает много времени.
Это примерно как некоторые считают перл write only языком.
LISP — мультипарадигменный язык, код на нем обычно не более функциональный чем на python или ruby.
Несмотря на его мультипарадигмальность, мне кажется, что он все-таки более располагает к функциональному стилю, чем те же Ruby и Python.
Наверное можно сказать, что они движутся к одному и тому же идеалу ЯП, но с разных сторон :)
об этом еще Пол Грехем писал
Вас ему обучали в универе а вы еще жалуетесь))
UFO just landed and posted this here
вы просто не любите скобки
UFO just landed and posted this here
Любите ли вы скобки так, как люблю их я?
(любой Ъ-ли(пер)
вы закрывающую скобку пропустили, у вас не компилируется.
вы скобочку пропустили
У вас слишком много скобок. Вернее, так: больше уже не поставить.
Если есть цель — можно что угодно:-D например нормальный такой кодЕц
{{{{{{{}}}}}{}}}{}{}{}{}{}
UFO just landed and posted this here
UFO just landed and posted this here
lisp хорош для программирования экспертных систем. а php хорош для веб-программирования.
хотя можно и все сделать наоборот, конечно… при желании.

очевидно (!), правильно оформленный код на php — вовсе не уродлив, ибо выглядит так как и любой язык с Си-подобным синтаксисом. и очевидно код на php проще читается, что является преимуществом при обычных условиях.

все это отлично понятно любому профессиональному и образованному программисту, поэтому ваши реплики были восприняты как неуместные. так что все очень логично.

а ваше уебищное «похапэ» маркирует вас как подростка с больным самолюбием и ничто меня уже давно так не удивляло как то, что у вас карма <100!!!

в кои-то веки зашел на хабр с ощущением ностальгии и тут же затошнило. спасибо, чувак.

UFO just landed and posted this here
Извини, Григорий, очень уж неприятно читать было.
UFO just landed and posted this here
Георгий, почему неприятно читать «бложеке похапэ погромистов» — понятно, а вот почему у тебе неприятно читать php код — это за пределами адекватного понимания.
UFO just landed and posted this here
основной критерий (был, есть и будет) — логика.
узнай(те) об этом побольше…

UFO just landed and posted this here
вот только гуманитарий, нахватавшись терминов, может такое предложить — с каких это пор исследование аргументации в естесственном языке делается формальной логикой?

для этого, товарищ непохапэ-настоящий-программист, используется сама логика, как наука о правильном мышлении, а не ее формализмы.

и, вообще, ану-ка без ану-ка.
UFO just landed and posted this here
древние греки бросаются, а не я.
вы просто безграмотны.
UFO just landed and posted this here
этим и заканчивая) банальной опечаткой.
и прекратите коверкать слово гуманитарность.
че это: «Это ж что ж такое же. Он никак не уймётся. habrahabr.ru/blogs/webdev/104349/#comment_3258437 juick.com/936041 (сегодня в 14:02)»
???

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

малыш, уймись лучше ты. сморозил зуйню — признай и иди дальше, а минусы ничего никогда не изменят.

увлечение модными штучками — удел гико-педерастов. только они не в состоянии понять для чего нужны lisp, scala и почему php — хороший язык, а его код вовсе не уродлив.

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

dixi. (от**бись с латыни).

UFO just landed and posted this here
Возможно, вам попался действительно плохой код))
lisp хорош для программирования экспертных систем

Бука ты. Лиспоеды, читающие тред, померли со смеху.

очевидно (!), правильно оформленный код на php — вовсе не уродлив

Пример правильно оформленного кода на пхп можно посмотреть? А то от поеботы в жумле блевать тянет, например.

ибо выглядит так как и любой язык с Си-подобным синтаксисом.

В пыхе сишнообразный синтаксис? А как же классы, implicit declarations,etc.?
я был так лаконичен в надежде на адекватную реакцию сообщества, но видимо, к моему ужасу, грамотных людей среди комментаторов совсем немного.

итак, я отвечаю:

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

следующая прописная истина, которую вы тоже ухитрились не знать и даже удивляться — это тот факт что php имеет си-подобный синтаксис — у меня нет слов, так что опять же читайте вики, просто блин статью «php» хотя бы.

что гораздо хуже — удивляясь си-шному синтаксису в php (о, боги!..), вы ухитрились:

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

б) спутать Си и Си++ — потребовав классы, как доказательство Си-подобного синтаксиса!

Далее, все языки с си-подобным синтаксисом читаются одинаково (легко).
Поймите (же наконец!), мы говорим не о содержании программы (плохой/хороший код, джумла отстой и т.п.), а о читабельности — ясности разделения областей видимости, объявления блоков и циклов, использования операторов, условных переходов и т.д.
В конечном итоге о легкости реверс-инжениринга алгоритма по имеющемуся коду.
И глупо спорить, что php тут даст lisp-у сто очков форы. ибо он даже легче читается чем бейсик, не то что си или си++ или не дай бог lisp или, скажем, perl.

ну че спорить? потроллить?

Интересно, хоть один человек когда-нибудь сможет объективно и с обоснованием оценить читаемость языков. А то всё «глупо спорить» да «не дай бог».
строгой теории нет, но некоторые метрики кода позволяют делать косвенные выводы. кроме того, для личного понимания рекомендую книгу «анализ программного кода», где автор детально разбирает процесс чтения чужого кода и методы работы с ним.
Благодарю. Было бы неплохо, если бы вы и в комментариях воздержались от необоснованных выводов. Например, я знаю десятки людей, которые совершенно не считают C-подобный синтаксис читаемым, и только один из них лиспер :) Это субъективный критерий (точнее просто статистика), но её достаточно, чтобы опровергнуть ваши выводы. Но не достаточно, чтобы сделать свои.
и где у меня необоснованный вывод? если я пропустил строгий вывод утвеждения (ну не каждое же слово обосновывать?) — это не значит что аргументация отсутствует вообще.
но самые очевидные моменты можно и так обосновать — чем ближе синтаксис языка к естественным языкам, тем легче он читается человеком. поэтому бейсик учат в школе, поэтому perl нечитабелен, и поэтому составлять sql-запросы можно научится очень быстро.
именно поэтому классический набор ключевых слов if, then, else, while, for… и т.д. + скобки для областей видимости — это и есть золотая середина си-подобного синтаксиса.
Чем ближе синтаксис ЯП к естественным языкам, тем легче его будет осилить человеку, который ни на чём никогда не писал. На читаемость кода для человека опытного в данном языке его близость к естественным никакого влияния не оказывает.

И насчёт нечеловеческости перла: www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html :)
ну да. так логично звучит, и при этом абсолютно неверно. )

я бы рассказал вам как язык формирует мышление, но мне здесь уже просто неприятно вести дискуссию.
Про то как язык формирует мышление я читал. Только скажите, для вас тоже (как и для тов. tenshi) язык ограничивается синтаксисом?
ну что за провокация? ) конечно нет.
как он может ограничится? должна быть определена и грамматика, и синтаксис, и сама семантика.

Прошу прощения, просто до сих пор не могу забыть высказывание одного товарища: «сравнивая язык, мы сравниваем синтаксис». Да и tenshi здесь, похоже, с ним согласен.
согласитесь ли вы что функциональные языки располагают к использованию рекурсивных структур?
этим, они близки математическому представлению алгоритмов, и наверное отчасти отсюда и выразительная мощь.
но ведь потому-то нас и учили везде где возможно заменять рекурсию циклом, что мозг испытывает затруднения при анализе таких участков кода? проще говоря — для читабельности)
Да. В чисто функциональном языке цикл невозможен. Рекурсия плоха тем, что человек так не думает. Человек думает итеративно и процедурно. Проще понять код, который работает так, как человек привык думать.

А теперь два но.
1. Common Lisp — не функциональный. Даже в Scheme есть циклы, а в Common Lisp так и целый DSL — макрос LOOP. Я ни разу не видел рекурсию в боевом коде на Common Lisp.
2. Человеку проще понять итеративный алгоритм, чем рекурсивный, но ему (после небольшой, порядка часов, практики) абсолютно без разницы в каком виде (с каким синтаксисом) этот алгоритм записан.
боевой это прикладной? конечно, ведь программистам надо будет это поддерживать и они идут, фактически, против самой парадигмы языка (где даже нет нативного синтаксиса для циклов!), чтобы применять его в реальных приложениях.
не совсем нормальная ситуация для веба, где нужно много относительно простых (алгоритмически) программ.

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

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

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

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

LOOP есть в стандарте, оптимизации хвостовых вызовов (хвостовой рекурсии) — нет. Т.е. по стандарту рекурсию в Common Lisp использовать нельзя.

> со стороны семантики обширное использование рекурсивных определений

Первый раз слышу, где почитать подробнее?

> вот вам и логическое обоснование, вполне стройное,

Рано делать выводы. :P Ещё есть неточности.
Прошу прощения если чем-то испугал. Поясню.

Процесс разбора кода на лиспе делится не на лексический, синтаксический, и семантический анализаторы, а на:
1. Программируемый ридер (функция read, примерно соответствует лексеру и части парсера)
2. Программируемый macro-expander (функция macroexpand, соответствует остатку парсера)
3. eval (выполняет функции семантического анализатора, кодогенератора, и ещё чего угодно, по необходимости реализации)

Первым двум стадиям абсолютно без разницы, запрограммировали их в системе, в стандартной либе, или в пользовательском коде.

И всё-таки, где вы в стандарте Common Lisp нашли рекурсивные определения?
UFO just landed and posted this here
В этом коде есть одно место, которое точно можно критиковать, это использование «магических констант» в строках 142-149

В этих строчках содом какой-то:

if ($pageInfo['doktype'] != 3 &&
                        $pageInfo['doktype'] != 4 &&
                        $pageInfo['doktype'] != 5 &&
                        $pageInfo['doktype'] != 6 &&
                        $pageInfo['doktype'] != 7 &&
                        $pageInfo['doktype'] != 199 &&
                        $pageInfo['doktype'] != 254 &&
                        $pageInfo['doktype'] != 255 &&
                        $pageInfo['no_search'] == 0 &&


return ($average >= 180*24*60*60 ? 'yearly' :
                                ($average <= 24*60*60 ? 'daily' :
                                ($average <= 60*60 ? 'hourly' :
                                ($average <= 14*24*60*60 ? 'weekly' : 'monthly'))));


if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/class.tx_ddgoglesitemap_pages.php'])


Фу блядь! Фу нахуй! Это даже на c# в сто раз лучше и короче выглядеть будет. Про всякую ерунду навроде
 protected $renderer;
из-за которой хер поймешь, что это за renderer (массив? референс? ...?) говорить смысла нету.
UFO just landed and posted this here
Про 142-149 я и написал, что там цифры, а не константы (и почему) :

Дело не в magic numbers, а в нечитаемом выблеве на десять строк.

А для protected $renderer есть phpDoc с типом переменной.

То есть без ide никак, и без жесткого документирования. А жестко задокументирован, как известно, только сферический код в вакууме. А потом еще удивляются, что испытательные сроки для новых сотрудников по 3 месяца — да в этой лапше за пол года дай бог разобраться.
UFO just landed and posted this here
По-моему, то же самое можно было написать как-то типа:
if doktype in [3,4,5,6,7,199,254,255]

Так что говнокод все равно детектед.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
я показывал своей бывшей девушке питон. первую задачку с project-euler она сама решила через полчасика. конечно, не ахти, но совсем уж абракадаброй код не был — при том, что она чистый гуманитарий, из гуманитарного класса на филологический факультет перешла

ну, может, это она меня так сильно любила
если номер в пределах pcl-files-map вызвать genurl с параметрами pcl-chapter-view chapter=значение из pcl-files-map с индексом number.

Обычный английский язык, только скобочками обернули, чтоб читать проще было.
С каких пор в английском языке стала употребляться префиксная запись?
Почему лисп так привлекает понторезов, никогда не понимал.
Это уже придирки. Такие куски читаются на ура. Уверен, что тут есть наркоманы лиспоеды, которые по 5-6 уровней вложенности и макросы в голове раскручивают.
dulepov спросил, что такое (> number -1), и услышал ответ «Обычный английский язык, только скобочками обернули».
Возможно, он вас и понял, но по-моему это ответ ради ответа, а не вопроса.
Любезнейший, это ложь, он спросил Что, например, делает этот код:, и получил ответ. В чем можно убедится прочитав текст, помеченный курсивом в моём комментарии: habrahabr.ru/blogs/webdev/104349/#comment_3256422

Про «обычный английский» — во-первых, это была ремарка, во-вторых, мне второй раз на ум приходит шутка про 10 типов людей, who understand binary and who dont.
Т.е. dulepov не спрашивал, что такое (> number -1)? Странно, тогда я не понял второй абзац его комментария.
Обычный английский.
то что ты написал — это уже перевод на английский. а в оригинале — какая-то шифровка, которая одним потоком не воспринимается — нужно бегать глазами туда-сюда, чтобы понять суть и переставлять всё это дело в уме.

а то что ты написал записывается так:

if number in [ 0… len( filesMap ) ]: genUrl( :chapterView, :chapter= filesMap[ number ] )

что читаемо даже при записи в одну строку

но я бы предпочёл как-то так:

try: genUrl( :chapterVew, :chapter= filesMap[ number ] )
catch filesMap->XWrongIndex: void
то что ты написал — это уже перевод на английский. а в оригинале — какая-то шифровка

Шифровка — это

if($a==$b && $b == $c && $crap === $garbage)
&& $this->page->tables['head']->order != 2;
... 120 lines ..
&& $this->page->tables['head']->order != n;


вроде понятно, но всё засрано какими-то $,&&,-> и прочим мусором.

но я бы предпочёл как-то так:

try: genUrl( :chapterVew, :chapter= filesMap[ number ] )
catch filesMap->XWrongIndex: void


Какая забавная семантика. Впрочем, никто не мешает нарисовать свой dsl и использовать её в лиспе.
да-да, неимоверное количество скобочек — намного лучше х)

свой язык я могу нарисовать на чём угодно. но при чём тут лисп? я лучше возьму что-нибудь более высокоуровневое, чем лисп или макроассемблер.
да-да, неимоверное количество скобочек — намного лучше х)

Скобочки не отвлекают, а засирание кода левыми символами отвлекают. Зачем нужно $? Напоминание для олигофренов о том, что это переменная?

более высокоуровневое, чем лисп или макроассемблер.

Мде…
человек, который не может уместить в своей оперативной памяти весь список используемых в программе литералов — олигофрен? вы бредите, товарищ.

а нужно это для таких вот выкрутасов: $obj->$methodName()
человек, который не может уместить в своей оперативной памяти весь список используемых в программе литералов — олигофрен?

Как пишущие на С, например, обходятся без префиксов?

а нужно это для таких вот выкрутасов: $obj->$methodName()

Правильно! Ради выкрутасов засрем весь код.
без понятия. на яваксрипте вот мне доллара немного нехватает.

странно это слышать от человека со стёртыми 9 и 0 на клаве…
$ мешает восприятию кода не так сильно как повторяющийся три раза оператор &&. Хотя и здесь возможны варианты^Wмнения. :)

if($a==$b && $b == $c && $crap === $garbage)

(if (and (equal a b)
           (equal b c)
           (=== crap garbage))
    ...)

Функции ===, конечно же, нет. Считайте это псевдокодом.
подобные конструкции я пишу так:

if( $a==$b )&&( $b == $c )&&( $crap === $garbage):

endif;

а расположение открывающей и закрывающей скобки на разных строках — это зло, так как ломается суть скобок — обернуть контент, образовав блок
А вот меня скобочки отвлекают — для каждой открывающей сразу смотришь где она закрывается, а на каждой закрывающей смотришь, где она открылась (в случае простых выражений, конечно не так, но если скобок с десяток пар...). По "$" же глаз пробегает не останавливаясь, исторически он нужен был интерпретатору, афаик, как и ";".
Приведите пример чего-нибудь более высокоуровневого, но при этом не являющегося специализированным, чем Common Lisp.
смалтолк, питон, руби, яваскрипт… тысячи их
Чем же они высокоуровневее? Все оперируют одними и теми же сущностями, что и Common Lisp с небольшими вариациями. Везде объекты, процедуры, последовательные вычисления и т.д. Могу объяснить подробнее, но хотелось бы сначала услышать Ваше мнение.
конечно же все они оперируют битами х) вопрос лишь в том как они это делают — используют специальный синтаксис для подчёркивания смысла сущностей. например [0..10], что понятно даже без чтения манов, вместо абракадабры в духе лиспа (… 0 10). и не надо говорить, что можно сделать свой дсл и бла-бла-бла, полученный дсл — это будет уже не лисп. точно также как си — это не ассемблер, хотя на нём и написан и позволяет использовать ассемблерные вставки.
Всё бы хорошо, но синтаксис к высокоуровневости не имеет никакого отношения. Есть языки, указывающие что делать процессору (асм), есть языки, абстрагированные от процессора, оперирующие битами ( C ), есть языки, оперирующие типизированными данными (Common Lisp, Python и т.д.). От того что вы вместо (subseq my-array 0 10) напишете my_array[0… 10] вы не начнёте оперировать чем-то более высокоуровневым чем массив, вы просто запишете ту же операцию в другом виде.
0..10 — это диапазон, а не массив. а высокоуровневость _языка_ от высокоуровневости _библиотеки_ только и отличается что синтаксисом. в том же ассме можно оперировать сом-объектами. будем считать его объектно ориентированным?

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

У вас есть здравая мысль, но вы её, похоже, сами не заметили. :) [0..10] — это создание диапазона, примитива. В CL такого примитива нет. Хотя я мог бы поспорить, что собственно к программированию диапазоны никакого отношения не имеют и в языке общего назначения должны быть реализованы в библиотеке, но факт остаётся фактом. В какой-то области Питон можно считать более высокоуровневым.
«это абстракция, то есть введение смысловых конструкций, кратко описывающих такие структуры данных и операции над ними, описания которых на машинном коде (или другом низкоуровневом языке программирования) очень длинны и сложны для понимания.»

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

ru.wikipedia.org/wiki/MASM
По крайней мере она выглядит как одна операция и на самом деле является одной операцией, в отличие от примера на asm'е. Существуют языки, в которых библиотечная сущность чувствует себя не хуже родной. Отличный пример языка, *НЕ* являющегося таковым — C++. ;) Исправить это — одна из задач языка D. Было действительно интересно наблюдать за размышлениями Александреску на эту тему. Оно осталось где-то в архиве nntp://news.digitalmars.com/digitalmars.D, но искать лень. :)
я всё-равно английский не разумею ._."

я только за, если можно расширить синтаксис языка, но иногда надо опускаться на уровень ниже (например для реализации этого высокоуровневого синтаксиса), а тут нас обычно ждёт жопа.
Знакомый, не имеющий доступа к Хабру интереусется, в чём же проблема Lua?
в том, что он без сишных биндингов ничего толком не умеет ._." а их вечно не хватает…
Ясно. И как это делает его низкоуровневым?

У меня складывается впечатление, что высокоуровневыми языками Вы называете те и только те, на которых лично Вам приятно писать. Странный критерий, не правда ли?
его делает никтоуровневым то, что кроме таблиц, функций и чисел в нём ничего нет. банальные строки в нём — это массив байтов. это язык низкого уровня для табличной виртуальной машины.
Да, кстати, если gen-url поднимает сигнал, то этот код легко переписывается:
(ignore-errors (genurl 'pcl-chapter-view
                               :chapter (first (aref *pcl-files-map*
                                                          number)))))
не надо глотать все ошибки…
UFO just landed and posted this here
это типа как в матрице?
— теперь я могу мыслить префиксно :-О
— ну что ж, проверим *хренак сотней скобочек по голове*
вот почему-то не поворачивается тумблер: «a + b» — легко, «a b +» нормально, «add(a,b)» — бывает :), а вот "(+ a b)"… :(
Если просто читать, становлюсь в тупик сразу: «Если и больше номер -1 меньше номер 1 — длина чего-то...».

Вместо number > -1 пишется (> number — 1). Вместо a and b пишется (and a b).
У вас отступы съехали. Это важно. sprunge.us/IZVP?cl
Код на лиспе читается не слева направо (и не как английский, cnupm ;]), а как дерево.

Корень — if. У него два потомка. Первый — условие (начинается с and), второй — then_expression (начинается с genurl). Условие — это and от двух. (> number -1) и (< number (1- (length *pcl-files-map*))). Т.е. число находится в диапазоне от -1 до *pcl-files-map*.

then_expression — это вызов функции genurl с символом pcl-chapter-view (в других языках обычно используется что-то вроде enum) и именованным параметром chapter равным первому элементу списка, являющегося number'ным элементом массива *pcl-files-map*. «Аналог» (first (aref *pcl-files-map* number)) в C — list_head(pcl_files_map[number]);
Так глядишь и лисп в этом топике выучу. Сначала выше коммент про префиксную запись: посмотрел выражение — стало понятней. Теперь про дерево — ещё понятней :)
если число больше -1 и число меньше, чем (length *pcl-files-map*) уменьшенное на 1, вызови генератор URL с параметрами…
Я написал, что мне Лисп кажется немного перегруженным, только и всего. Я вовсе не считаю его плохим языком.

Да что там перегруженным может быть — пара скобок, car,cdr,quote — вот и весь язык.

А есть какие–то реальные примеры веб приложений на Лиспе? Реальный код смотреть интереснее.

На lisper.ru с десятка эдак два статей на эту тему, всё остальное цепляется через cliki.net. Но зачем? Пишите на похапе и бидоне — хуже не будет.
>Но зачем?

Интересно, с префиксной записью выражений ещё не встречался (если не считать «сколько будет разделить 5 на 3?» :) )
у вас тут много лишних значков $ и;
вас это не парит?
Ну если их не парит наличие =,== и === то о чем с ними вообще можно говорить.
Во всём есть свои минусы
что-то вроде:

(set foo
     (cons (eq foo bar)
           (+ foo 99)
           bar))


По-моему вполне понятно (если что-то напутал — поправьте).
уупс, напутал…

  (set foo
       (if (eq foo bar)
           (+ foo 99)
         bar)))
а лучше вообще так:

(defun foo-bar-baz (foo bar)
  (if (= foo bar)
      (+ foo 99)
    bar))

(foo-bar-baz 10 20)
=> 20

(foo-bar-baz 10 10)
=> 109
Вопрос привычки. После нескольких погружений в LISP или Scheme перестаёшь замечать. А Emacs сам за тебя закрывающие скобки доставляет пока пишешь.

Небольшое погружение в LISP очень впечатляет. Внутренняя красота и элегантность языка, мощь выражения того, что ты хочешь сделать и т.д. Останавливает только тот факт, что по работе ни LISP, ни Scheme использовать не придётся, а значит вся эта красота и останется на созерцательно-умозрительном уровне…
Ну почему же не придется? Можно последовательно аргументировать свою позицию или просто поменять работу на более демократичную. В конце концов можно сделать и свой проект — люди делают
а clojure…?
работает на jvm, можно использовать обилие готовых java библиотек и фраемворков, при этом писать на lisp
уж лучше Scala для тех, кто хочет использовать ява-библиотеки и кто уже знаком хорошо с явой…
для кого лучше?
для тех кто знает java и не знает лисп и не хочет его изучить?
это возможно… но не более
эм… да=)

Вряд ли есть такие задачи в веб разработке с которыми лисп справляется лучше чем ява
ну веб разработка по сути это обычная разработка софта,
на clojure гораздо быстрее можно описать серверную логику, да и взаимодействие сложных структур на нем описываются легче и быстрее чем на java, особенности самого языка
> а clojure…?
> работает на jvm, можно использовать обилие готовых java библиотек и фраемворков, при этом писать на lisp

lisp — не язык, а семейство языков со сходными фичсетами и синтаксисом. Код на Clojure можно запустить в SBCL?

Для разработки софта размером меньше пары миллионов строк, конечно, надо и наличие неободимых библиотек оценивать. Здесь может победить как Clojure, так и Common Lisp в зависимости от задачи.
>Код на Clojure можно запустить в SBCL?
вряд ли, код SBCL например в scheme тоже не пойдет мне кажется без изменений
Во-первых, когда реализуемое приложение должно обладать достаточно сложной семантикой, другими словами, если требуется высокая гибкость программного кода

Высокая гибкость программного кода обуславливается возможностью его легко масштабировать. Я очень сомневаюсь, что это возможно при функциональном программировании.
Да, лисп — это функциональный язык. ООП на нём возможно, да… так же, как на Haskell :)
Вы только что-то слышали о LISP и не понимаете о чём речь. По этому вы не правы.

У LISP OOP (а именно CLOS), на которую многие языки равняются. Она позволяет легко делать многие ОО вещи элементарно, которые в других языках делается уже на уровне алгоритмов, паттернов итд.
Равняются да не выровняются. Всё так же тупо копируя C++ (или что-то ещё более раннее?) делают методы принадлежащими классам.
Чтобы скопировать плюсовое ООП сперва надо съехать с катушек и крепко удариться головой.
И, тем не менее, все кладут методы внутрь классов, тем самым лишая язык гибкости диспетчеризации, мультиметодов и вводя ненужные лишние сущности.
тем самым? х) всё это есть в любом тру-ООП языке ( smalltalk, objective-c и тд )
Ну да, в Ъ-ООП языках это тоже есть. :) Но объясните, почему, Python и Ruby, разрабатываемые через десятки лет после Smalltalk и CLOS сделали методы принадлежащими классам?
а кто мешает сделать простой метод, не принадлежащий ниодному классу?
У обобщённого метода может быть несколько реализаций, из которых при вызове выбирается специализация в зависимости от типов или даже значений аргументов. Сейчас в Python это можно сделать только положив методы с одинаковыми именами в разные классы, а остальное (типы и значения аргументов) проверять внутри ручками. Если метод специализируется по двум и более классам, то первый (какой из них???) будет при вызове записан перед точкой, а остальные после скобочки.

Можно, конечно, положить процедуру вне классов и устроить в ней свою диспетчеризацию. Как это делать отлично рассказывается в главе 2.6 SICP. ;) Но лучше бы этим занимался язык.

А ещё говорят, что Python высокоуровневее чем Common Lisp. ;) habrahabr.ru/blogs/webdev/104349/#comment_3256886
ты не понял. во всех ооп языках «методы» принадлежат классам. только в тру-ооп это не «методы» а «сообщения». и каждый объект сам решает как ему эти сообщения обрабатывать.

единственный косяк, который впрочем не решён и в фя, — это как группировать функции для которых нет вы «доменного параметра»

например, есть функции перевода типа А в тип Б, Б — в В, и А — в В
нужно разбить код на независимые модули АА, ББ и ВВ так, чтобы каждый из них не знал о другом. очевидно это не возможно, так как функции перевода должны знать два типа. можно создать отдельный модуль АБВ, который будет содержать все преобразователи. но АБВ зависит от всех трёх, а значит подключив А и Б придётся подключать и В. тогда можно ввести модули АБ, АВ и БВ, то есть перебрать все варианты совместного подключения модулей. и если с 3 модулями ещё можно совладать, то с 33 уже наступает жопа.
Что это за типы такие?
Нужен общий тип Ы и в модулях
А->Ы, Ы->А
это не эффективно. типы — например цвета в разных цветовых плоскостях.
Это намного эффективнее, чем в случае с 33 типами объяснять компилятору 528 вариантов преобразований.
я имел ввиду скорость работы, а не разработки. впрочем, ничего не мешает часть преобразований реализовать через промежуточный тип, чтобы сделать нормальную реализацию когда-нибудь потом.

а вообще, я мечтаю об автоматическом приведении типов. то есть, чтобы интерпретатор составлял граф, где узлами были бы типы, а рёбрами заданные функции приведения, и в нём бы он уже сам автоматически находил оптимальный путь с учётом оценок сложности каждого преобразования.
это книга или я не то нагуглил?
и толку мне от неё? о0
Если боитесь скобок — никакого. Если нет — то там есть реализация на Схеме всего, что вы хотите. :)
вот именно что боюсь… к тому же отладкой программы через репл я уже в яваскрипте наелся…
Сейчас везде интерпретируемые языки и виртуальные машины, а вас смущает двойное преобразование при операции, которая не должна быть особо частой.
Автоматическое приведение… Где вам требуется паутина из равнозначных типов?
цветовые плоскости, различные формы пикселей, форматы телефонов, времени, кодировки символов. если приглядеться, то вокруг полно различных типов которые мы по привычке приводим с нескольким базовым не используя толком возможности типизации.

программы жрут всё больше и больше ресурсов. только успевай апгрейдиться. а всё потому что языки предоставляют простые средства писать неэффективный код. а хороший язык должен позволять просто писать эффективный код.
С 33 вариантами наступит жопа в любом случае и придётся использовать решение megalol'а. 64 преобразования вместо 528.

Насчёт модулей, поясните в чём проблема. Наверняка в любом языке можно написать костыль, который будет загружать только требуемые модули. :) То есть для пользователя это будет:
(use-package '(a d convert))

(convert some-a some-d)

Метод в convert, типы в a, b, c, и т.д. Каждая реализация метода в своём модуле, который становится доступен при загрузке соответствующих типов. Вынос каждой реализации в модуль и автоматическую подгрузку можно красиво сделать макросами. Для реализации необходимы только мультиметоды, ну и хотя бы текстовые макросы, чтобы под кальку код не писать.

Но *практически* самое вменяемое решение — это положить все реализации в один модуль и попросить компилятор убрать неиспользуемый код и типы.
в том-то и дело, что плодить модули-конвертеры геморно, поэтому нужега либо какая-то инфраструктура с репозиториями, либо механизм разрешения конфликтов, ибо каждый модуль будет поставлять с собой конвертеры ко всем известным ему форматам в обе стороны.
Сколько вбросов.
LISP маштабировать легче чем PHP.
LISP — мультипарадигменный язык, вас никто не заставляет писать в функциональном стиле.
OOP в LISP и OOP в Haskell совсем разные звери.
Поддерживаю. Многие спорят о вкусе устриц не попробовав их
Приведите пример, когда PHP или Python будут лучше масштабироваться.
В одном из докладов ув. товарища Иехуды Каца приводится график сравнения производительности Ruby, Python, PHP и если не ошибаюсь Perl. Так вот, Ruby 1.9.1(2) находится на втором месте после Python 2…

Неужели в Ruby и Python нет возможностей метапрограммирования? ай-ай-ай…

Собственно более высокая производительость — это единственное преимущество, которое я вижу, однако в условиях маленькой команды, особенно более выгодно будет использовать Ruby и его рельсы или Python и его Джанго и Пайлонс…

Соглашусь с мнениями выше по поводу плохой читаемости кода в Лисп.
Я знаком с Ruby и Python достаточно поверхностно. Поправьте меня, если я буду не прав, но насколько я знаю, метапрограммирование на этих языках достигается костылями в стиле эмитирования кода сборок в .NET. Т.е. использовать это практически очень и очень непросто. О наглядности такого подхода вообще умолчу.
В питоне легко и непринужденно создаются классы генерящие классы, функции или что-либо еще, сам язык очень динамичен, в класс можно налету добавить методов/свойств, можно обращаться к методам и свойствам которые еще созданы, а создаются, скажем динамически ну и тп. Насчет руби не знаю, знаю что там есть кое какая возможность создания dsl'ей habrahabr.ru/blogs/ruby/48754/
По метапрограммированию на Руби был целый цикл статей, в том числе некоторые на Хабре:
habrahabr.ru/blogs/ruby/49951/

habrahabr.ru/blogs/ruby/75289/ и т.д.

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

Другое дело, это обсуждение критериев допустимости метапрограммирования в промышленных проектах, тут у сторон возникает множество аргументов как за, так и против.
> Неужели в Ruby и Python нет возможностей метапрограммирования? ай-ай-ай…

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

> Соглашусь с мнениями выше по поводу плохой читаемости кода в Лисп.

Да вырастайте вы уже из школьного возраста. Код, благодаря структурированию в виде дерева, отлично читается. Просто во всех виденные вами ранее языках принято форматировать код как попало, но одинаково (отступ на scope и т.д.). Код на любом современном языке — это дерево. Последовательностью является только код на ассемблерах.
> Примеры жонглирования кодом в студию.

в блоге ruby было несколько годных статей, например habrahabr.ru/blogs/ruby/49951
почитайте, очень интересно
Все замечательные плюсы и плюшки Лиспа мнгновенно перечеркиваются двумя фактами:
Во-первых, программистов на Лиспе днем с огнем не сыщещь, в отличие от пхп/руби/питона. Т.е. Лисп для веба с очень низкой долей вероятности будет выбран в обычных веб-разработках, которые и составляют львиную долю веб-рынка. Это значит, что Лисп — удел стартапов, причем именно стартапов лисперов, по вышеназваным причинам.
Во-вторых, привлекательность основных языков основана на привлекательности фреймворков и библиотек-расширений для них (ранний пхп можно не считать, там основным фактором служил низкий порог входа). Скажем, используя Ruby on Rails я потрачу каких-то пол-часа на создание адекватной системы аутентификации и авторизации. В это время войдет настрока плагинов, черновая реализация системы ролей и прав, и простое тестовое покрытие. В качестве бонусов я получу поддерживаемый сообществом (а не мной одинм) код расширений, всяческая поддержка OpenId, OAuth и иже с ними без написания тонн кода, возможность достаточно легко взять новых людей в команду.

Можно, конечно же сказать, что второе возражение перекрывается clojure или Scala на jvm, скрещенными со Spring. Однако, в случае выбора jvm и Spring в подавляющем большинстве случаев будет выбрана Java, как язык. (А скорее всего, выбор будет идти в обратном порядке по цепочке Java->Spring).
Да, хочу заметить, что я не противник Лиспа в вебе, просто не вижу никаких уникальных преимуществ для разработки рутинных веб-проектов перед «мэйнстрим» языками. Для «неординарных», допустим, высоконагруженных проектов он может быть и подойдет, но нужно как-то определить его нишу, к примеру, как для Эрланга, вполне себе олдсукльного функционального языка с его чудесной OTP.
Для разработки рутинных веб-проектов мэйнстрим языки — это единственный правильный выбор, а количество кодеров на нём — основной аргумент в пользу. ;)
Почему-то у меня не возникает проблем с поиском лисперов — достаточно зайти в профильное сообщество. Даже в этом посте можно насобирать почти десяток. И в отличии от пхп-шников все они будут иметь серьезный уровень компетентности. Знание лиспа — это знак качества разработчика.

«Уникальные преимущества для разработки рутинных веб-проектов» — это оксюморон. Преимущества лиспа проявляются при разработки сложных проектов, рутинные веб-проекты не сложны. (но даже там, умелое применение преимуществ лиспа сокращает время разработки и команду разработчиков)

«я потрачу каких-то пол-часа на создание адекватной системы аутентификации и авторизации.» — у лиспа тоже есть сообщество, пусть не такое обширное, но зато достаточно компетентное. Все перечисленные плюшки можно получить и за более короткое время, за время существования лиспа было сделано достаточно проектов.

UFO just landed and posted this here
А хостинги с лиспом существуют?
Google App Engine хостит Java. Clojure — лисп для Java. Следовательно, GAE хостит лисп.
«Это значит, что Лисп — удел стартапов, причем именно стартапов лисперов, по вышеназваным причинам.»

С первой частью этого утверждения наверное соглашусь, со второй — нет. Не нужно быть лиспером со стажем, чтобы прочувствовать мощь под капотом этого языка. Да, Lisp прекрасно подойдёт именно для новых вещей, когда разница между его невысокой популярностью по сравнению с популярными языками будет нивелирована (ведь готовых решений нигде не будет). Но я вас уверяю, у большинства основных библиотек для PHP/Python/Ruby есть 1-2 качественных аналога для Common Lisp.
Не удержался. Очень понравились фразы «игрушечный язык», «игрушечный пример». =)
> Стандарт Scheme описывает синтаксис и семантику самого языка, игнорируя стандартные библиотеки. В итоге мы имеем изящный, но игрушечный язык с многочисленными несовместимыми друг с другом расширениями

Уже совместимыми. en.wikipedia.org/wiki/Scheme_Requests_for_Implementation

> SBCL имеет экспериментальную поддержку Windows, но она не полноценна (в частности, нет многопоточности)

dmitry-vk.livejournal.com/ Где-то в этом блоге пролетала информация, что потоки будут в следующем релизе sbcl, а выходит он раз в несколько месяцев. Там же можно почитать об ущербности и костылях виндосовских нитей. :)
Компилятор выбрали. А когда будем писать «Hello World!»?
Наверное, не будем — это ведь не обзор языка, а, скорее, обзор библиотек для web-разработки (и не только) с небольшими примерами кода.

Для изучения языка рекомендую замечательную книгу: Practical Common Lisp.
Всё, ждем появления MVC веб-фреймворка на Haskell и новых SVG сайтов на AutoLisp'е!
Однако, уже snapframework.com/
Сам не использовал, насколько удобен не знаю.
От ведь есть ебанутые… :)
Надеюсь следующая статья будет более конкретная, а то вводных хвалебных статей по лиспу я уже начитался на 10 лет вперед, хотелось бы продолжения банкета.

Сам я сейчас потихонечку изучаю пеареный clojure, а так же читаю sicp (достал бумажную yes!, yes! yes!), так что тема мне очень интересна, но хочется больше конкретики.
Да, будет конкретнее, материала достаточно.
Впервые слышу о таком. Почитаю. Упоминание, наверное, да, а вот подробнее, думаю нет — не могу писать о том, с чем не работал.
Первая часть этого обзора будет вводной. Опытные лисперы смогут смело его пропускать.


Первая часть не получилась вводной. Она вообще никакая. На введение в лисп не тянет (тема list processor'а и его регистров car/cdr не раскрыта). На введение в «Лисп в вебе» не тянет, потому что веб не упомянут. Зато зачем-то в лучших традициях идет повествование о метапрограммировании в контексте лямбда-исчисления, причем не через богоугодные макросы, а через пень-колоду под названием eval. Слабовато извращение. Надо было вообще конструировать строку с определением функции, натравливать на нее read и потом eval — было бы еще кошернее.

Извините, но жирный низачот.
У меня есть сильное сомнение, что человек, который не знает о defmacro, но рассуждает о метапрограммировании, может научить чему-то хорошему. Приведенный в посте пример должен быть написан в духе
(defmacro sum-of-n (n)
  (let ((args (loop for i from 1 to n collect (gensym))))
    `(lambda (,@args)
       (+ ,@args))))


В противном случае это не LISP, а Javascript со скобками.
Зачем судить о человеке, совсем вам незнакомого, заключая о его незнании макросов лишь по тому факту, что он не привёл defmacro в своём посте? Желаю вам совершенствоваться в личностном плане.

Пример с defmacro я не приводил, поскольку макросы не обладают мощностью eval, поскольку не предназначены для рантайма, кроме того есть аналоги макроподстановок в других языках, пусть и не такие мощные. Я же хотел показать изюменку Lisp.
макросы не обладают мощностью eval


Что?! «Мощность eval»? Уважаемый, скажите мне, а eval имеет доступ к compile-time вычислениям? Нет. lambda-функция, полученная вот таким вот eval'ом списка будет скомпилирована? Нет.

О какой мощи идет речь? Вот с макросами, я понимаю, можно часть вычислений вынести из runtime в compile time. А eval — это костыль, использование которого является признаком кривой архитектуры приложения (конечно, в одном случае на миллион еспользование eval будет оправдано, но в посте явно не тот случай).

Я же хотел показать изюменку Lisp.


Изюминка LISP — это eval?! Такая изюминка есть практически в каждом интерпретируемом языке. Изюминка лиспа именно в макросах, которые вследствии своих невычисляемых аргументов способны превратить язык в нечто новое, главное этим не злоупотреблять. Макросы позволяют реализовать DSL максимально прозрачно.

Например, можно написать макрос, аналогичный defun, который будет генерировать обертки для вызова удаленных методов. В итоге объявление и вызов удаленного метода выглядят абсолютно прозрачно, чего в других языках крайне проблематично добиться без каких-нибудь внешних rpcgen'ов.
«О какой мощи идет речь?»

О мощности строить программу, о которой ничего не известно на этапе компиляции. Прислушайтесь к моему пожеланию)).
О мощности строить программу, о которой ничего не известно на этапе компиляции. Прислушайтесь к моему пожеланию)).

А теперь давайте подумаем: исходный код программы — это текст. Генерировать текст можно в любом практически применимом ЯП. В интерпретируемых ЯП обычно есть eval, которым можно выполнить текст программы. LISP's eval не превзошел в этом контексте ни одного интерпретируемого языка.

Если речь идет о компилируемых языках, можно в самом плохом случае вызвать компилятор, получить shared library из сгенерированного исходного текста, загрузить ее и вызвать оттуда функцию. При этом, кстати, функция будет выполняться быстрее, чем простым eval'ом. Получается, что eval можно сэмулировать даже в компилируемых языках.

Кстати, вот в таких вот отeval'енных функциях нет оптимизации хвостовой рекурсии, которая является достаточно популярным приемом в LISP. Вывод: eval — зло (про compile я знаю если что).

Прислушайтесь к моему пожеланию)).

О «совершенствовании в личностном плане»? То есть, видя откровенно кривой tutorial, я должен писать: «Молодец, так держать! Yes we can!»? Сюсюкаются только с маленькими детьми. Взрослые люди должны адекватно воспринимать конструктивную критику и аргументированно отстаивать свою точку зрения. Будьте добры, аргументированно разрешите противоречия между двумя вашими же тезисами:

1. (defun set-sum-of-n (n) ...) (далее идет текст функции, о которой в compile-time известно, что она генерирует функцию, суммируюущю n чисел)

2. Данным примером я хотел показать возможность LISP'а строить программу, о которой ничего не известно на этапе компиляции.

Если вы не видите противоречий в этих высказываниях, подсказываю: в примере жестко задается вид функции в compile-time и жестко задается список аргументов при ее вызове. При том, что n задается в runtime, а в compile-time пишется вызов с тремя параметрами… Кхм, нулевая применимость за пределами REPL. Уж как минимум следовало бы использовать apply.
Добавил вам кармы. Когда будет велосипед, подобреете. )))
Так не в велосипеде дело.

Я прочитал как-то «On Lisp», проникся лиспом и в конце-концов через cliki.net пришел к ucw и решил его попробовать. hello world'ы работали, но с течением времени ucw вдруг начинал потреблять все ресурсы CPU. Я помножил это на откровенный дефицит библиотек в CL и пришел к выводу, что если сильно захотеть, можно написать веб-приложение в Common Lisp, однако преимущества неочевидны, а граблей целое минное поле.

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

Лучше помогите автору советом или напишите статью лучшего качества. Снобизм тут излишен.
очень важный вопрос: а веб-фреймворки под лисп существуют?
человек, придумавший такое название, однозначно не заморачивается с тем, как его код будут читать… написал и ладно, пусть втыкают как хотят
Carnegie Mellon University Common Lisp.
никто не будет произносить название из 5 слов…
Спасибо за статью! Правда, вы ещё ничего не написали о собственно самой веб-разработке с использованием CL, но начинание — хорошее.

Не обращайте внимание на критику языка. Я сам — веб-разработчик с достаточно большим стажем (последние годы — Python, Django), но к функциональным языкам отношусь весьма серьёзно, и к Lisp-разновидностям тоже. В данный момент параллельно читаю «SICP» и «Real World Haskell».

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

И функциональные языки (появившиеся, как ни странно, уже очень-очень давно — в 60-70-х) — это не «прошлое» программирования, а наоборот, его будущее. Также как теорема Пифагора, они не могут просто так устареть, потому что отражают именно абстрактный фундамент мышления, а не тупо подражают современной архитектуре процессоров, как современные императивные языки. Но пока компьютеры были простыми и слабыми, изменения и не были никому нужны.

И что мы видим сегодня? Архитектура процессоров (и сред исполнения вообще) стала менятья — появились виртуальные машины, многоядерность, альтернативные архитектуры, облачные сервисы… И тут же современные языки резко «встряли» — вместо простого и элегантного кода стали выдавать каких-то жутких монстров, увешанных специальными костылями и блокировками как новогодние ёлки. А это бесконечные месяцы отладки, тяжелейший рефакторинг и т.п. Причём даже эти монстры часто работают неэффективно. А функциональные языки, напротив, вписываются в новую картину будущего просто идеально! Да, они ПОКА могут быть несовершенны, особенно инструментарий разработки (компиляторы, наборы библиотек). Но это же решается! Под Python тоже 7 лет назад не было инструментария. И Ruby on Rails тоже не было. И даже под PHP — «кот наплакал». Даже Java, при всей популярности, допиливали много лет, чтобы добиться сносной производительности. И это при большом вложении средств! Сегодня мы гордо гнём пальцы, и называем это всё «мейнстримом». Функциональные языки долго жили лишь в академической среде, никто не вкладывал миллионы в развитие средств разработки (как, например, Google вкладывал в Python). Пока…

Не слушайте никого. В любом случае, занятия Lisp'ом сильно повысят ваши способности как разработчика, я уверен. Даже если потом вы пересядете на Erlang или Haskell ;)
Вы так говорите «Erlang или Haskell», как будто это что-то плохое.
Напротив, это что-то очень, очень хорошее! :) Просто хотел поставить эти языки «на одну полку», ведь навыки, полученные в Lisp, могут успешно применяться и в других функциональных языках (да и многие императивные языки сейчас позволяют функциональный стиль, хотя и не поощряют, не получают от этого больших выгод, и писать «функционально» на Python и на Haskell — это две большие разницы).
Спасибо вам за положительный отзыв! Да, в Common Lisp не вкладывают денег, потому он всегда остаётся на обочине. Очень жаль. Согласен с вами в том, что будущее за функциональным программированием.
Продолжайте цикл! Только советую прислушаться к комментарию dimoclus'а, и получше продумайте целевую аудиторию ваших статей.

Если это профессиональные веб-разработчики, уже интересующиеся темой — не надо им рассказывать про Lisp. Достаточно указать «использовал SBCL и фреймворк такой-то, т.к. другие хуже». А далее — к сути.

Если пишете для широкой аудитории — тем более, не пишите про Lisp. Ничего, совсем. Другими авторами написано уже более чем достаточно, и более интересно (взять хотя бы статьи Пола Грэма). Сошлитесь на готовое. А дальше постарайтесь «затянуть аудиторию». Приведите примеры известных веб-проектов (Reddit, например) или покажите на примере какую-нибудь убойную возможность, которая позволяет решить близкую разработчикам по опыту задачу «с полпинка» вашим способом. «Заведите» людей! Потому что унылых постов вида «Как я писал плагин к ERP на .NET» — на хабре более чем достаточно. И люди просто на них не реагируют, их можно понять. Часто даже если тема хороша, то её подача убивает смысл прочтения. Не наступайте на эти грабли, попробуйте найти примеры интересных постов по программированию (с высоким рейтингом) и проанализировать причины их успеха.
будущее за функциональным программированием.

Скорее за гибридным как Scala, наверно. imho.
Я считаю, что само появление в огромном количестве всех этих «гибридов» — важная тенденция, открытое признание того, что с императивными языками «не всё ладно», что «чего-то не хватает». Ведь «функционализация» языков уже принимает просто характер какой-то эпидемии, даже в новый С++ её впихивают!

Моё имхо заключается в том, что «гибридные языки» — это из-за переходности данного этапа. Также как сейчас бесполезно создавать чистые электромобили для массового использования — нет инфраструктуры зарядных станций, быстрой смены батарей и т.п. Подобно этому, программисты сейчас просто привыкли думать в императивном стиле. Также, как китайцы привыкли к своим иероглифам, и считают их чем-то само собой разумеющимся.

Создатели гибридных языков — молодцы, умные люди, которые понимают эту экономическую целесообразность постепенного перехода. Что только последовательными мелкими шажками можно перенаправить «слона» современной индустрии в другом направлении. Резкая смена парадигмы для такой большой массы людей и кода просто невозможна. Но это не мешает отдельным разработчикам, у кого есть такая возможность, перепрыгивать переходные этапы ;)
> Скорее за гибридным как Scala, наверно. imho.

Или OCaml, или Common Lisp, или даже Scheme.
А если пересяду с PHP на Python/Ruby/Java/C#/..., пригодятся навыки ФП вообще и на Lisp в частности? Особенно для последних двух, в Python/Ruby, а теперь и в PHP :), парадигма ФП как-то реализована, пускай и не является доминирующей, а в Java/C# ФП, афаик, и не пахнет, а эти языки чуть ли не самые востребованные на российском рынке.

Спрашиваю не из праздного любопытства, сейчас наклевываются два долгоиграющих проекта, в которых выбором платформы я буду никак не ограничен (в разумных приделах — архитектура PC и свободные ОС/ПО :) ). Образно говоря, веб-страницу с «Hello world» у меня потребуют через месяц-другой после старта, так что время вникнуть есть почти во что угодно (по верхам, конечно, но на реальных задачах) — вот хочется попробовать что-то новое, как говорится «just or fun», но чтобы, как говорится, мою конкурентоспособность на рынке труда повысило :)
кажется в .net есть заигрывания с функциональщиной, например недавно пиареный F#
Ну, тут я вам многого посоветовать не могу. Могу лишь дать пищу для размышлений, а дальше решайте сами:

Это трудно сформулировать, но функциональное программирование — «дисциплинирует» мозги, заставляет порой полностью переосмыслить даже привычные вещи, взглянуть на них иначе (например, на операторы ветвления и циклы). А если ещё и SICP прочитан — вообще хорошо. Напоминаю, ФП отражает сам по себе Процесс — в чистом, математическом виде, без наслоений особенностей работы именно современных компьютеров. И глубокое понимание таких вещей также важно и полезно, как таблица менделеева для химиков. Отсюда и феноменальная «живучесть» того же Lisp'а. Устаревать-то нечему! (я уже приводил пример с теоремой Пифагора) Как ни крути, а фундаментальные кирпичики «программной материи» — они всегда были, есть, и будут есть ;)

Во-вторых, я начал заниматься Python'ом одновременно с Django, с января 2006-го. Тогда ни на Django, ни даже на Python'е «на российском рынке» никто почти и не писал. Теперь на Django пишут уже сайты Кремля… На самом деле не имеет значения, какой язык сейчас самый популярный. Python, например, в разы менее популярен чем C#, но работы на нём — это ужас какое количество! Важно не на чём вы пишете, а насколько хорошо и качественно. И без куска хлеба с чёрной икрой вы не останетесь, я гарантирую ;) В рунете есть примеры, когда целыми командами мигрируют на Erlang, например, причём всего за месяц. И качество кода при этом возрастает, как и масштабируемость и надёжность, хотя код становится меньше и понятнее. Если у инструмента есть такие преимущества, я считаю, уже не важно насколько он «мейнстримовый». Важно, что он позволяет экономить человеко-часы, а значит и деньги. Можно взять почти любого толкового программиста, и он освоится за месяц. Причём, мне кажется, сам разработчик с большим удовольствием пойдёт на вакансию, где есть возможность попробовать что-то новое.
Я имел некоторый опыт с ФП. И знаете, чуда не произошло. Да, я очень-очень много узнал. Мой код стал лучше на всех языках. После прочтения SICP появилось ощущение, что в голове есть фундаментальная база. Однако, код моих сложных проектов все равно выглядит сложным. Не возможно решить сложную задачу простым способом. Это все равно, что построить вечный двигатель. Вы можете разбить задачу на ряд простых подзадач. Однако в суме взаимодействия подзадач будут сложными. Почитайте Брукса. Можно лишь уменьшать привнесенную сложность. Некоторая постоянная минимальная сложность есть всегда, ибо это и есть сама задача. Так что от «бесконечные месяцы отладки, тяжелейший рефакторинг и т.п» никуда не уйти =) Однако, я не отговариваю никого от изучения от ФП. Знакомство с haskell было самым большим «драйвом» в программирвоании в моей жизни.
… я очень-очень много узнал. Мой код стал лучше на всех языках… Знакомство с haskell было самым большим «драйвом» в программирвоании в моей жизни.

Ну вот видите :)

Я не утверждаю, что ФП позволяет сложные задачи сделать простыми. Равно как врядли можно придумать «другую математику», в которой теорема Ферма элементарно доказывается даже школьником.

Но вы сами верно заметили про «привнесённую сложность». Часто решение задачи становится в разы проще даже от простого переформулирования (например, многие алгоритмы красиво записываются через рекурсию). А уж выбор правильной формулировки для записи решения — это вообще архиважно. Для примера, возьмём популярный ныне подход Duck typing, который только своим существованием сразу, на порядки (!!) уменьшает число дополнительных типов в проекте, и упрощает их иерархию.

К сожалению, «мейнстрим» сейчас очень и очень далёк от элегантности и простоты конечных решений. Более того, далёк часто даже от эффективности (микропрограммы на С, работающие со скоростью света не предлагать).
> Часто решение задачи становится в разы проще даже от простого переформулирования (например, многие алгоритмы красиво записываются через рекурсию)

Так оно так. Но я это смог применить резве что только для работы со списками. Сложные вещи на императивном языке выглядят как лапшекод, но как переписать на хаскель я вообще не знаю. Возможно у меня мозги слабоваты, и кто-то сможет строить такие мощные абстракции, но я пасс. Мне больше нравятся языки, позволяющие грязные хаки — языки с динамической типизацией (лисп, руби, питон). Пусть лучше немного сломанный местами код, но работающий в целом, и не падающий целиком, если что-то отваливается.
SICP прочитан — вообще хорошо.

В рунете есть примеры, когда целыми командами мигрируют на Erlang, например, причём всего за месяц. И качество кода при этом возрастает, как и масштабируемость и надёжность, хотя код становится меньше и понятнее.

Silver bullet?

Если у инструмента есть такие преимущества, я считаю, уже не важно насколько он «мейнстримовый».

extract_text_field(Binary,TextList,Count) when byte_size(Binary) == 0 ->
	TextList;
extract_text_field(Binary,TextList,Count) ->
	<<Size:16/little,Content:Size/little-binary-unit:8,Rest/binary>> = Binary,

        ...

	case Count rem 2 == 0 of
		true -> Text = TextList ++ [binary_to_atom(Content,latin1)];
		false -> Text = TextList ++ [Content]
	end,

	extract_text_field(Rest,Text,Count+1).


тут какие-то гуарды, бинари-мэтчинг, рекурсия. Мама, мы в аду! Мы в аду, мама!

… тут у меня еще 2к строк натива парсера xml для ирлонга..
Собственно прямого совета и не просил, важна была как раз пища для размышлений, имеет ли смысл изучать lisp или другой ФЯП фактически только для себя, для расширения кругозора, или углубить какие-то знания специфичного продукта. Спасибо за подробный ответ

P.S. «Попробовать новое» и вакансии, имхо, плохо совместимы. Читаешь вакансии и такое ощущение, что на рынке только специалисты по хайлоад, знающие на отлично с пяток платформ, с десяток языков, пару десятков библиотек/фреймворков, администрирующих и винду, и фрибсд, и IOS, и Android, умеющие оптимизировать запросы и к MS SQL, и CouchDB, а что-то вроде «требуется lisp-программист, базовое знание lisp будет плюсом» не встречается как-то
Функциональные фишки применимы хоть на чистом С.
А у лиспа достоинство в том, что это по сути AST. Отсюда удобство разработки специализированных языков. А функционально можно писать и не привыкая к скобкам.
Функциональные фишки применимы хоть на чистом С.

Если мне по сети прилетает набор байтов (что-то вроде «date05-09-2008 12:37:02.12947textOh noes») и я хочу получить кортеж
{date,<<05-09-2008 12:37:02.12947>>,text,<<Oh noes>>}
сунуть в какой-то там список и сделать какую-нибудь херню, например, редукцию или отмапить список с хитрым условием, сколько килострочек на сях займет реализация? И сколько килострочек(внешних препроцессоров/библиотек/wadever) к ней надо добавить, чтоб можно было использовать в других местах проекта?
Я как понимаю, это опровержение. Т.е. вы утверждаете, что функциональные фишки не применимы на чистом С.
Ок.
SICP — не о функциональном программировании, а о программировании вообще. После его прочтения должно появиться не чувство сродни «ФП — это серебряная пуля», а чувство, позволяющее использовать правильный подход в правильном месте — любую из 4 описанных в книге парадигм (ФП, императивщина, логическое и мета).
Согласен. Но именно в этом смысле я SICP и упомянул, мол «Если SICP прочитан — человек уже наверняка понимает что к чему». Может просто бестолково выразился.
«обственно прямого совета и не просил, важна была как раз пища для размышлений, имеет ли смысл изучать lisp или другой ФЯП фактически только для себя, для расширения кругозора, или углубить какие-то знания специфичного продукта.»

Однозначно имеет. Особенно почитайте про базовые функционалы, например, map.
С питоновскими map/reduce не родственники? :)
Сам понял, что да:
>Влияние других языков на Python
>…
>Lisp — отдельные черты функционального программирования (lambda, map, reduce, filter и другие);

ru.wikipedia.org/wiki/Python
Насколько я в курсе хорошего стиля — использовать map, filter, reduce и аккумуляторы/свертки с более чем одним аргументом в питоне — дурной вкус, ибо есть стандартные lisp comprehensions, которые реализуют map и filter в духе питона.
Вставлю свои 5 копеек в обсуждение веб-разработки на функциональных языках. Ведь все не так уж и плохо, правда странно почему хабра-юзер zahardzhan не подключился к обсуждению. У него есть отличная статья в которой описывается пример создания веб-приложения на Clojure для Google App Engine. И как мы видим библиотек не мало.
К примеру Compojure, Ring,Hiccup, Enlive.
Да это все работает на JVM. И я очень рад тому, что уже сейчас могу писать для JVM в функциональном стиле! Достигать максимального быстродействия, использовать все ядра процессора. Я не говорю вам, бросайте свое ООП и бегом на ФП. Просто знайте, что есть и другой подход в разработке.

p.s. возможно наши дети скажут: «Ах-ха-ха! Пап, ты писал… Как это тогда называлось… ООП? О боже, это же так много писать!»
а ты уверен, что на jvm разница в быстродействии хоть сколь-нибудь ощутима? %-)
Эта статья открыла мне глаза на что, что Хабр — не торт. dimoclus сказал все что я хотел сказать, и более здесь нечего добавить.
ООП и ФП никоим образом не противопоставлены друг другу.
Блин, тэги не сработали. Ссылка на статью.http://zahardzhan.github.com/2010/clojure-setup-for-google-app-engine.html
О-бал-денная статья. Ни слова о веб-программировании и дикий холивар в комментах.
Если вы считаете, что это дикий холивар, вы не были на ЛОРе. Здесь вполне конструктивная беседа.
Sign up to leave a comment.

Articles

Change theme settings