Doge

Doge


Ну ладно. Достаточно странные претензии, точнее, неясные. Что такое средненький рантайм и как отсутствие тайпклассов (которые в принципе есть только в одном языке) и хкт ограничивают архитектуру?


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


Отсюда недостаток фич языка, там, где в других языках фичи запиливают за пару пулл реквестов, в окамле (и хаскеле) на реализацию уходят годы. Оно и понятно, например, в мультикор ветке, которая еще не готова, уже есть описанная и верифицированная memory model. Какие языки (кроме крестов и жабы) могут похвастаться наличием формализованной memory model? В купе с алгебраическими эффектами, которые тоже входят в мультикор ветку, обо всем этом уже написано с десяток бумаг, и все это тянется уже 3 года. Но, когда будет готово, скорей всего будет работать так, как того ожидаешь (привет сломанные атомики с11))). К слову мультиков к хаскеле пилили тоже больше 4 лет. Тоже касается и modular implicit (в той же ветке возможны зависимые типы), ее пилят уже три года, и она тоже находится на стадии проверки на soundness. К слову о soundness, окамл один из немногих языков, для которого не доказана тьюринг полнота тайпчекера (unlike scala, rust etc). Строки в окамле - буфферы чаров, для нормализации и работы с кодпоинтами есть сторонние либы. Это, как по мне, тоже не то чтобы минус, ибо лучше так, чем как в пистоне3, где юникод строка представлена последовательностью кодпоинтов, что в общем-то не очень корректно (и ведет к неожиданным исключениям в некоторых случаях). Ну то есть идиома "если что-то есть, то оно работает" мне больше нравится, чем куча фич, создающих проблемы тут и там.


Что касается рантайма, за исключением отсутсвия shared memory паралеллизма я не вижу в нем проблем, с версии 4.03 там low latency GC, который дает задержки меньше, чем гц в практически любом другом языке, новый инлайнер и фреймворк оптимизации в компиляторе flambda, который как раз переписывают к следующей версии (и тоже довольно тщательно [1]). Ну и мультикор надвигается медленно, но верно.


Касательно библиотек не знаю, что такое бедная экосистема, но качество и количество либ меня радует. К либам в целом подходит то же описание, что и к самому языку, они очень качественные и само коммьюнити состоит из людей, которые очень глубоко шарят в том, что делают. Ну и сами либы довольно практичные, недавно видел комментарий на hn по этому поводу [2]. Ну то есть есть проект mirage, из которого вышло огромное количество полезных либ для системного ПО (своя реализация git, файловых систем, алгоритмов сжатия, тлс слой, сервер и миддлвэр, виртуализация), есть куча сторонних популярных либ от других проектов (юникод с довольно годным введением в юникод [3], owl [4], графика, звук и мультимедиа от создателей liquidsoap, монады от авторов bap, всяких шаблонизаторов, транспайлеров в жабаскрипт, пдф и проч.). Качество всего этого обычно меня устраивало куда чаще, чем во многих других языках. Ну и 2к либ в репах это не мало.


Что касается фич языка, то модули = объекты = тайпклассы, так что не вижу проблемы в отсутсивии последних. Честно говоря фичи окамла мне как раз показались куда как более практичными, чем hkt и тайпклассы из окамла. Что есть:


1) Модули. модули можно создавать, наследовать и отображать в другие модули используя функторы (функции над модулями). Модуль - это структурный типы, потому поддерживают структурный сабтайпинг, что позволяет использовать один и тот же модуль как параметр разных функторов не заморачиваясь с иерархиями тайпклассов. Много примеров с активным использованием модулей можно увидеть мираж [5] и bap [6]. С помощью модулей можно реализовать статические безопасные контейнеры (например, Map - функтор от модуля, реализующего Ord, Hashtable - функтор от модуля, реализующего интерфейс Hash, подстановка происходит в компайл тайме в отличие от тайпклассов, причем один и тот же модуль благодаря структурным типам может реализовывать нестколько интерфейсов), и другие абстрактные вещи (в том же мираже разные части ос это просто функторы от таймеров, блочных устройств, файловых систем и других интерфейсов)


2) Сабтайпинг ковариантный и контрвариантный, объекты (обычные рекорды с поддержкой методов и сабтайпинга) и polymorphic variants (обычные тип-суммы с поддержкой сабтайпинга), и, соответственно, row polymorphism. Добавляет динамизм не лишая статических проверок [7] [8]


3) GADT, про них много написано.


4) First-class modules. При желании можно использовать модули в рантайме как параметры функций и обычные переменные. Сравнительно бесполезная фича при наличии объектов, но на основе ее пилят ad-hoc polymorphism (модули подставляются как параметр функции неявно компилятором, как в coq, так и называется modular implicits) и можно инкапсулировать состояние в модуль, что в каком-то смысле чище, или по крайне мере имплицитнее, инкапсуляции в объект/класс. Используется много где, как ни странно, например caqti, абстрактная либа над разными sql бд при подключении к бд возвращает модуль с интерфейсом бд.


-) Когда-нибудь будут эффекты [9]


[1] https://blog.janestreet.com/proofs-and-refutations-using-z3/


[2] https://news.ycombinator.com/item?id=11371382


[3] http://erratique.ch/software/uucp/doc/Uucp.html#uminimal


[4] https://github.com/ryanrhymes/owl


[5] https://github.com/mirage/ocaml-git/blob/master/src/git/mem.ml


[6] https://github.com/BinaryAnalysisPlatform/bap/blob/master/lib/bap_plugins/bap_plugins.mli


[7] https://www.cl.cam.ac.uk/teaching/1415/L28/rows.pdf


[8] http://kcsrk.info/ocaml/types/2016/06/30/behavioural-types/


[9] https://github.com/ocamllabs/ocaml-effects-tutorial

Report Page