Entry tags:
Динамическая типизация, или статическая типизация для ленивых
Вчера
ivan_gandhi сделал замечание что я, пользуясь динамически типизированной кложурью, при этом требую, чтобы в Java проверяли входные параметры на валидность. (Если что, проверка валидности в дотнете есть на каждом шагу, а объяснения вида "экономят циклы и не делаю проверки" в контексте жабы, тяжелого железа, JIT и прочего звучат крайне странно).
Собирался на эту тему устроить срач с утра, но
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
Собирался на эту тему устроить срач с утра, но
Так вот, динамически типизированными языками мы пользуемся от бедности - нету статически типизированных языков, которые давали бы ту же функциональность.
Например, я хочу использовать кортеж с именованными полями (потому что позиционные кортежи нихера нечитабельны и их тип вида 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
no subject
Ну никто же так не делает, причем тут вообще динамическая типизация? Формально даже статическая типизация не обязана этому мешать.
no subject
(даже странно слышать что в C# ничего подобного нет)
no subject
no subject
no subject
- об'явить case class MyRecord(x:Int = 0, s:String = ""),
- сослаться на него везде, где надо,
- об'явить новый case class MyOtherRecord(x:Int = 0, s:String = "", y:Int),
- и как-то написать трансформацию из MyRecord в MyOtherRecord.
Выходит довольно многословно.
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Сравните 3 кода:
public void execute(String sql) throws Exception {
a.
if(sql == null) throw IllegalArgumentException("sql must be not null");
b.
if(sql == null) throw NullPointerException("sql must be not null");
c.
sql = sql.toLowerCase();
а от б отличается только классом исключения, а от ц только сообщением. Вы видите полезную разницу? Я -- нет.
Зачем писать бесполезный код? Достаточно задокументировать, что @throws NullPointerException if sql is null
no subject
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Работает же.
> объявляемые по месту типы данных (чтобы каждый раз при разработке не переключаться между объявлением типа и конструированием данных по этому типу)
Я спрашивал здесь, где должны быть видны эти объявляемые по месту типы данных. Там возикают проблемы вроде, чего делать, если в нескольких функциях объявлены типы с одним именем, что если у этих типов разная сигнатура, что если уже существует тип с таким именем, объявленный не по месту, и тд. И даже стал делать такое на Немерле, но не осилил по техническим причинам, хотя каких-то принципиальных проблем запилить костыльную реализацию, которая мне пришла в голову, вроде нет.
В любом случае, держать в уме, какой там тип был, во что он превратился после расширения сложно. То есть мне это чем-то point-free style напоминает.
no subject
(no subject)
no subject
Т.к. единственное их применение - возврат нескольких значений из функции, то и проблему нужно решать на корню.
Вместо кортежей нам предлагается использовать всё-таки именованные data class. Мол, если вам придётся всё-таки назвать это - заставит лишний раз подумать, нужно ли оно в принципе =)
http://blog.jetbrains.com/kotlin/2012/09/how-do-you-traverse-a-map/
no subject
no subject
no subject
Людям работать надо, а не на язык дрочить.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(Anonymous) - 2012-10-11 20:40 (UTC) - Expand(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
...
...
...
...
...
...
...
...
...
...
...
(no subject)
(no subject)
(no subject)
(no subject)
(Anonymous) - 2012-10-13 15:19 (UTC) - Expand(no subject)
(no subject)
...
(Anonymous) - 2012-10-15 14:07 (UTC) - Expand...
...
(Anonymous) - 2012-10-15 20:13 (UTC) - Expand...
...
(Anonymous) - 2012-10-15 22:04 (UTC) - Expand...
...
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(Anonymous) - 2012-10-11 20:37 (UTC) - Expand(no subject)
(no subject)
(no subject)
no subject
У Хаскела очень высокий порог вхождения, который теоркат-гики не особо собираются снижать. Вероятность встретить статью о реализации какого-нибудь квазиморфизма гиперфункторов гораздо выше вероятность встретить статью про, не знаю там, чат-сервер на Comet.
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
(no subject)
no subject
и заодно показывает предыдущую задеплоенную модель, чтобы можно было сравнить и скрипты апгрейда пописать.
no subject
no subject
российскуюбелорусскуюдемократиючто там у вас.var v = new { Amount = 108, Message = "Hello" };
Или если угодно окамл и его объекты, которые можно создавать вообще без объявления класса, и все будет статически проверено. Короче, "нет языков" - не верю.
no subject
(no subject)
(no subject)
(no subject)
no subject
Впрочем, я не исключаю, что получится как с IO в хаскелле: внутри чистый костяк, а снаружи небольшая нечистая обертка. Будет внутри строго типизированный костяк, а на системном уровне - динамическая типизация, duck typing, protocol negotiation, обработка ошибок, fallback и пр.
no subject
(Anonymous) 2012-10-11 06:24 pm (UTC)(link)Они есть просто потому, что без них надо вокруг каждого желания прыгать с бубном!. Я даже жду прагмы динамик он и динамик офф...
no subject
Look no further!
(no subject)
no subject
pack .w.f -anchor "w" -expand 1 -fill "x" -ipadx 2px -ipady 2px -side "left"
no subject
ТОП: 11:30 MSK
Почитать текст со всеми комментариями по ссылке (http://tools.t30p.ru/?http%3a%2f%2fmetaclass.livejournal.com%2f735575.html).
Это Ваш 8-й ТОПовый пост в этом году.
Посмотреть статистику автора можно в карточке топблогера (http://rating.t30p.ru/?metaclass.livejournal.com&p=tops).
no subject
> Хаскель сразу закапываем - там на каждый случай имеется 3-4 расширения и 10 пакетов в hackage различной степени недоделанности
Записи -- это такое общепризнанное слабое место в Хаскелле.
> идиоматический подход - писать в point-free style, чтобы коллеги не разобрались,
Идиоматичное применение point-free -- это последовательное применение нескольких ф-ий, т.е. вместо
f x = a $ b $ c $ d x
пишут
f = a . b . c . d
а вот когда начинаются ((.) . (.)) <=< flip (first >>> second), то это уже неидиоматично, т.к. затрудняет чтение.
> а работать в продакшене можно только с теми сторонними библиотеками, которые я могу сам починить.
Неправда ваша. Сырых библиотек хватает, но есть и очень качественные.
> Второй use-case, где "вроде бы динамическая типизация" - это когда я делаю документы в виде кложурных структур данных, подгоняя комбинации списков-мапов-массивов-множеств под предметную область.
Так и не понял, что имеется ввиду.
> В кложуре же это делается в лоб, а в хаскеле в один список не положишь три разных по структуре(типу) раздела документа.
А что потом делают с этими разделами? Действительно ли они настолько разные, что их никак нельзя описать?