Толочь воду в ступе

Apr 15, 2011 00:43

Пост навеян свежим ПФП. Статья про circumflex, вот этим вот:

// Выбрать все города Швейцарии, вернуть Seq[City]:
SELECT (ci.*) FROM (ci JOIN co) WHERE (co.code LIKE ”ch”)
ORDER_BY (ci.name ASC) listСтоило ли огород городить, если на выходе всё равно получается нечто, что ( Read more... )

article, typing, orm, common lisp, macros, sql, dsl, lisp, metaprogramming, pfp

Leave a comment

nivanych April 15 2011, 10:57:13 UTC
> С каких пор реализация тривиального,
> прекрасно описанного в литературе
> алгоритма на 100 строчек,
> стала чем-то неэлементарным?

Усугубляя - конечно, элементарно!
Ведь есть готовая реализация, надо только copy-paste этот код!
Haskell так и вообще готов!

Я не говорю о том, что это как-то сложно. Но времени уйдёт.
Сделать некую работающую систему, это уже не элементарная задача.
Hindley-Milner - это ж ещё далеко не всё в языке и системе типов.
Собственно, в интересных мне случаях он и не работает ;-)

А придумать хорошую систему типов всегда сложно, даже если это, всего лишь, создаваемый тобой DSL.
Поскольку, всегда речь идёт о чём-то, эквивалентном какой-то (часто, небольшой) части логики обоснования свойств программы.

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

Естественно ;-)
Ну хорошо, в языке с вменяемой системой типов, хотяябы, как ML-подобное, это совсем запросто почти любому, кто освоил этот язык.
А чтоб криво и глючно сделать, это уж совсем голову выкинуть надо.

> сделать так, чтобы оно работало нормально

Сложности _только_ в оптимизации, больше ни в чём.
И не настолько уж сильно бОльшие сложности, по кравнению с классическим выводом типов.
Собственно - реализовать быстрый eval (который считают неотъемлемой частью большинства динамических языков), это сложновато, да - надо баллансировать между временами компиляции и исполнением кода.
Но кто это делает, оптимизацию эту, для динамических языков?

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

Собственно, я вот вспомню только один случай, когда хоть как-то оптимизировали динамические типы, это был какой-то лисп (CMU?). Это, конечно, не значит, что больше нету оптимизированной динамики, просто я не встречал. Ну, о всяких HipHop, надеюсь, говорить не будем ;-)
Вообще, любопытно. Приведите, кто-нибудь, примеров шустрого динамически-типизированного языка?

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

И уж что точно, так это, элементы динамической системы очень запросто встраиваются в любую вменяемую статически типизированную систему, а вот обратное неверно _даже_ для лиспа. Впрочем, тут могу ошибиться - сильно уж зависит от точной формулировки "элементы статической системы".

Reply

nivanych April 20 2011, 05:55:24 UTC
Спасибо.

Reply

nivanych April 16 2011, 06:08:50 UTC
> Hindley-Milner - это ж ещё далеко не всё в языке и системе типов.

Ну у тебя же речь шла о Хиндли-Милнере. Вообще тут есть очевидное утверждение - сделать хорошую реализацию статической типизации намного проще, чем хорошую реализацию динамической. Потому что все, что нужно сделать для статики - это реализовать некую _внешнюю_ по отношению к компилятору/среде исполнения софтинку, которая всего-то анализирует синтаксическое дерево, выполняет тайпчек с тайпинференсом и лепит на это дерево некую доп. информацию. Все совершенно тривиально, все алгоритмы известны (еще и с референсными реализациями на функциональных языках, ага). Работать _плохо_ это просто не может, оно либо работает либо нет. С динамикой так не выйдет - здесь надо забуриваться глубоко в кодогенератор/рантайм.

> А придумать хорошую систему типов всегда сложно

А зачем придумывать?

> Сложности _только_ в оптимизации, больше ни в чём.

И эти сложности ведут к куче совершенно нетривиальных проблем, для решения которых, вобщем-то, никакого the best way на данный момент не существует.

> И не настолько уж сильно бОльшие сложности, по кравнению с классическим выводом типов.

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

> Приведите, кто-нибудь, примеров шустрого динамически-типизированного языка?

как раз тот факт, что их нет и говорит о том, что реализация шустрого динамического языка - задача очень сложная :)

> И уж что точно, так это, элементы динамической системы очень запросто встраиваются в любую вменяемую статически типизированную систему, а вот обратное неверно _даже_ для лиспа.

Это, на самом деле, софистика. При помощи лиспо-макросов можно реализовать любую статику в виде компайл-тайм чекера, аналогично в рамках статики можно реализовать динамику, запилив руками ее рантайм.

Reply

nivanych April 20 2011, 05:50:51 UTC
> С динамикой так не выйдет -
> здесь надо забуриваться глубоко в кодогенератор/рантайм.

Гм. Мне так кажется, что надо совершенствовать вывод типов и компилировать в какое-нибудь GRIN-подобное.
Ну можно и попроще backend.
Сам я не делал вывод типов для динамики, но по словам "очевидцев" (тех, кто пробовал), даже минимально получившийся вывод уже очень неплохо работает. И скажем, обогнать даже современный GHC не так и сложно (у него там других проблем при оптимизации навалом).
То есть, упрощённо - делается любой примитивный вывод типов, и он уже неплохо работает.
Самому время тратить и проверять совершенно неохота, да и нет оснований не доверять тому товарищу.
Это не так?

>> А придумать хорошую систему типов всегда сложно
> А зачем придумывать?

Затем, что для данной задачи существующие чем-то не устраивают и надо их обработать напильником, специализировать, чтобы устраивали. Но обычно DSL'и, конечно, очень примитивные и таких раздумий не требуют.
Например, делаю я DSL для всякого IO и даже распределённого.
Но я не беру уже существующие всякие \pi, у меня своя идея (семантика пучков).
Под эту идею надо свою логику, то есть, свою систему типов.
В зависимых типах оно нормально описывается, в хаскеле уже надо Template Haskell либо воротить в динамике.

>> И не настолько уж сильно бОльшие сложности,
>> по кравнению с классическим выводом типов.
> А какие сложности с классическим выводом типов?

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

> фулл тайп инференс вообще не нужен.

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

> При помощи лиспо-макросов можно реализовать
> любую статику в виде компайл-тайм чекера

Может быть, я и не прав.
Как во время компиляции отличить в конкретном листочке, скажем, плавучку от целого?
Тип, определённый по написанию, уже много, на что влияет дальше. Это неявное определение типа.
Впрочем, это только маленький практический момент.

Reply


Leave a comment

Up