LINUX.ORG.RU

ByteString и «безопасность»

 


0

7

Недавно, заглянувши в сорцы bytestring, обнаружил что в объявлении типа ByteString используется ForeignPtr вне монады, а остальная часть кода кишит различными «unsafe» функциями, что вызвало у меня некоторое количество удивления, при том сам пакет bytestring помечен как «Trustworthy», немного почитав, я узнал, что модуль Foreign в целом «достаточно безопасен, чтобы спокойно использовать его функции мимо монады, но недостаточно безопасен чтобы исключить монады из реализации вообще».
Хотелось бы узнать, у людей которые контактируют с haskell-сообществом белее тесно чем я, следующие:

  1. Что думают на этот счёт «Ъ-хаскелисты»?
  2. Как много людей которые принципиально используют ByteString только внутри IO?
  3. Подтверждение того что на значения возвращяемые функциями Foreign можно спокойно применять unsafe*PerformIO
Deleted

А какая разница, как это реализовано внутри? Главное, чтобы снаружи соблюдалась ссылочная прозрачность и все.

dave ★★★★★
()

при том сам пакет bytestring помечен как «Trustworthy»

Почему тебя это смущает? Внутри оно может как угодно быть написано. Главное что оно снаружи выполняет контракт.

anonymous
()

Что думают на этот счёт «Ъ-хаскелисты»?

Уже раз десять про это писал. Только здесь.

Как много людей которые принципиально используют ByteString только внутри IO?

Почему-то упоротых людей в сообществе на удивление мало. Мистика...

Подтверждение того что на значения возвращяемые функциями Foreign можно спокойно применять unsafe*PerformIO

Нет. Не вдаваясь в подробности... Есть FFI, есть PrimOps (примитивные операции), так вот, FFI — это примопсы, но не всякие примопсы — FFI. Короче говоря, в пакете bytestring всё рассчитано до миллиметра, и лезть своими кривыми руками туда не нужно, и изобретать свой собственный велосипед не нужно, и оптимизировать без нужды не нужно.

Macil ★★★★★
()

1. bytestring очень хорошо реализован с точки зрения работы с FFI и вообще внешним кодом, если хочется поучиться, то туда стоит минимум посмотреть

2. подозреваю что 0.

3. accursedUnutterablePerformIO использовать небезопасно, о чем явно говорит комментарий и серия багов относящихся к коду, где его использовать было небезопасно. К Foreign это имеет весьма опосредованное отношение.

«достаточно безопасен, чтобы спокойно использовать его функции мимо монады, но недостаточно безопасен чтобы исключить монады из реализации вообще»

очень сложно разумно прокомментировать это..

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

Есть FFI, есть PrimOps (примитивные операции), так вот, FFI — это примопсы, но не всякие примопсы — FFI.

НУЖНО БОЛЬШЕ ИНТЕРЕСНЫХ УТВЕРЖДЕНИЙ НА LINUX.ORG!!! может вдашься в подробности, а то мне даже интересно стало?

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

минимум с точностью до наоборот, priop - это всегда внешний вызов (FFI), но не всякий внешний вызов primop, например ccall это не primop.

Вообще, если вдаваться в подробности (см. GHC Track wiki) primop-ы делятся на внутри-GHC-ш-ные, которые нельзя добавлять или изменять не изменяя исходники GHC; есть юзерские - юзерские это FFI с Haskell соглашением о вызовах (cc10 в терминах LLVM), они делаются или на C-- или напрямую подключая символы собранный llvm. Но зачем это в данном треде я не знаю.

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

Вообще, если вдаваться в подробности

Ум-м-м-м... Давай не считать GHC рантайм «внешним», а FFI считать unsafe-вызовом внешней C-процедуры. Чисто с дидактической точки зрения. А то разницу между байтстрингами и FFI будет сложно уловить. Т.е.

1. ByteStrnig — это MutableByteArray#

2. ForeignPtr используется по историческим причинам, и чтобы не быть прибитым гвоздями к ghc-prim (в скромной надежде что когда-нибудь появятся другие реализации Хаскеля).

3. У ForeignPtr, используемого в ByteString, нет финалайзера. За утилизацию отвечает сборщик мусора.

4. ByteString не имеет никакого отношения к FFI, в смысле внешних по отношению к рантайму сишных функций.

5. ByteString может эффективно передаваться в FFI вызовы.

6. ByteString нельзя злоупотреблять, т.к. а) вызывают фрагментацию памяти; б) выделяются (или раньше выделялись?) в один поток.

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

Давай не считать GHC рантайм «внешним»...

Ну давай, я правда не вижу причин для этого. Только не забывай о наличии foreign-out-of-line-primop. inline-primop я, так уж и быть, согласен не считать FFI в итоге получится, что FFI это не primop (т.к. может быть другое соглашение о вызовах), primop это не FFI (т.к. есть inline-primop, которые мы тут договорились не считать FFI).

1. ByteStrnig — это MutableByteArray#

нет. При чем дважды «нет».

2. ForeignPtr используется по историческим причинам, и чтобы не быть прибитым гвоздями к ghc-prim (в скромной надежде что когда-нибудь появятся другие реализации Хаскеля).

нет.

3. У ForeignPtr, используемого в ByteString, нет финалайзера. За утилизацию отвечает сборщик мусора.

нет.

4. ByteString не имеет никакого отношения к FFI, в смысле внешних по отношению к рантайму сишных функций.

cоглашусь

5. ByteString может эффективно передаваться в FFI вызовы

да

6. ByteString нельзя злоупотреблять, т.к. а) вызывают фрагментацию памяти; б) выделяются (или раньше выделялись?) в один поток.

да. а - только байтостроки тут не сильно при чем, это свойство любой pinned памяти. б. - если usafeDupablePerformIO в unsafeCreate не было, то так

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

лезть своими кривыми руками туда не нужно

да я и не собирался

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

серьёзно. это утверждение явно было сказано в контексте разговора, где уже имеется достаточное количество дополнительных определений и допущений. Когда оно звучит в отрыве от этого контекста проще сказать, что «все не так», чем восстанавливать этот контекст и уточнять формулировки, несмотря на то, что доля правды (в возможно и все утверждение) автором были сказаны справедливо. Просто очень похожие вещи могли быть высказаны и теми, кто не до конца понимает, что происходит, и тогда согласие или комментарий этого высказывания как оно есть, приведет к неверным выводам.

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

Ой, прости, тупанул немного, это было в контексте импорта сишных функций.

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

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

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

мы не парились и вызывали curl как подпроцесс, но нам по мелочам надо. А для чего libcurl хочется использовать? тк. всякие либы типа http-client и прочие (чет из головы вылетели) для http задачу удобнее курла решат.

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

А для чего libcurl хочется использовать?

Да вот выкачивать приходится порой по 3000-30000 мелких файлов и иногда писать это на ftp, делаю это в 15 потоков через вызов curl, но как-то мне это костыльно показалось, поэтому заинтересовался libcurl, к тому-же у них там в библиотеке уже реализована многопоточность и, судя по всему, можно даже нормально процесс выполнения спросить.

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