metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-11-06 04:15 am
Entry tags:

Scala

Читаю книжку Одерского, до основной шизы еще не добрался, но такое ощущение, что в скале чрезмерно много синтаксического сахара. Типа "тут вы можете скобки опустить, а тут вместо скобок использовать фигурные скобки, а тут мы прямо в параметрах класса сделаем их полями, а в multiline string literal вы можете сделать отступ и stripMargin" и прочая и прочая в том же духе.
Основное из этого, видимо - function literals и вызов методов в стиле a methodName b, без точек и скобок, что делает код более лаконичным, одновременно позволяя при желании превратить код в нечитабельный ад.

Заодно по наводке [livejournal.com profile] 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

По-моему, это уже достаточно сложно, чтобы увлечь психов и стать новыми крестиками. Вот [livejournal.com profile] xeno_by еще приделает макросы - и совсем хорошо станет.

[identity profile] valentin budaev (from livejournal.com) 2012-11-12 05:47 am (UTC)(link)
То, что в лени задумываться не надо - это какой-то сомнительный тезис, вспомним хотя бы проблемы с оптимизацией и оценкой сложности ленивых программ.
В общем, описанное выше решение (фиксация порядка вычислений типами) как раз и нужна за тем, чтобы не задумываться - то есть если нам хочется узнать, что и как вычисляется, то нам в этом случае не надо исследовать control-flow, достаточно посмотреть на тип выражения.
Еще можно вспомнить о том, что бОльшая часть юзкейзов лени покрывается ленивыми структурами. В этом смысле какой-нибудь map для списка не должен писаться руками - он должен быть сгенерирован автоматически, исходя из определения АТД "List" и генерализованного определения map для произвольного АТД (как, например, это можно делать в Clean). Для ленивого списка мы автоматически получим ленивый map, для энергичного списка - энергичный map, а переход между способами вычисления будет выглядеть как явное преобразование типа соответствующей структуры.

[identity profile] thesz.livejournal.com 2012-11-12 06:27 am (UTC)(link)
Проблемы с оптимизацией начинаются уже после написания программы. Если начинаются вообще.

[identity profile] valentin budaev (from livejournal.com) 2012-11-12 08:55 am (UTC)(link)
Проблемы с оптимизацией я упомянул лишь для демонстрации того, что не так все очевидно с control-flow ленивой программы. Если бы было очевидно - не было бы проблем с оптимизацией и оценкой сложности.

[identity profile] thesz.livejournal.com 2012-11-12 09:00 am (UTC)(link)
Как бы это сказать помягче.

Проблем с оптимизацией ленивой программы не более, чем проблем с оптимизацией программы на C под Cell BE. Со сложностью то же самое.

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

[identity profile] valentin budaev (from livejournal.com) 2012-11-12 11:46 am (UTC)(link)
Вы полностью пропустили то, что я написал :)

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

Здесь есть посылка (делать вывод о ходе вычисления проще при ленивом порядке) и следствие (программист экономит время).

Чтобы следствие получилось верным, надо показать, что верна посылка. Но тут-то и возникает проблема - есть известные факты, которые посылку опровергают. То есть программист, может, время и экономит - но явно не потому, что в ленивом порядке делать выводы о ходе программы проще - т.к. известно, что делать эти выводы при ленивом порядке _сложнее_.

[identity profile] thesz.livejournal.com 2012-11-12 07:25 pm (UTC)(link)
>То есть программист, может, время и экономит - но явно не потому, что в ленивом порядке делать выводы о ходе программы проще - т.к. известно, что делать эти выводы при ленивом порядке _сложнее_.

Вот тут дилемма.

Стоит ли нашему читателю верить Валентину Будаеву или Джону Хьюджесу и Леннарту Аугустссону?

Вадлер, кстати, утверждает дуальность call-by-name и call-by-value. Поэтому на статью с показанной дуальностью call-by-value и call-by-need я бы хотел посмотреть.

И ещё хочу попросить у вас ссылку на статью, которая показывает повышение модульности программ на энергичном языке по сравнению с ленивым. WhyFP Джона Хьюджеса показывает повышение модульности программ только для ленивых языков, надо исправить это упущение.

[identity profile] valentin budaev (from livejournal.com) 2012-11-13 02:23 am (UTC)(link)
> Стоит ли нашему читателю верить Валентину Будаеву или Джону Хьюджесу и Леннарту Аугустссону?

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

> И ещё хочу попросить у вас ссылку на статью, которая показывает повышение модульности программ на энергичном языке по сравнению с ленивым. WhyFP Джона Хьюджеса показывает повышение модульности программ только для ленивых языков, надо исправить это упущение.

