Пост навеян свежим
ПФП. Статья про circumflex, вот этим вот:
// Выбрать все города Швейцарии, вернуть Seq[City]:
SELECT (ci.*) FROM (ci JOIN co) WHERE (co.code LIKE ”ch”)
ORDER_BY (ci.name ASC) listСтоило ли огород городить, если на выходе всё равно получается нечто, что
(
Read more... )
> прекрасно описанного в литературе
> алгоритма на 100 строчек,
> стала чем-то неэлементарным?
Усугубляя - конечно, элементарно!
Ведь есть готовая реализация, надо только copy-paste этот код!
Haskell так и вообще готов!
Я не говорю о том, что это как-то сложно. Но времени уйдёт.
Сделать некую работающую систему, это уже не элементарная задача.
Hindley-Milner - это ж ещё далеко не всё в языке и системе типов.
Собственно, в интересных мне случаях он и не работает ;-)
А придумать хорошую систему типов всегда сложно, даже если это, всего лишь, создаваемый тобой DSL.
Поскольку, всегда речь идёт о чём-то, эквивалентном какой-то (часто, небольшой) части логики обоснования свойств программы.
>> динамические типы способен соорудить любой студент хоть на сишечке.
> С одной поправкой - все это будет криво, глючно и тормознуто.
Естественно ;-)
Ну хорошо, в языке с вменяемой системой типов, хотяябы, как ML-подобное, это совсем запросто почти любому, кто освоил этот язык.
А чтоб криво и глючно сделать, это уж совсем голову выкинуть надо.
> сделать так, чтобы оно работало нормально
Сложности _только_ в оптимизации, больше ни в чём.
И не настолько уж сильно бОльшие сложности, по кравнению с классическим выводом типов.
Собственно - реализовать быстрый eval (который считают неотъемлемой частью большинства динамических языков), это сложновато, да - надо баллансировать между временами компиляции и исполнением кода.
Но кто это делает, оптимизацию эту, для динамических языков?
В общем, не могу я серьёзно воспринимать заявления о том, что динамические типы - это действительно сложная задача, а вот статические системы клепаются запросто и быстро.
Собственно, я вот вспомню только один случай, когда хоть как-то оптимизировали динамические типы, это был какой-то лисп (CMU?). Это, конечно, не значит, что больше нету оптимизированной динамики, просто я не встречал. Ну, о всяких HipHop, надеюсь, говорить не будем ;-)
Вообще, любопытно. Приведите, кто-нибудь, примеров шустрого динамически-типизированного языка?
А в большинстве случаев, код на динамически типизированных языках работает так небыстро, что говорить о какой-то сложности реализации нелепо. Тупо интерпретируют или только чуть более того. Чо тут сложно-то?...
И уж что точно, так это, элементы динамической системы очень запросто встраиваются в любую вменяемую статически типизированную систему, а вот обратное неверно _даже_ для лиспа. Впрочем, тут могу ошибиться - сильно уж зависит от точной формулировки "элементы статической системы".
Reply
http://sbcl-internals.cliki.net/tag%20bit
http://planet.sbcl.org/
http://insidelisp.blogspot.com/
Reply
Reply
Ну у тебя же речь шла о Хиндли-Милнере. Вообще тут есть очевидное утверждение - сделать хорошую реализацию статической типизации намного проще, чем хорошую реализацию динамической. Потому что все, что нужно сделать для статики - это реализовать некую _внешнюю_ по отношению к компилятору/среде исполнения софтинку, которая всего-то анализирует синтаксическое дерево, выполняет тайпчек с тайпинференсом и лепит на это дерево некую доп. информацию. Все совершенно тривиально, все алгоритмы известны (еще и с референсными реализациями на функциональных языках, ага). Работать _плохо_ это просто не может, оно либо работает либо нет. С динамикой так не выйдет - здесь надо забуриваться глубоко в кодогенератор/рантайм.
> А придумать хорошую систему типов всегда сложно
А зачем придумывать?
> Сложности _только_ в оптимизации, больше ни в чём.
И эти сложности ведут к куче совершенно нетривиальных проблем, для решения которых, вобщем-то, никакого the best way на данный момент не существует.
> И не настолько уж сильно бОльшие сложности, по кравнению с классическим выводом типов.
А какие сложности с классическим выводом типов? Это же элементарный алгоритм, описание которого займет максимум пару страниц (в сущности если хоть какие-то мозги есть - то можно и без описания, алгоритм очевиден). При реализации тоже никаких подводных камней нет. В чем тут вообще может быть проблема? Все-таки тайпинференс - это самое простое, что вообще есть в статике. Вот если у нас неразрешимая система типов (например, с зависимыми типами), то тогда нам придется применять нетривиальные алгоритмы, вводить эвристики - вот это уже будет сравнимо с аналогом динамики. Я уж не говорю о том, что фулл тайп инференс вообще не нужен.
> Приведите, кто-нибудь, примеров шустрого динамически-типизированного языка?
как раз тот факт, что их нет и говорит о том, что реализация шустрого динамического языка - задача очень сложная :)
> И уж что точно, так это, элементы динамической системы очень запросто встраиваются в любую вменяемую статически типизированную систему, а вот обратное неверно _даже_ для лиспа.
Это, на самом деле, софистика. При помощи лиспо-макросов можно реализовать любую статику в виде компайл-тайм чекера, аналогично в рамках статики можно реализовать динамику, запилив руками ее рантайм.
Reply
> здесь надо забуриваться глубоко в кодогенератор/рантайм.
Гм. Мне так кажется, что надо совершенствовать вывод типов и компилировать в какое-нибудь GRIN-подобное.
Ну можно и попроще backend.
Сам я не делал вывод типов для динамики, но по словам "очевидцев" (тех, кто пробовал), даже минимально получившийся вывод уже очень неплохо работает. И скажем, обогнать даже современный GHC не так и сложно (у него там других проблем при оптимизации навалом).
То есть, упрощённо - делается любой примитивный вывод типов, и он уже неплохо работает.
Самому время тратить и проверять совершенно неохота, да и нет оснований не доверять тому товарищу.
Это не так?
>> А придумать хорошую систему типов всегда сложно
> А зачем придумывать?
Затем, что для данной задачи существующие чем-то не устраивают и надо их обработать напильником, специализировать, чтобы устраивали. Но обычно DSL'и, конечно, очень примитивные и таких раздумий не требуют.
Например, делаю я DSL для всякого IO и даже распределённого.
Но я не беру уже существующие всякие \pi, у меня своя идея (семантика пучков).
Под эту идею надо свою логику, то есть, свою систему типов.
В зависимых типах оно нормально описывается, в хаскеле уже надо Template Haskell либо воротить в динамике.
>> И не настолько уж сильно бОльшие сложности,
>> по кравнению с классическим выводом типов.
> А какие сложности с классическим выводом типов?
Никаких, конечно.
Это давно и хорошо изученная тема с кучей готовых исходников.
Собственно, и в выводе типов для динамики сложностей немногим больше, что и хотел сказать.
Где-то, наверное, одинаковая сложность вывода типов для динамики и зависимых типов.
> фулл тайп инференс вообще не нужен.
Согласен. Достаточно его для "не очень сложных" типов, для "сложных", всё равно, лучше документировать, указывая явно.
Да и "не всегда" существует наиболее общий тип в интересных системах.
> При помощи лиспо-макросов можно реализовать
> любую статику в виде компайл-тайм чекера
Может быть, я и не прав.
Как во время компиляции отличить в конкретном листочке, скажем, плавучку от целого?
Тип, определённый по написанию, уже много, на что влияет дальше. Это неявное определение типа.
Впрочем, это только маленький практический момент.
Reply
Leave a comment