LINUX.ORG.RU

Галерка хочет мигрировать из Haskell в Rust, но не знает зачем

 ,


0

8

Дано (на самом деле этот раздел можно пропустить, чтобы не читать простыню, он написан во избежание лишних вопросов): друг работает в конторе с достаточно широким полем деятельности, но повсюду применяющей микросервисную архитектуру, либо просто разрабатывающую небольшие утилиты вроде драйверов, так что, вопросы легаси и т.п. не стоят. Миграция из языка в язык достижима практически без накладных расходов. Уже используются: haskell, c++ + asm, go. Для менее требовательных задач python, ruby, java. К первой тройке недавно добавился rust. Язык весьма зашёл некоторым разрабам, но не всей команде. Прямой руководитель сперва был воодушевлён, но результаты внедрения на практике оказались не столь впечатляющими. Если я правильно понял, ранее написанный драйвер на хаскеле, был переписан на Rust. Там переписывание одного и того же - нормальная практика, так как реальное оборудование не всегда совпадает с тестовым и документацией. Поэтому сперва делается тестовый образец на хаскеле/го, а затем — всё переводят на плюсы. Сейчас попробовали перейти на rust. Оказалось, что линуксовый драйвер написанный на rust с тем же алгоритмом выиграл всего лишь на 4% у хаскельного драйвера (да я тоже удивился, что они используют язык с gc в драйверах, но оказалось, все довольны), при этом разработка заняла 5 недель вместо чуть меньше месяца на хаскеле. Ок, чтобы совсем уж код на rust не выкидывать, переписали с ассемблерными вставками (там это норма). Всё бы ничего, и решили, что если бы писали на плюсах с асмом, вышло бы также по скорости. Вот только, вставки на асме заняли 40% полезного кода (для плюсов там такое тоже норма) и весь драйвер был в unsafe. Короче, они там пришли к выводу, что когда вставок на асме становится слишком много, проще взять плюсы, типа там даже безопаснее получается. Итого, rust рассматривают как замену go и хаскеля. Первых уже потеснили, значит очередь за хаскелистами. И тут разгорелась локальная «святая война». Хаскелисты утверждают, что haskell с монадками и клёвой типизацией якобы на практике не хуже раста, и даже безопаснее. Т.к. кто кого безопаснее пока не выяснили, а аргументы хаскеллистов не понимает никто, кроме них самих, вопрос пока подвис. Конечно, скорее всего они там сами разберутся, чай не дураки, гуглить умеют, но вдруг здесь у кого есть интересное чтиво по данному вопросу.

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

Собственно вопрос: где бы найти почитать взвешенный сравнительный анализ хаскеля и раста? Там с нормальным сравнением производительности, особенно (!) безопасности и прочее.

Если выигрыша по скорости нет, то хаскелль подвинуть не получится. Но я бы учёл то обстоятельство, что на хаскелле они пишут уже давно, а на расте только первый блин написали, и он совсем не оказался комом. Что, если они прокачают скиллы в расте, более вдумчиво начнут писать код (unsafe обертывать в безопасный API), и отрыв станет более впечатляющим?

Virtuos86 ★★★★★ ()

Я тоже заметил, что haskell может быть очень хорош по скорости, и кое-где выигрывать у rust (сюрприз, но иногда gc дает бонус в зависимости от задачи).

У haskell и rust очень много общего. Сам способ работы с объектами и типажами в rust почти содран с haskell за некоторым упрощением. Я не говорю о более простых вещах, таких как сопоставление с образцом, где аналогии просты выпирают.

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

dave ★★★★★ ()

ранее написанный драйвер на хаскеле,

Драйвер? На Хаскеле? Для House?

был переписан на Rust

Для Redox?

где бы найти почитать взвешенный сравнительный анализ хаскеля и раста?

Такое впечатление, что где-то замешаны наркотики.

tailgunner ★★★★★ ()
Ответ на: комментарий от th3m3

Ох уж эти тесты - в одном они даже собрать проект ниасилили (make error).