Во-первых, это статья о том, как FP поднимает модульность в языках вроде хаскеля. К другим ЯП сделанные в статье выводы, конечно же, неприменимы. Во-вторых, статья рекламная - а энергичному порядку реклама не требуется, Это лень на данный момент маргинальна.В-третьих, я могу ошибаться (вы меня тогда поправьте), но вот тот же Саймон Пейтон-Джонс как-то высказывался на тему того, что лучше было бы хаскелю быть энергичным, нет?

> Поэтому на статью с показанной дуальностью call-by-value и call-by-need я бы хотел посмотреть.

call-by-need и call-by-name изоморфны в обсуждаемом смысле.

[identity profile] migmit.livejournal.com 2012-11-13 04:19 am (UTC)(link)
> А экспериментальные факты таковы, что при оценке сложности и оптимизации программ ленивый порядок не упрощает, а усложняет reasoning.

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

Если же использовать семантику Скотта, то рассуждения становятся проще в разы (а то и в десятки раз).

[identity profile] valentin budaev (from livejournal.com) 2012-11-14 03:46 am (UTC)(link)
> Неверно.

От того, что вы белое назовете черным, оно не станет таковым. Проблемы с оценкой сложности ленивых программ - известный факт.

> Если же использовать семантику Скотта, то рассуждения становятся проще в разы (а то и в десятки раз).

Было бы неплохо продемонстрировать этот тезис на каком-нибудь простом примере. Ну, например, докажите в семантике Скотта ассоциативность ф-и append.

[identity profile] migmit.livejournal.com 2012-11-14 08:21 am (UTC)(link)
> Проблемы с оценкой сложности ленивых программ - известный факт.

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

> Ну, например, докажите в семантике Скотта ассоциативность ф-и 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.
Edited 2012-11-14 08:21 (UTC)

(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

Так что тут преимущество как минимум неочевидно. Может, тогда, вы сами подберете какой-нибудь несложный пример, на котором это преимущество уже будет очевидным?

[identity profile] migmit.livejournal.com 2012-11-15 10:21 am (UTC)(link)
> Так что никто никуда не спрыгивал.

Вы правы, прошу прощения. Просмотрел.

> У вас обычное доказательство по индукции

В некотором роде. Может, вы ещё сможете ответить, индукция по чему ведётся? Только не надо говорить "по длине xs" - доказательство вполне работает и при бесконечном xs.

> только усложненное "оберткой" из непрерывности, неподвижной точки и жопы.

Ну, эта "обёртка" входит в стандартный инструментарий и применяется без напряжения мозга, так что не страшно.

> Может, тогда, вы сами подберете какой-нибудь несложный пример, на котором это преимущество уже будет очевидным?

Может быть, я подумаю.

[identity profile] valentin budaev (from livejournal.com) 2012-11-15 12:21 pm (UTC)(link)
> В некотором роде. Может, вы ещё сможете ответить, индукция по чему ведётся? Только не надо говорить "по длине xs" - доказательство вполне работает и при бесконечном xs.

Трансфинитной индукцией по ординалам до алеф_0 включительно (все списки конечной длины). Наше утверждение соответствует алеф_1 (бесконечные списки):)

[identity profile] migmit.livejournal.com 2012-11-15 08:44 pm (UTC)(link)
> Трансфинитной индукцией по ординалам до алеф_0 включительно (все списки конечной длины). Наше утверждение соответствует алеф_1 (бесконечные списки):)

Какой кошмар.

Алеф-1 — это, если принять ГК, континуум. Откуда вы его там выкопали — я не понимаю.

А "по ординалам" — не пойдёт; грубо говоря, я хочу услышать что-то вроде "индукция по n", а вы мне говорите "индукция по натуральным числам".

[identity profile] valentin budaev (from livejournal.com) 2012-11-16 02:12 am (UTC)(link)
> Алеф-1 — это, если принять ГК, континуум

List_n - списки длины
[Error: Irreparable invalid markup ('<n.>') in entry. Owner must fix manually. Raw contents below.]

> Алеф-1 — это, если принять ГК, континуум

List_n - списки длины <n. Можно было брать <=n, тогда бы остановились на алеф_0. Это совершенно не существенно в нашем случае.

> А "по ординалам" — не пойдёт; грубо говоря, я хочу услышать что-то вроде "индукция по n", а вы мне говорите "индукция по натуральным числам".

По множествам списков длины не превышающей n, это дело по включению изоморфно (как вполне упорядоченное множество) ординалам до алеф_0 (раз вас смущает алеф_1 начнем с нуля :)). Т.к. нам нужен этот самый алеф_0, то индукция трансфинитная. Если ограничиться только конечными списками - тогда достаточно простой индукции.

[identity profile] migmit.livejournal.com 2012-11-16 08:31 am (UTC)(link)
> List_n - списки длины
[Error: Irreparable invalid markup ('<n [...] к>') in entry. Owner must fix manually. Raw contents below.]

