metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-10-11 03:22 pm

Динамическая типизация, или статическая типизация для ленивых

Вчера [livejournal.com profile] ivan_gandhi сделал замечание что я, пользуясь динамически типизированной кложурью, при этом требую, чтобы в Java проверяли входные параметры на валидность. (Если что, проверка валидности в дотнете есть на каждом шагу, а объяснения вида "экономят циклы и не делаю проверки" в контексте жабы, тяжелого железа, JIT и прочего звучат крайне странно).
Собирался на эту тему устроить срач с утра, но [livejournal.com profile] thedeemon уже начал, так что я продолжу :)

Так вот, динамически типизированными языками мы пользуемся от бедности - нету статически типизированных языков, которые давали бы ту же функциональность.

Например, я хочу использовать кортеж с именованными полями (потому что позиционные кортежи нихера нечитабельны и их тип вида int*string*smallint*money*bool*Chervie ни о о чем не говорят). От входа в F# при этом нужно:
1) объявить этот чертов record где-то
2) сослаться на модуль с объявлением везде где он нужен
3) создавать экземпляры рекорда кривопачвярными конструкциями, причем оставить поля значениями по умолчанию нельзя.
4) паттерн матчинг с декомпозицией вроде не работает с рекордами.

Хаскель сразу закапываем - там на каждый случай имеется 3-4 расширения и 10 пакетов в hackage различной степени недоделанности, идиоматический подход - писать в point-free style, чтобы коллеги не разобрались, а работать в продакшене можно только с теми сторонними библиотеками, которые я могу сам починить.

При этом, у меня при работе с оперденями постоянно ситуации вида: есть запись с тремя полями, полученная из БД, мне нужно произвести обработку этой записи и добавить результат обработки в виде четвертого поля, получив новый тип записи.
Я НЕ хочу объявлять каждый раз такое руками и в Clojure это делается элементарно, добавлением нового ключа в map в функции-обработчике записей.

При этом РЕАЛЬНО динамическую типизацию я не использую. Она мне почти не нужна, потому что единственная ситуация, где вменяемый человек будет на одном цикле биндить к имени число, на втором строку, на третьем - список записей - это когда по условию задачи нужна, например, EAV-модель во все поля. И то - обычно EAV делается от безысходности, потому что пользователь не может нормально работать со схемой БД, а задача требует чего-нибудь вроде "добавить к части записей атрибут "фаза луны в которую производилась приемка товара"". В норме должны быть зависимые типы и миграции и пользователи бы пользовались той же системой типов что и разработчик.
Т.е. нормальный вывод типов - это когда программа берет типы из тут же описанного SQL-запроса, а рекорды расширяемые и объявлять их не нужно.

Второй use-case, где "вроде бы динамическая типизация" - это когда я делаю документы в виде кложурных структур данных, подгоняя комбинации списков-мапов-массивов-множеств под предметную область. В кложуре же это делается в лоб, а в хаскеле в один список не положишь три разных по структуре(типу) раздела документа. Но на самом деле, то что я делаю в кложури - это просто алгебраический тип данных "для бедных", без объявления заранее и без явно выделенных-именованных конструкторов данных. Если бы была возможность делать расширяемые и объявляемые по месту типы данных (чтобы каждый раз при разработке не переключаться между объявлением типа и конструированием данных по этому типу) - то было бы то же самое что в кложури - но статически типизированное.

PS: На ту же тему: http://justy-tylor.livejournal.com/190153.html

[identity profile] thesz.livejournal.com 2012-10-11 10:52 pm (UTC)(link)
Чем Cloud Haskell не ниша Хаскеля? Помимо всякого другого, той же REPA.

[identity profile] zamotivator.livejournal.com 2012-10-11 10:53 pm (UTC)(link)
Вот когда I/O, монады и ленивость починят, вот тогда и станет нишей. А пока не тянет.

[identity profile] thesz.livejournal.com 2012-10-11 10:55 pm (UTC)(link)
То есть, надо починить только то, что вы не смогли освоить? Так?

[identity profile] zamotivator.livejournal.com 2012-10-11 11:01 pm (UTC)(link)
Нет, починить нужно сущности, неадекватные по сложности или неудовлитворительные по потреблению ресурсов решаемым задачам.

[identity profile] thesz.livejournal.com 2012-10-11 11:10 pm (UTC)(link)
Вот смотрите, вынесенное в отдельную сущность IO позволило Хаскелю стать одним из первых языков с хорошей поддержкой SMP. fortkIO это примерно конец 1990-х, если я не ошибаюсь.

Если это полезное качество - вы можете быть против, конечно, - то может быть стоит считать это полезным архитектурным решением, чем неадекватным по сложности излишеством?

К слову, Cloud Haskell работает в своей монаде. А Cloud Haskell это практически Erlang 2.0, ибо использует исправленную семантику Эрланга.