Haskell в плане безопасности гораздо гораздее раста, хотя бы из-за контроля над побочными эффектами + много фишек типизации.

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

Да и хаскель не стоит на месте - много проблем с GC (хотя и не все) решаются недавно введенными Compact regions - выделение объектов в особый регион, который не проходится GC-ом, если есть ссылка хотя бы на один объект из него. Это может очень помочь, если что ;-)

А вообще удивлен использованию языка с GC в написании драйверов. O_O

lazybones ()
Ответ на: комментарий от Virtuos86

Блин. Я не до конца дописал. Там вопрос стоит о расширении штата. Поэтому, там скорее думают кого нанимать: хаскелистов или растовиков.

Что, если они прокачают скиллы в расте, более вдумчиво начнут писать код

Да всё может быть. К слову, тот драйвер на хаскелле писали одни люди, а на расте переписывали другие. Первые более опытные.

next_time ★★★★ ()
Ответ на: комментарий от tailgunner

Для House? Для Redox?

подробностей не знаю - конторка не моя, с этими терминами не знаком

next_time ★★★★ ()

Вот еще мнение анонимуса:

https://www.linkedin.com/pulse/haskell-vs-rust-daniel-mery/

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

Первое естественно проще. Поэтому в плане легкости написания несложного, но быстрого кода раст впереди, втч благодаря отсутствию GC.

Но ты написал, что безопасность важнее и хаскель здесь на голову выше. Отсутствие ручной работы с памятью (да - переменные с определенным временем жизни это круто, но все же....), полный контроль над принципиальной возможностью побочных эффектов в любом месте кода. Кстати, насколько я знаю, с обработкой исключений в расте все куда хуже.

Опять же - гибкая система типов итд....

lazybones ()
Последнее исправление: lazybones (всего исправлений: 1)
Ответ на: комментарий от dave

При том, что Rust выгллядит как «lovechild of C and Haskell»...

сопоставление с образцом, где аналогии просты выпирают.

Сопоставление с образцом не для Haskell придумано и не из Haskell взято.

tailgunner ★★★★★ ()

В общем, похоже, что ТС толсто вбросил.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Такое впечатление, что где-то замешаны наркотики.

если вкратце, то почему? оба же языка нацелены на безопасность

к тому же, сами выше пишете:

«lovechild of C and Haskell».

next_time ★★★★ ()
Последнее исправление: next_time (всего исправлений: 1)
Ответ на: комментарий от lazybones

Haskell в плане безопасности гораздо гораздее раста, хотя бы из-за контроля над побочными эффектами + много фишек типизации.

Но ведь в Haskell нет контроля над побочными эффектами: в IO можно выполнять любой код. А в Rust хоть весь код и находится фактически в IO, зато он четко разделен на safe и unsafe. Ещё в Rust есть деструкторы которые позволяют следить что ресурсы не «утекают». Так что с моей точки зрения у них паритет в плане безопасности.

userd ()
Ответ на: комментарий от next_time

Такое впечатление, что где-то замешаны наркотики.

если вкратце, то почему?

Потому что ты рассказываешь о драйверах на Haskell.

оба же языка нацелены на безопасность

Нет. Haskell - академическая игрушка для академических задач, Rust - язык системного программирования; его подмножество safe Rust обеспечивает memory safety (не какую-то абстрактную «безопасность», а именно memory safety).

tailgunner ★★★★★ ()
Ответ на: комментарий от userd

Но ведь в Haskell нет контроля над побочными эффектами: в IO можно выполнять любой код.

«Контроль» не означает запрет ) И да - в IO возможны не любые побочки, чай ввод-вывод у нас не единственный возможный эффект ).

Контроль означает, что для любой функции ты можешь по ее типу сказать, что в ней может происходить, а что - нет. Принципиально нет.

lazybones ()
Ответ на: комментарий от tailgunner

Haskell - академическая игрушка для академических задач

Изначально да, но времена меняются ;-)

lazybones ()

Вот только, вставки на асме заняли 40% полезного кода (для плюсов там такое тоже норма) и весь драйвер был в unsafe. Короче, они там пришли к выводу, что когда вставок на асме становится слишком много, проще взять плюсы, типа там даже безопаснее получается

