Scala
Читаю книжку Одерского, до основной шизы еще не добрался, но такое ощущение, что в скале чрезмерно много синтаксического сахара. Типа "тут вы можете скобки опустить, а тут вместо скобок использовать фигурные скобки, а тут мы прямо в параметрах класса сделаем их полями, а в multiline string literal вы можете сделать отступ и stripMargin" и прочая и прочая в том же духе.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.
Заодно по наводке
jdevelop глянул на http://spray.io/ https://github.com/spray/spray/wiki
Примеры там, конечно, знатный abuse возможностей языка и вычислений на типах, типа extraction-директив с HList в качестве параметра типа.
Clojure по сравнению с этим выглядит более простой и логичной, хотя я не уверен, можно ли сравнивать совершенно разные языки, общего у которых только функциональщина и иммутабельность иногда.
PS: Вот, к примеру:
https://github.com/spray/spray/blob/master/docs/documentation/spray-routing/code/docs/HttpServiceExamplesSpec.scala
В SimpleService HttpResponse реализован как html-код написанный прямо внутри скала-кода.Сижу уже 30 минут ищу, где это преобразование реализовано и как. Т.е. не видя отдельных литералов и их типов (которые без загрузки всего оного кода с зависимостями в IDE/интерпретатор еще и не увидишь), с ходу догадаться, что происходит, достаточно сложно. XML literals, встроенные в язык и где-то implicit для конверсии.
PPS: implicit evidence:
http://jim-mcbeath.blogspot.com/2008/11/scala-type-infix-operators.html
http://stackoverflow.com/questions/3427345/what-do-and-mean-in-scala-2-8-and-where-are-they-documented
По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот
xeno_by еще приделает макросы - и совсем хорошо станет.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.
Заодно по наводке
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Примеры там, конечно, знатный abuse возможностей языка и вычислений на типах, типа extraction-директив с HList в качестве параметра типа.
Clojure по сравнению с этим выглядит более простой и логичной, хотя я не уверен, можно ли сравнивать совершенно разные языки, общего у которых только функциональщина и иммутабельность иногда.
PS: Вот, к примеру:
https://github.com/spray/spray/blob/master/docs/documentation/spray-routing/code/docs/HttpServiceExamplesSpec.scala
В SimpleService HttpResponse реализован как html-код написанный прямо внутри скала-кода.
PPS: implicit evidence:
http://jim-mcbeath.blogspot.com/2008/11/scala-type-infix-operators.html
http://stackoverflow.com/questions/3427345/what-do-and-mean-in-scala-2-8-and-where-are-they-documented
По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
no subject
no subject
no subject
Проблем с оптимизацией ленивой программы не более, чем проблем с оптимизацией программы на C под Cell BE. Со сложностью то же самое.
Мой подход состоит в экономии времени программиста, чтобы тот совершил больше полезных для понимания предметной области ошибок, а не оптимизировал ещё не написанную программу.
no subject
Начнем сызнова - ваш тезис, как я понимаю, состоит в следующем: ленивый порядок экономит время программиста, поскольку делать выводы о ходе вычисления проще при ленивом порядке.
Здесь есть посылка (делать вывод о ходе вычисления проще при ленивом порядке) и следствие (программист экономит время).
Чтобы следствие получилось верным, надо показать, что верна посылка. Но тут-то и возникает проблема - есть известные факты, которые посылку опровергают. То есть программист, может, время и экономит - но явно не потому, что в ленивом порядке делать выводы о ходе программы проще - т.к. известно, что делать эти выводы при ленивом порядке _сложнее_.
no subject
Вот тут дилемма.
Стоит ли нашему читателю верить Валентину Будаеву или Джону Хьюджесу и Леннарту Аугустссону?
Вадлер, кстати, утверждает дуальность call-by-name и call-by-value. Поэтому на статью с показанной дуальностью call-by-value и call-by-need я бы хотел посмотреть.
И ещё хочу попросить у вас ссылку на статью, которая показывает повышение модульности программ на энергичном языке по сравнению с ленивым. WhyFP Джона Хьюджеса показывает повышение модульности программ только для ленивых языков, надо исправить это упущение.
no subject
А зачем кому-то верить? Я предпочитаю смотреть на экспериментальные факты, а не на чьи-то мнения и статьи (которые тоже суть не более чем мнения). А экспериментальные факты таковы, что при оценке сложности и оптимизации программ ленивый порядок не упрощает, а усложняет reasoning.
> И ещё хочу попросить у вас ссылку на статью, которая показывает повышение модульности программ на энергичном языке по сравнению с ленивым. WhyFP Джона Хьюджеса показывает повышение модульности программ только для ленивых языков, надо исправить это упущение.
Во-первых, это статья о том, как FP поднимает модульность в языках вроде хаскеля. К другим ЯП сделанные в статье выводы, конечно же, неприменимы. Во-вторых, статья рекламная - а энергичному порядку реклама не требуется, Это лень на данный момент маргинальна.В-третьих, я могу ошибаться (вы меня тогда поправьте), но вот тот же Саймон Пейтон-Джонс как-то высказывался на тему того, что лучше было бы хаскелю быть энергичным, нет?
> Поэтому на статью с показанной дуальностью call-by-value и call-by-need я бы хотел посмотреть.
call-by-need и call-by-name изоморфны в обсуждаемом смысле.
no subject
Неверно. Рассуждения о программе усложняются, если пытаться использовать императивный способ рассуждений, основанный на понятии "ход вычислений".
Если же использовать семантику Скотта, то рассуждения становятся проще в разы (а то и в десятки раз).
no subject
От того, что вы белое назовете черным, оно не станет таковым. Проблемы с оценкой сложности ленивых программ - известный факт.
> Если же использовать семантику Скотта, то рассуждения становятся проще в разы (а то и в десятки раз).
Было бы неплохо продемонстрировать этот тезис на каком-нибудь простом примере. Ну, например, докажите в семантике Скотта ассоциативность ф-и append.
no subject
Фу, как некрасиво. Только что говорили вообще про рассуждения о программе — и вдруг спрыгиваете на оценку сложности.
> Ну, например, докажите в семантике Скотта ассоциативность ф-и append.
Это которая в Хаскеле (++)? Конкатенация списков?
Пожалуйста.
Определение:
append [] ys = ys
append (x:xs) ys = x : append xs ys
Требуется доказать:
append xs (append ys zs) = append (append xs ys) zs
Расшифровка определения: если положить
t f [] ys = ys
t f (x:xs) ys = x : f xs ys
то append — наименьшая неподвижная точка функции t, то есть, наименьшая f, для которой t f = f.
Далее, если f такова, что f xs (append ys zs) = append (f xs ys) zs, то t f тоже удовлетворяет этому условию, так как
t f [] (append ys zs) = append ys zs = append (t f xs yz) zs
t f (x:xs) (append ys zs) = x : f xs (append ys zs) = x : append (f xs ys) zs = append (x : f xs ys) zs = append (t f (x:xs) ys) zs
Функция (_|_) этому условию удовлетворяет:
(_|_) xs (append ys zs) = (_|_) = append (_|_) zs = append ((_|_) xs ys) zs
Значит, условие удовлетворяется для tn(_|_) при любом натуральном n. В силу непрерывности обеих его частей по f, оно удовлетворяется также и для supntn(_|_) — а это и есть append.
no subject
(Anonymous) 2012-11-15 04:46 am (UTC)(link)Я позволю себе процитировать свой комментарий, на который вы отвечали:
> А экспериментальные факты таковы, что при оценке сложности и оптимизации программ ленивый порядок не упрощает, а усложняет reasoning.
Так что никто никуда не спрыгивал.
> Пожалуйста.
У вас обычное доказательство по индукции (f -> t f шаг индукции как раз), только усложненное "оберткой" из непрерывности, неподвижной точки и жопы. То есть без упоминания семантики Скотта все было бы проще:
append [] (append ys zs) = append ys zs = append (append [] yz) zs
append (x:xs) (append ys zs) = x : append xs (append ys zs) = x : append (append xs ys) zs = append (x : append xs ys) zs = append (append (x:xs) ys) zs
Так что тут преимущество как минимум неочевидно. Может, тогда, вы сами подберете какой-нибудь несложный пример, на котором это преимущество уже будет очевидным?
no subject
Вы правы, прошу прощения. Просмотрел.
> У вас обычное доказательство по индукции
В некотором роде. Может, вы ещё сможете ответить, индукция по чему ведётся? Только не надо говорить "по длине xs" - доказательство вполне работает и при бесконечном xs.
> только усложненное "оберткой" из непрерывности, неподвижной точки и жопы.
Ну, эта "обёртка" входит в стандартный инструментарий и применяется без напряжения мозга, так что не страшно.
> Может, тогда, вы сами подберете какой-нибудь несложный пример, на котором это преимущество уже будет очевидным?
Может быть, я подумаю.
no subject
Трансфинитной индукцией по ординалам до алеф_0 включительно (все списки конечной длины). Наше утверждение соответствует алеф_1 (бесконечные списки):)
no subject
Какой кошмар.
Алеф-1 — это, если принять ГК, континуум. Откуда вы его там выкопали — я не понимаю.
А "по ординалам" — не пойдёт; грубо говоря, я хочу услышать что-то вроде "индукция по n", а вы мне говорите "индукция по натуральным числам".
no subject
List_n - списки длины
List_n - списки длины <n. Можно было брать <=n, тогда бы остановились на алеф_0. Это совершенно не существенно в нашем случае.
> А "по ординалам" — не пойдёт; грубо говоря, я хочу услышать что-то вроде "индукция по n", а вы мне говорите "индукция по натуральным числам".
По множествам списков длины не превышающей n, это дело по включению изоморфно (как вполне упорядоченное множество) ординалам до алеф_0 (раз вас смущает алеф_1 начнем с нуля :)). Т.к. нам нужен этот самый алеф_0, то индукция трансфинитная. Если ограничиться только конечными списками - тогда достаточно простой индукции.
no subject
Это вы к чему?
> Можно было брать <=n, тогда бы остановились на алеф_0. Это совершенно не существенно в нашем случае.
Может, и не существенно, но я абсолютно не понимаю, что вы имеете в виду. При чём тут вообще алефы, в особенности алеф-1?
> По множествам списков длины не превышающей n
Нет.
> это дело по включению изоморфно (как вполне упорядоченное множество)
Кто "это дело"? Множество списков? Оно не является упорядоченным вообще.
no subject
Да. Ну то есть вы, может, и имели ввиду нечто другое, но и индукции по множествам списков длины менее n вполне достаточно. По включению эти множества образуют вполне упорядоченное множество, изоморфное ординалам до алеф_0 включительно (все-таки нам надо брать List_n - списки длины <n, я выше немного поторопился, иначе у нас не будет множества соответствующего всем конечным спискам). Тогда в результате трансфинитной индукцией получаем утверждение для List_алеф_1 - что есть списки не более чем счетной длины.
no subject
То есть, по-нормальному это называется "трансфинитная индукция по длине списка".
Так вот: нифига. Прелесть в том, что вам приходится изобретать некую числовую (ординальную, кардинальную, whatever) характеристику, по которой вести индукцию. В случае списков выбор достаточно прост, но если предметом рассуждений будут, скажем, деревья, тут уже пойдут варианты - брать число вершин? число листьев? высоту?
В моём варианте индукция совершенно обычная (никакая не трансфинитная) ведётся всегда по одному и тому же: по степени, в которую возводится функция (в данном случае - функция t). И эта характеристика уже есть, она входит в построение неподвижной точки.
Кроме того, вам, чтобы сделать полноценный индукционный переход, всё равно потребуется говорить какие-то слова про непрерывность. Сейчас вы их мягко замолчали.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Действительно, СПЖ сказал в интервью, что чистота важнее порядка выполнения и что "следующий Хаскель" может быть и энергичным. Просто проще всего сделать язык чистым с помощью ленивого порядка выполнения.
Который, к тому же, ещё и удобней для программирования.
Насчёт маргинальности... По-моему, умного человека смущает не количество единомышленников, а их качество. Мне нравится Haskell community.
Прошу прощения, но упомянутые вами "эксперименты" пока выглядят всего лишь как ещё одно мнение. Эксперименты должны иметь результаты в виде цифр. Вот таковые про Хаскель и энергичные языки.
И я хочу увидеть чьё-то ещё мнение насчёт изоморфизма call-by-value и call-by-need. Только вашего мне недостаточно. Вы рассматриваете этот пока ещё не существующий для меня дуализм на слишком низком уровне.
no subject
> Вот таковые про Хаскель и энергичные языки.
Вы сами догадаетесь, куда следует засунуть статистические эксперименты без обоснования репрезентативности выборки, или вам подсказать?
no subject
Лично мне более по душе наличие хотя бы каких-то результатов эксперимента, чем полное их отсутствие и вкусовщина, демонстриремая вами.
no subject
Результаты эксперимента еще надо интерпретировать. Вот вы там видите ленивый хаскель и вам кажется, что результат в пользу ленивости, а я смотрю, что там есть вполне энергичный лисп, который порвал хаскель как тузик грелку.
Эксперимент, результаты которого можно свободно интерпретировать совершенно противоположными способами, никакой практической ценности для меня лично не несет. Ну а вы как хотите, я вам свое мнение не навязываю. Блажен, кто верует, как говорится.
no subject
И вот так у вас все.
Мне эта наша дискуссия нравится настолько, что я буду давать на нее ссылку при каждой вашей попытке начать со мной общение в будущем.
no subject
no subject
будубыл здесь всю неделю! Вы очень приятная аудитория!Надеюсь, удовольствие было не только эстетическим.
no subject
Вы видели этот код? Я - нет. Если код втрое меньше - это не значит, что он более читабелен, понятен и прост в поддержке. Более того, если посмотреть, то видно, что более короткий код разрабатывался _дольше_ - это значит "плотность" информации выше, а код - сложнее. Так что у меня есть все основания предположить, что там плохо пахнущая обфусцированная куча в стиле перловских однострочников. Это уже не говоря о том, что мерить код "строками" - как минимум, некорректно. в разных языках может быть разная насыщенность строк. В одном ЯП у нас на строке мешанина из кучи односимвольных идентификаторов, в другом - то же самое, но на 5 строк - ясно и понятно.
С другой стороны, время разработки - это фактор полностью объективный. Получили результат втрое быстрее - значит затраты втрое меньше.