LINUX.ORG.RU
ФорумTalks

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

 ,


1

8

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

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

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

★★★★★

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

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

Кстати в Rust вывод в stdout происходит через мьютекс.

будто в Haskell не так, что кстати является проблемой для отлова исключений.

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

а tailgunner просто тролль для LOR.

Холмс, вы догадались об этом, прочитав мой профиль? Впрочем, я и правда хотел бы больше узнать о драйверах на Haskell (да и на Rust тоже).

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

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

qnikst ★★★★★
()

будь добр, напрягись и сделай нормальное форматирование. текст выглядит как говно.

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

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

rustc

в нём нет ООП

1) есть

2) при чем оно тут?

не, не так

1) при чем оно тут?

2) есть

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

а вообще Haskell перестал «быть академическим» где-то с ghc-7.10, на самом деле с последних версий 6-ки, там же дотащили нормальное rts и библиотеки, bytestrings, vector и все такое. Благодаря этому полезли и всякие прикладные библиотеки. И язык можно использовать для всего, и любой рандомный человек может его взять и использовать без необходимости лазать в компилятор и базовые библиотеки.

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

отлавливает ли он ошибки такого рода:


int a1 = SomeThingA1 + "бла-бла";

int b1 = SomeThingB1 + "другое бла-бла";

int с1 = SomeThingСl + "второе бла-бла";

int d1 = SomeThingD1 + "третье бла-бла";

?

если да, насколько хорошо?

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

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

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

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

Есть зачем. Такие ошибки - более-менее частое явление. В отличие, скажем, от сегфолтов. И ловятся вручную сложнее.

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

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

Но наши рукожопы не лыком шиты. Они из тех людей, которых С++ заставляет говнокодить, сегфолтами мучает и не дает исключения в деструкторе кидать. Поэтому они выбирают всякие модные «убийцы С++».

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

А поскольку драйверы все таки надо писать не на расте и не на цацкеле, а по идейным соображениям на С писать не хочется, то рукожопы решили лабать прямо на ассемблере. Что еще раз говорит о запредельной рукожопости, ибо ассемблеров в драйверах пользуются вообще в экстренных случаях или когда надо читать порт, но даже там есть in/out-функции.

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

goto там находится целиком в монаде Cont ;-)

Хочешь сказать, что побочки возможны не только в IO? =)

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

Но почему? Ведь Rust разграничивает safe и unsafe код. Есть такая синтаксическая конструкция в расте, unsafe {}. Только внутри неё можно использовать unsafe функции и производить операции над сырыми указателями и т.д. Такой вот загончик для небезопасных операций. Вне unsafe компилятор может доказать что код не будет иметь «data race» и прочих ошибок работы с ресурсами.
Т.е. я могу сказать то же самое про Rust:
1. Далеко не весь код в Rust находится в unsafe{} 2. Бесконтрольность unsafe{} в IO — хуже, нежели ограниченное количество небезопасных операций в специальных загончиках.

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

будто в Haskell не так, что кстати является проблемой для отлова исключений.

Не знаю, в Ubuntu 16.04 putStrLn выполненный одновременно в 2 потоках перемешивает символы выводимые каждым из потоков. Мб в новых версиях поправили, ждем 18.04. А как оно может помешать отлову исключений?

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

Не знаю, в Ubuntu 16.04 putStrLn выполненный одновременно в 2 потоках перемешивает символы выводимые каждым из потоков.

Это нормальное поведение, разделения вывода можно добиться через MVar.

Мб в новых версиях поправили, ждем 18.04.

Причем тут версия вашей убунты вообще?

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

Кстати в Rust вывод в stdout происходит через мьютекс.

будто в Haskell не так, что кстати является проблемой для отлова исключений.

А о каком тогда мьютексе говорил qnikst? В Rust println! не перемешивает символы даже если вызван одновременно в разных тредах.

Причем тут версия вашей убунты вообще?

Может в новой версии ghc которая будет доступна в новой убунте вывод в stdout сделали как в расте.

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

unknown identifier: SomeThingСl ?

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

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

Нормальные люди пилят драйвер на С

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

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

Так оно там и на С/С++, на хаскеле - рабочий прототип, который временами так и остаётся работать в продакшене. Просто вопрос в том, что драйвер всё равно приходится переписывать

И поэтому клоуны кодят на расте с ассемблером.

Где ты там увидел «раст с ассемблером»? Ты вообще в своем уме?

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