скорее всего криво спроектировали

хотя в целом логика верна, но по идее раст должен быть строго не хуже плюсов в аспекте безопаности

MyTrooName ★★★★★ ()
Последнее исправление: MyTrooName (всего исправлений: 1)

Кто бы что не говорил, а у раста несравненно больше перспектив стать коммерческим инструментом, за разработку на котором можно получать деньги. Хаскелл не будет таким никогда. Логично и с точки зрения и бизнеса, и работника предпочесть один инструмент другому.

Портянку разумеется не читал.

Im_not_a_robot ★★★ ()
Ответ на: комментарий от userd

Ещё в Rust есть деструкторы которые позволяют следить что ресурсы не «утекают»

В Haskell тоже есть средства управления ресурсами. И по поводу IO - кто-то заставляет писать весь код в IO ? В rust по факту ж так и есть ;-)

lazybones ()
Ответ на: комментарий от lazybones

Haskell - академическая игрушка для академических задач

Изначально да, но времена меняются ;-)

И что изменилось? Я не слежу за Haskell, но несколько лет назад слышал о том, как рулит Cabal. Сейчас слышу о том, как рулит Stack. Интересно, что будет следующим.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

При чем здесь stack, cabal и академичность ?

И таки да - stack весьма удобная надстройка над cabal. И да - она делает разработку проектов, втч коммерческих удобнее.

lazybones ()
Ответ на: комментарий от tailgunner

Потому что ты рассказываешь о драйверах на Haskell.

Да но, вы сказали «тяжёлые наркотики» ОС - на C# (Singularity) - вот где тяжёлые наркотики, а это так...

Haskell - академическая игрушка для академических задач

Его так авторы позиционируют? Где вы у них это прочитали?

next_time ★★★★ ()
Последнее исправление: next_time (всего исправлений: 1)
Ответ на: комментарий от lazybones

При чем здесь stack, cabal и академичность ?

Я спрашивал, что изменилось - Haskell перестал быть академической игрушкой? Когда? Что именно произошло - появился cabal? Появился stack?

А cabal и stack академичны в том смысле, что работа академиков - пробовать один подход за другим и публиковать результаты. Что происходит с разработанным кодом, их заботит мало.

tailgunner ★★★★★ ()
Последнее исправление: tailgunner (всего исправлений: 2)
Ответ на: комментарий от tailgunner

Haskell перестал быть академической игрушкой? Когда?

очевидно, для ответа на этот вопрос вы должны предоставить своё определение «академической игрушки»

next_time ★★★★ ()
Ответ на: комментарий от tailgunner

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

lazybones ()
Ответ на: комментарий от dave

Да ты не в теме!

Да, Холмс! Вы догадались об этом по моему «я не слежу за Haskell»? Я не в теме и пытаюсь выяснить, что такого случилось с Haskell, раз как минимум один человек перестал считать его академической игрушкой.

tailgunner ★★★★★ ()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Stack дает воспроизводимость сборки. Это более, чем довод так думать.

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

Касательно противопоставления cabal и stack. Вот сегодня я только проверял сборку проектов cabal разными версиями GHC с помощью stack. Фантастически удобно

dave ★★★★★ ()
Последнее исправление: dave (всего исправлений: 1)
Ответ на: комментарий от dave

Я не в теме и пытаюсь выяснить, что такого случилось с Haskell, раз как минимум один человек перестал считать его академической игрушкой.

Stack дает воспроизводимость сборки. Это более, чем довод так думать.

Ммм... нет. В «промышленности» уже десятки лет используются системы сборки, которые этого не гарантируют. Конечно, воспроизводимость сборки - это круто, но это прежде всего академический успех (который, конечно, полезен в практической работе).

Кстати, воспроизводимость сборки - это побитовое соответствие собранных артефактов? stack как-то записывает версию тулчейна?

Последние годы редко ломают обратную совместимость, но тогда спасает stack

Можно об этом подробнее (или ссылку)?