Если счесть и это полезным свойством, то, может, и монады полезны?

[identity profile] zamotivator.livejournal.com 2012-10-11 11:17 pm (UTC)(link)
> Вот смотрите, вынесенное в отдельную сущность IO позволило Хаскелю стать одним из первых языков с хорошей поддержкой SMP. fortkIO это примерно конец 1990-х, если я не ошибаюсь.

А толку? MySQL на сях долго страдал на ядрах больше четырёх, но его взяли и починил в итоге.
Починили, а не на haskell переписали.

И я вам сейчас открою страшный-страшный секрет. Я вот в октябре 2010 был на Monty Programming Conference.
Туда приехал представитель компании Intel. За свой счёт (счёт Intel я имею ввиду). Он советовался с разработчиками MySQL, как ему правильно тестировать качество сгенерированного интеловским компилятором кода и качество новых процессоров на примере MySQL.

Вы понимаете? Под презренный MySQL написанный на презренном Си INTEL ЖЕЛЕЗО ЗАТАЧИВАЕТ.

Ваш haskell со своим SMP могут продолжать гнить на задворках. Под android и ios его до сих пор нету, ЕМНИП.
Си, Джава - есть.

Хорошая поддержка SMP. И это всё? Сочувствую.

[identity profile] thesz.livejournal.com 2012-10-11 11:20 pm (UTC)(link)
Вы говорите про существующую программу. В этом случае понятно, что переписывать не стоит.

Спрошу с другой стороны. Стоит ли писать новую программу на Хаскеле? Ту, которую вы до сих пор не писали, но от которой много ждёте.

[identity profile] zamotivator.livejournal.com 2012-10-11 11:24 pm (UTC)(link)
Смотря какую программу.
Назовите задачу, и скажу:
1) компетентен ли и квалифицирован ли я достаточно в этой области, чтобы выбирать язык программирования для этой задачи
2) если (1) - да, то какая язык и платформу следует выбирать и почему.
Edited 2012-10-11 23:24 (UTC)

[identity profile] thesz.livejournal.com 2012-10-11 11:50 pm (UTC)(link)
Ну, вот возьмите ради прикола решение систем уравнение для нерегулярных сеток. Аэродинамику и нагрузки на самолёт/автомобиль считать. Система простая Ax=b, где A - разрежена (количество элементов O(N)), не имеет регулярной структуры, за исключением симметрии, и велика (N в районе десятков миллиардов - почему нет?). Решают её итеративным способом, используя метод сопряженного градиента, ибо иначе нельзя.

То есть, вам понадобится уметь параллелить задачу на одной машине и параллелить задачу на многих машинах. Да ещё и свертку считать (для определения останова).

А ещё прикольней интегратор для системы из миллиардов транзисторов. SPICE модель памяти считать, как много потребляет, например. Каждый транзистор состоит (в зависимости от модели) от пяти до 15 элементов. Рунге-Кутта, например, неустойчив к выбору шага (стр. 91), вы не поймёте, когда система взорвалась. Надо придумать способ динамического выбора шага интеграции, чтобы не тратить зазря много времени.

[identity profile] zamotivator.livejournal.com 2012-10-11 11:55 pm (UTC)(link)
Для прототипирования обоих задач, пожалуй, подойдёт лучше всего matlab или аналоги.


Для production инсталляциии первой задачи - SciDB. Само то для хранения и вычисления на разреженных массивах, математики в составе много, опять же.
Хотя не самые типичные задачи, всё сильно зависит от того, на чём эти вычисления делаются уже, какие существуют библиотеки, etc. Может вполне оказаться, что считать придётся на Fortran и трахаться с его кластеризацией.

Насчёт второй не знаю деталей этой предметке, ничего сказать не могу.

[identity profile] thesz.livejournal.com 2012-10-12 12:03 am (UTC)(link)
Для второй задачи есть интересный вариант решения: на "бесконечных" списках. По моим прикидкам подходит практически идеально: на лету генерируются интеграторы и можно выбрать либо сложность генерирования, либо шаг времени. Требует вычисления обратной матрицы, как я понимаю, и я думаю, как присобачить к этому итеративные методы

Что опять же интересно, про эту статью знают либо те, кому я рассказал, либо те, кто знает Хаскель. ;)

Ибо кому ещё важны ленивые вычисления.

[identity profile] zamotivator.livejournal.com 2012-10-12 12:08 am (UTC)(link)
Про вторую задачу я сказал уже, что не знаю.
Но в том же Питон с его yeild ленивые бесконечные списки делаются элементарно.
Edited 2012-10-12 00:08 (UTC)

[identity profile] thesz.livejournal.com 2012-10-12 12:17 am (UTC)(link)
>Питон с его yeild

Нет.

Это генерация on-demand (call-by-name), не call-by-need.

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:19 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:22 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:23 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:39 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:40 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:39 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:40 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:47 (UTC) - Expand

