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] voidex.livejournal.com 2012-10-11 07:47 pm (UTC)(link)
СУБД писать проще, чем хелловорлды на Haskell?

[identity profile] zamotivator.livejournal.com 2012-10-11 07:48 pm (UTC)(link)
В разы. Там хотя бы понятно, что нужно и откуда ноги растут.
Edited 2012-10-11 19:48 (UTC)

[identity profile] voidex.livejournal.com 2012-10-11 07:50 pm (UTC)(link)
У знакомой мне девушки с хелловорлдом, что умеет работать с командной строкой, на хаскеле проблем с первого же дня не было. Мне кажется это потому, что она кроме хаскеля ничего не видела.

[identity profile] zamotivator.livejournal.com 2012-10-11 07:53 pm (UTC)(link)
Не, ну написать что-то работающее - это немножко не то.
Я хочу написать код, который я понимаю
Каждый раз сажусь, смотрю на этот долбанный IO, иду читать про него, через четыре часа вываливаюсь из дремучих дебрей с мыслями "да пошло оно всё в жопу".

[identity profile] voidex.livejournal.com 2012-10-11 08:42 pm (UTC)(link)
Мне правда интересно, что там сложного?
Я понимаю, может быть сложно, когда пытаешься понять, как же это так, чистота и ввод-вывод, монады какие-то. Ну так это всё равно что таблицы виртуальных функций изучать. Без этого знания можно писать, хотя лучше с ним.

[identity profile] zamotivator.livejournal.com 2012-10-11 08:44 pm (UTC)(link)
Я без этого знания писать не могу

[identity profile] voidex.livejournal.com 2012-10-12 01:07 am (UTC)(link)
А ведь полезный навык-то

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

Разницу нужно объяснять между этими двумя вещами?

[identity profile] voidex.livejournal.com 2012-10-12 01:43 am (UTC)(link)
Надо учиться писать, чтоб всё получалось, и не понимать при этом, как.
Чтобы выполнять трюки на велосипеде, понимание того, какие процессы там протекают, второстепенно.

[identity profile] metaclass.livejournal.com 2012-10-12 05:27 am (UTC)(link)
Костыли. Потом возникает "какая-то проблема" а вы сидите и мямлите работодателю и заказчикам "ну ээ, ыы, ну это там ленивость и whnf какой-то". Вместо того, чтобы сразу понять, в чем проблема.

[identity profile] thesz.livejournal.com 2012-10-14 11:06 am (UTC)(link)
На любой ваш анекдот у меня найдётся свой.

В геймдеве мне довелось ускорить работу игровой физики в пять раз для некоторых сценариев использования. Начальство было довольно, ибо создатель библиотеки на вопросы отвечал "не надо создавать большое количество сталкивающихся объектов" и "это нормально". C++, где "всё понятно".

В любом случае, "сидеть и мямлить" плохо, надо решить проблему, тем более, что она техническая. Также плохо решать проблемы до их возникновения, то есть, бессмысленно учить внутренности, если собираешься решать высокоуровневую проблему.

Кстати, проблема Забиватора показывает пробел в подходе Джоэля Спольски. Джоэль считает, что если человек освоил указатели, то он освоит всё, что угодно. Забиватор опровержение этого тезиса, что несомненно полезно.

Есть также другой подход, более абстрактный. Авторство не припомню. Считается, что программист работает с системами уровня заклинаний. "Надо произнести бугабага, чтобы получить зюзю. Надо произнести выкупаку и подпрыгнуть, чтобы окрасить бущу в фиолетовый цвет. Поэтому надо произнести гыгабука рыкужапу, чтобы получить фиолетовую зюзю." То есть, надо сделать так-то, чтобы получить требуемое, и никто на свете не скажет тебе, почему надо поступить именно так. Ментальная модель, если и формируется, формируется не совсем по правилам реального мира. Это как у квантовых физиков-теоретиков.

[identity profile] zamotivator.livejournal.com 2012-10-12 06:38 am (UTC)(link)
А потом мы получаем глючное гавно, ага.

[identity profile] voidex.livejournal.com 2012-10-12 08:08 am (UTC)(link)
А если не получаем, что вы тогда делать будете?

[identity profile] zamotivator.livejournal.com 2012-10-12 08:11 am (UTC)(link)
Радоваться.

[identity profile] metaclass.livejournal.com 2012-10-11 07:54 pm (UTC)(link)
В общем, да.
Если задаться целью написать сложносочиненную систему - с базами данных, железом, GUI, веб-сервисами, да еще на нескольких языках c разными библиотеками - то с хаскелем мы упремся в то, что сокращение размера кода алгоритмов за счет лаконичности языка с лихвой компенсируется boilerplate кодом для FFI и прочим взаимодействием с внешним миром.

[identity profile] thesz.livejournal.com 2012-10-11 09:35 pm (UTC)(link)
Я опять потерял мысль где-то в середине, в районе "на нескольких языках".

Почему тогда Хаскель упрётся, а другие языки нет?

[identity profile] metaclass.livejournal.com 2012-10-12 05:03 am (UTC)(link)
Потому что другие языки используют ADO.NET, JDBC и прочие готовые либы и фреймворки.
И починить эти либы можно, не выходя из обычных способов работы с языком.
На хаскеле сразу втыкаешься в hackage и то, что авторы либ их поддерживают от случая к случаю.
А попытка починить самостоятельно втыкается в то, что у каждого автора свой стиль использования языка, а уж если там оптимизация производительности имеется - то закапывать лучше сразу.

[identity profile] thesz.livejournal.com 2012-10-12 11:32 am (UTC)(link)
>И починить эти либы можно, не выходя из обычных способов работы с языком.

Опа! Это как?

>А попытка починить самостоятельно втыкается в то, что у каждого автора свой стиль использования языка, а уж если там оптимизация производительности имеется - то закапывать лучше сразу.

Опа! Это только у Хаскеля такое?

[identity profile] metaclass.livejournal.com 2012-10-12 11:42 am (UTC)(link)
Да, отсутствие единообразного стиля между разными разработчиками в основном наблюдается в хаскеле.

[identity profile] thesz.livejournal.com 2012-10-12 11:47 am (UTC)(link)
Хорошо, хоть "в основном в Хаскеле", хоть не "только в Хаскеле".

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

[identity profile] metaclass.livejournal.com 2012-10-12 11:56 am (UTC)(link)
А, да. Это все-таки продолжение достоинств языка.