tailgunner ★★★★★ ()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от lazybones

И да - в IO возможны не любые побочки, чай ввод-вывод у нас не единственный возможный эффект

В IO возможны любые побочки, вплоть до сегфолта)
Rust при правильной инкапсуляции unsafe операций гарантирует отсутствие «состояний гонки» или использования ресурсов после их освобождения. Haskell не имеет borrow checker-а и не может предоставить таких гарантий.

Контроль означает, что для любой функции ты можешь по ее типу сказать, что в ней может происходить, а что - нет. Принципиально нет.

Haskell не дает возможности по типу функции определить безопасна она или нет: print и writeIORef x имеют одинаковый тип, но первая безопасна, а вторая — нет. В Rust же корректность доступа к памяти может быть доказана компилятором.

userd ()
Ответ на: комментарий от tailgunner

Stack фиксирует версию компилятора ghc и версии самых основных библиотек cabal, гарантируя, что они совместимы друг с другом. И мне показалось, что для такой всей из себя особенной системы Windows даже предоставляет уже заранее собранные бинарники некоторых библиотек, потому как на чистой Windows с тулчейном могут быть большие-пребольшие проблемы, а haskell - платформа, где почти все собирается из открытого кода.

Я под воспроизводимостью имею в виду, что на выходе получим функционально тот же бинарник и через 5-10 лет на всех поддерживаемых операционных системах. На счет побитового сравнения я бы не заморачивался. Не думаю, что это кого-то особо волнует.

Кроме того, stack позволяет подключать сторонние пакеты cabal, да хотя с того же github или с локальной файловой системы, или с чего-нибудь типа nexus, что важно для закрытой коммерческой разработки.

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

dave ★★★★★ ()
Ответ на: комментарий от dave

Я под воспроизводимостью имею в виду, что на выходе получим функционально тот же бинарник и через 5-10 лет на всех поддерживаемых операционных системах. На счет побитового сравнения я бы не заморачивался. Не думаю, что это кого-то особо волнует.

Разработчиков Rust волнует именно побитовая идентичность. Вообще требование редкое, но не уникальное.

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

А есть в сети какая-нибудь мурзилка по stack?

tailgunner ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Потому что может приводить к состоянию гонки.

$ cat main.hs 
module Main where
import Data.IORef
import Control.Monad
import Control.Concurrent

threadCount = 1000
upCount = 10000

makeFun r v = do
  replicateM upCount $ modifyIORef' r (+ 1)
  putMVar v ()

main = do
 r <- newIORef 0
 v <- newEmptyMVar
 replicateM threadCount $ forkIO (makeFun r v)
 replicateM threadCount $ takeMVar v
 res <- readIORef r
 print res
 print $ res == threadCount * upCount
$ ghc -threaded main.hs 
[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
$ ./main 
9330000
False

userd ()
Ответ на: комментарий от tailgunner

А есть в сети какая-нибудь мурзилка по stack?

Не в курсе. Не искал. Я довольно быстро освоился со stack после опыта с cabal.

dave ★★★★★ ()

Зачем, у Хацкеля либы повзрослее и получше должны быть, чем у школораста.

Valeg ★★★ ()
Ответ на: комментарий от tailgunner

stack как-то записывает версию тулчейна

Угу. См LTS. Более того, голый стек этот тулчейн автоматом разворачивает.

lazybones ()
Ответ на: комментарий от tailgunner

А есть в сети какая-нибудь мурзилка по stack?

На русском? https://ruhaskell.org/posts/utils/2015/07/13/from-cabal-to-stack.html

Для меня великий профит в том, что стало легче разворачивать несколько сборочных окружений на 1 машине. Ну и зависимости, да)

lazybones ()
Ответ на: комментарий от hateyoufeel

Согласен, но writeIORef может поломать используемую структуру данных и привести к падению приложения или порче данных. Поломать что-то с помощью print сложнее. Кстати в Rust вывод в stdout происходит через мьютекс.

userd ()
Ответ на: комментарий от userd

В IO возможны любые побочки, вплоть до сегфолта)

Сделай мне goto в IO ;-)