[identity profile] voidex.livejournal.com 2012-10-12 09:21 am (UTC)(link)
Кстати о питоне. Пишу сейчас SublimeHaskell плагин.
С чем я столкнулся за пару часов?
1. Чтобы передать в функцию параметр, который хочется поменять, надо, чтобы он не был числом\строкой и прочим. Вот массив или словарь меняются.
2. Чтобы подписаться на обновление параметра (из настроек), надо написать такую строку:
get_settings().set_on_change('foo', lambda: self.setting_changed('foo'))
Мне надо подписаться на три. Если подписываюсь на три — саблайм падает. Если на один — ок. Хотя это, конечно, проблема не в питоне.
3. Так как мне пришлось неплохо порефакторить, даже на таком небольшом кол-ве исходников я не раз упускал какое-то изменение. Особенный шик в том, что код по-разному ведёт себя под Windows и Ubuntu (привет, кроссплатформенность). Официально он должен кидать исключение при попытке читать settings не из главного потока, но под Ubuntu через раз работал. Под виндой кидал стабильно, из-за чего отлаживал я под ней.

1-й пункт я прекрасно понимаю, но не поверю, что он "интуитивно понятен" тем, кто никогда не программировал на чём-то подобном.
2-й чёрт с ним, третий ожидаем для динамики, не считая возни с settings, которые там кидают, а сям — нет, а так как авторы писали только под Linux, под Windows плагин ожидаемо нихрена не работал вообще.

Update:

Пункт 4.
А сейчас мне нужно понять, как преставлена инфа о модулях, которые пропарсила внешняя тулза. Понятно, как, читаю исходники, что где пишется. Благо класс сам всего на 100 строк.
Edited 2012-10-12 09:31 (UTC)

[identity profile] thesz.livejournal.com 2012-10-12 11:41 am (UTC)(link)
Фортран слишком беден для прототипирования. Для второй задачи вы даже алгоритма оптимального не знаете, а уже Фортран выбрали.

А если я вам boolean SAT подкину, чтобы для Exascale подошёл? Опять же, параллельный внутри и между машинами. Там рекурсия и всякий backtracking. Неужто тоже Фортран выберете?

(Anonymous) 2012-10-13 03:19 pm (UTC)(link)
Про прототип в условиях не было сказано. Лучше скажите на чем продакшн будете писать, учитывая, что надо соревноваться в скорости с современными быстрыми спайсами. Они сейчас достаточно вылизанные и хорошо параллелятся.

[identity profile] thesz.livejournal.com 2012-10-15 01:07 am (UTC)(link)
Что такое "современные быстрые спайсы"? Извините, я волапюк не понимаю.

[identity profile] thesz.livejournal.com 2012-10-15 01:10 am (UTC)(link)
А! Понял!

Это SPICE на кластерах.

Так они редки и платны, как незнамо что. Virtuoso чуть ли не единственный пример.

(no subject)

(Anonymous) - 2012-10-15 14:07 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 14:47 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-15 20:13 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 21:06 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-15 22:04 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 23:19 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 23:20 (UTC) - Expand

[identity profile] thesz.livejournal.com 2012-10-11 11:54 pm (UTC)(link)
(на всякий случай)

Я облизываюсь на эти задачи. Времени не хватает. ;)

[identity profile] migmit.livejournal.com 2012-10-15 07:30 am (UTC)(link)
> починить нужно сущности, неадекватные по сложности

Супер. Вот когда в императивных языках починят присваивание, тогда приходите.

[identity profile] metaclass.livejournal.com 2012-10-12 05:12 am (UTC)(link)
Это ты еще внутренностей виндовс-рантайма хаскеля не смотрел наверно :)
Там все эти сказки про зеленые потоки, ожидания i/o и прочая асинхронность превращены в ебаную срань из костылей и утечек хендлов.
Короче, любимый пример с пиздатейшим TCP-сервером на хаскеле в пару строк под виндой под небольшой нагрузкой дохнет в сраку :)

[identity profile] nivanych.livejournal.com 2012-10-12 05:38 pm (UTC)(link)
Что-то тут не то.
Пару лет назад, я писал падвенду на хацкеле — ничего не падало, коннектов воспринимало сколько угодно.
Не хочется больше падвенду писать, но по другим причинам, с GHC не связанным.

[identity profile] thesz.livejournal.com 2012-10-12 07:41 pm (UTC)(link)
Что за любимый пример?

Спрашивали ли вы у [livejournal.com profile] awson насчёт веб-сервера под Windows? Он прицепил кого-то из Хаскельных серверов к веб-серверу в ядре Windows и получил производительность уровня Линукса.

[identity profile] metaclass.livejournal.com 2012-10-12 07:56 pm (UTC)(link)
Хм, в таком виде может получится неплохо. В винде http.sys поддерживает API для http-серверов.