то, что takeMVar это прерываемая операция, поэтому использование вывода в обработчике исключения может словить другое исключение, чего не все ожидают. (Разговор про асинхронные исключения)

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

я об этом. (Код из GHC.IO.Handle)


data Handle
  = FileHandle                          -- A normal handle to a file
        FilePath                        -- the file (used for error messages
                                        -- only)
        !(MVar Handle__)

что в программе не знаю, код в студию, проще сказать будет.

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

Не вводите tailgunner в заблуждение: там написано, что один раз им пришлось использовать ассемблерные вставки в расте, чтобы максимально ускорить драйвер. В плане скорости результат даже оправдал ожидания - но в плане чистоты кода - там уже пошёл один сплошной ансейф и решили больше так не делать.

«раст с ассемблером»? Ты вообще в своем уме?

Но возможность делать ассемблерные вставки в расте действительно есть.

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

Айда на старую добрую сишечку

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

один раз

вставки на асме заняли 40% полезного кода

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

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

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

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

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

Тупо потому что у него больше знаний о контексте.

как раз наоборот, о контексте задачи больше знаний всегда у человека

Компилятор в большинстве кейсов сгенерит лучший код

...для PDP-11

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

быстрее в разработке? про неё речь шла, вроде бы.

или мне хотите про оптимизации рассказать? с удовольствием послушаю гуру ассемблерной оптимизации.

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

о контексте задачи больше знаний всегда у человека

Херня. У человека есть знания семантики задачи. На уровне операций у компилера знаний больше: он видит весь код. А уж LTO человек точно никак руками не сделает.

для PDP-11

Часто разрабатываете драйверы под PDP-11? Хотелось бы послушать историй.

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

сперва - быстрая разработка, а уж затем - переписывание «как надо» на крестах или сишечке + асм

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

он видит весь код

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

и уж точно компилятор не станет менять алгоритм ради применения SSE2, например

Часто разрабатываете драйверы под PDP-11

то-то и оно, что в С89 затачивался под модель архитектуры PDP-11 и на современные процессоры она ложится примерно никак

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

компилятор не станет менять алгоритм ради применения SSE2,

Как-то у меня компилятор юзает SSE2, видимо какая-то особая персональная версия.

С89 затачивался под модель архитектуры PDP-11

Никто не спорит

на современные процессоры она ложится примерно никак

Пруфы будут? А то складывается впечатление что по твоему мнению с 89 года разработчики компиляторов сидят на жопе ровно и игнорируют x86, так, для галочки кодогенератор сделали.

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

Ну и да — нужна гарантия использования SSE — используйте интринсики и интегрируйте свой оптимизированный алгоритм на SSE в сишную кодовую базу, давая компилятору возможность использовать и ваш SSE-enabled код и оптимизировать всё грамотно. Ассемблер для этого совершенно не нужен.

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

используйте интринсики и интегрируйте свой оптимизированный алгоритм на SSE в сишную кодовую базу

а это типа не использование ассемблера?

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

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

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

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

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

а мне говорит:

Module Size Used by

и больше ничего: много из этой строчки узнать можно?

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

Это не написание ассемблера руками. Такой код компилятор может и развернуь, если он в цикле и более грамотно зашафлить инструкции. В отличие от рукописной volatile портянки.

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

Это наверное первый раз, когда я с тобой согласен.

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

Кстати, насколько я знаю, с обработкой исключений в расте все куда хуже

Кек, вот тут ты ошибаешься. Исключения в хаскеле оче хитрые. Пример:

import Control.Exception

listData = 1 : 2 : 3 : 4 : 5 : tail
    where tail = (1+undefined) : tail

main = do
    i <- readLn
    (tval :: Either (SomeException) Int) <- try$ return$ listData!!i
    print tval
Если тут ввести индекс 10, то екзепшн всплывет не в момент вызова try, а после, когда будет вычисляться print. Так что несмотря на наличие try блока исключение не будет выловлено. А вот если сделать так
import Control.Exception
import Control.DeepSeq

listData = 1 : 2 : 3 : 4 : 5 : tail
    where tail = (1+undefined) : tail

main = do
    i <- readLn
    let val = listData!!i
    (tval :: Either (SomeException) Int) <- try$ val `deepseq` return val
    print tval
То исключение будет поймано в try, даже несмотря на то, что визуально проблемный вызов «listData!!i» находится за блоком try.

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

Aswed ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.