Rust при правильной инкапсуляции unsafe операций гарантирует отсутствие «состояний гонки» или использования ресурсов после их освобождения.

При правильном использовании? И да, а что мешает «правильно использовать» MVar Или вообще пользовать STM? И если уж зашла речь о многопоточности, то как там в расте с легковесными потоками?

Да, в Rust невозможны гонки? Принципиально?

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

print и writeIORef x имеют одинаковый тип, но первая безопасна, а вторая — нет.

С точки зрения системы типов, обе небезопасны. Ибо IO. И да, раст небезопаснее.

В нем вообще любая функция может вести себя так, что

f(1) + f(2) != f(2) + f(1)

:-)

lazybones ()
Ответ на: комментарий от userd

Охх. Ладно, для развлечений оставили загончик IO, но глобальные ioref, разделяемые между потоками, это всегда печаль и намеренное выстреливание в ногу.

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

lazybones ()
Ответ на: комментарий от tailgunner

А cabal и stack академичны в том смысле, что работа академиков - пробовать один подход за другим и публиковать результаты. Что происходит с разработанным кодом, их заботит мало.

Всё таки не совсем так, по моему. Если я верно понимаю, кабал был решением чисто практической проблемы, мало волнующей академию, а именно проблемы зависимостей. Ну кому в самом деле какая в академии разница какие там зависимости? просто снеси хаскель платформ, поставь новую версию да и продолжай писать статьи. Ну или сиди до упора на старой версии и читай лекции/принимай практику у студентов. Там проблема зависимостей минимальна по моему. В отличие от практики, где зависимости одна из основных проблем сборки.

И проблему зависимостей кабал решил, но принёс с собой cabal hell, т.е. проблему конфликта зависимостей. Её можно было решать через кабал сандбокс руками в общем то, но я не знаю на сколько это было хорошо, я не застал. Это тоже чисто практическая проблема: если у тебя там полтора проекта один для статьи и один для студентов проверять задания, то ты вполне можешь настроить себе песочницы руками, а вот если тебе нужно часто устанавливать/удалять проекты в команде, то там такой подход работает плохо и не масштабируется совершенно.

Как решение проблемы cabal hell пришёл стек, который использует кабал и добавляет сверху него дополнительную информацию и функционал. Со стеком установка нескольких разных версий компилятора и библиотек для разных проектов стала обычным рутинным делом. Установка нового проекта сводится к stack install и это полностью ставит компилятор и библиотеки, можно просто работать. Вряд ил это нужно академии. Ну, по крайней мере до такой степени чтобы с этим заморачиваться, кмк.

AndreyKl ★★★★★ ()
Ответ на: комментарий от userd

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

hateyoufeel ★★★★★ ()
Ответ на: комментарий от MyTrooName

по идее раст должен быть строго не хуже плюсов в аспекте безопаности

не факт: поправьте меня, если вдруг ошибаюсь, но под раст нет аналогов pvs-studio и в нём нет ООП

next_time ★★★★ ()
Ответ на: комментарий от next_time

но под раст нет аналогов pvs-studio

clippy

и в нём нет ООП

А при чём тут безопасность?

O02eg ★★★★★ ()
Ответ на: комментарий от next_time

нет аналогов pvs-studio

Компилятор ловит больше, чем pvs.

RazrFalcon ★★★★★ ()
Ответ на: комментарий от lazybones

Сделай мне goto в IO ;-)

Кто-то уже сделал =)
Да, в Rust весь код находится в IO, зато в Haskell весь код IO находится в unsafe. Поэтому нельзя однозначно сказать что одно безопаснее другого.

userd ()
Ответ на: комментарий от userd

Да, в Rust весь код находится в IO, зато в Haskell весь код IO находится в unsafe. Поэтому нельзя однозначно сказать что одно безопаснее другого.

Второе безопасней, очевидно :

1. Далеко не весь код в Haskell находится в IO 2. Бесконтрольность побочных эффектов вообще - хуже, нежели ограниченное количество небезопасных операций в специальных загончиках.

lazybones ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)