> List_n - списки длины <n

Это вы к чему?

> Можно было брать <=n, тогда бы остановились на алеф_0. Это совершенно не существенно в нашем случае.

Может, и не существенно, но я абсолютно не понимаю, что вы имеете в виду. При чём тут вообще алефы, в особенности алеф-1?

> По множествам списков длины не превышающей n

Нет.

> это дело по включению изоморфно (как вполне упорядоченное множество)

Кто "это дело"? Множество списков? Оно не является упорядоченным вообще.

[identity profile] valentin budaev (from livejournal.com) 2012-11-16 09:54 am (UTC)(link)
> Нет.

Да. Ну то есть вы, может, и имели ввиду нечто другое, но и индукции по множествам списков длины менее n вполне достаточно. По включению эти множества образуют вполне упорядоченное множество, изоморфное ординалам до алеф_0 включительно (все-таки нам надо брать List_n - списки длины <n, я выше немного поторопился, иначе у нас не будет множества соответствующего всем конечным спискам). Тогда в результате трансфинитной индукцией получаем утверждение для List_алеф_1 - что есть списки не более чем счетной длины.

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-16 11:00 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-16 11:36 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-16 13:08 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-16 13:45 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-16 17:47 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-17 03:41 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-17 04:05 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-17 07:18 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-17 18:01 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-18 04:03 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-11-18 11:11 (UTC) - Expand

(no subject)

[identity profile] valentin budaev - 2012-11-25 12:53 (UTC) - Expand

[identity profile] thesz.livejournal.com 2012-11-13 10:20 am (UTC)(link)
Ага, я рад признанию неприменимости подходов Хаскеля в других ЯП.

Действительно, СПЖ сказал в интервью, что чистота важнее порядка выполнения и что "следующий Хаскель" может быть и энергичным. Просто проще всего сделать язык чистым с помощью ленивого порядка выполнения.

Который, к тому же, ещё и удобней для программирования.

Насчёт маргинальности... По-моему, умного человека смущает не количество единомышленников, а их качество. Мне нравится Haskell community.

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

И я хочу увидеть чьё-то ещё мнение насчёт изоморфизма call-by-value и call-by-need. Только вашего мне недостаточно. Вы рассматриваете этот пока ещё не существующий для меня дуализм на слишком низком уровне.

[identity profile] valentin budaev (from livejournal.com) 2012-11-14 03:49 am (UTC)(link)
Вы опять не читаете, что я пишу. Надоело.

> Вот таковые про Хаскель и энергичные языки.

Вы сами догадаетесь, куда следует засунуть статистические эксперименты без обоснования репрезентативности выборки, или вам подсказать?

[identity profile] thesz.livejournal.com 2012-11-14 08:29 am (UTC)(link)
Подскажите. Нашим читателям будет интересно.

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

[identity profile] valentin budaev (from livejournal.com) 2012-11-15 04:54 am (UTC)(link)
> Лично мне более по душе наличие хотя бы каких-то результатов эксперимента, чем полное их отсутствие и вкусовщина, демонстриремая вами.

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

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

[identity profile] thesz.livejournal.com 2012-11-15 08:53 am (UTC)(link)
Проиграв втрое по количеству строк, ага. Кто еще, кроме вас, назовет это "порвал, как тузик грелку"?

И вот так у вас все.

Мне эта наша дискуссия нравится настолько, что я буду давать на нее ссылку при каждой вашей попытке начать со мной общение в будущем.

[identity profile] berezovsky.livejournal.com 2012-11-15 09:16 am (UTC)(link)
Мне тоже очень доставляет ваш переинтеллекуализированный срач.

[identity profile] thesz.livejournal.com 2012-11-15 10:54 am (UTC)(link)
Спасибо! Я будубыл здесь всю неделю! Вы очень приятная аудитория!

Надеюсь, удовольствие было не только эстетическим.

[identity profile] valentin budaev (from livejournal.com) 2012-11-15 12:01 pm (UTC)(link)
> Проиграв втрое по количеству строк, ага. Кто еще, кроме вас, назовет это "порвал, как тузик грелку"?

Вы видели этот код? Я - нет. Если код втрое меньше - это не значит, что он более читабелен, понятен и прост в поддержке. Более того, если посмотреть, то видно, что более короткий код разрабатывался _дольше_ - это значит "плотность" информации выше, а код - сложнее. Так что у меня есть все основания предположить, что там плохо пахнущая обфусцированная куча в стиле перловских однострочников. Это уже не говоря о том, что мерить код "строками" - как минимум, некорректно. в разных языках может быть разная насыщенность строк. В одном ЯП у нас на строке мешанина из кучи односимвольных идентификаторов, в другом - то же самое, но на 5 строк - ясно и понятно.

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