Home
Objective Caml
ocaml@conference.jabber.ru
Четверг, 11 августа 2011< ^ >
f[x] установил(а) тему: Камль -- http://caml.inria.fr | http://camlunity.ru/ (теперь с git доступом!) | Верблюды грязи не боятся! | release crap, enjoy NIH | репортьте баги официальным дилерам | ocaml мёртв и тормозит, move on | stdlib only? - ССЗБ
Конфигурация комнаты
Участники комнаты

GMT+4
[00:19:01] <bobry> товарищи, а как бороться с ошибкой files <foo> and <bar> both defined a module named <Baz>?
[00:19:36] <bobry> у меня в обоих есть модуль Helpers, причем в обоих он в InternalModules
[00:22:52] <ygrek> bobry: ошибку перефразировал?
[00:23:09] <bobry> File "_none_", line 1, characters 0-1:
Error: Files src/helpers.cmx and /usr/lib/ocaml/alberto/alberto.cmxa
       both define a module named Helpers
Command exited with code 2.
[00:24:19] Typhon вошёл(а) в комнату
[00:27:28] <bobry> модули которые я не хочу экспортировать должны находиться в .mllib?
[00:28:08] <ygrek> по идее в mllib всё должно быть
[00:28:23] <ygrek> просто cmi ихние не надо инсталлить
[00:28:35] <bobry> а как это объяснить oasisу?
[00:28:42] <ygrek> InternalModules
[00:29:00] <ygrek> но это не спасёт от конфликта, думаю
[00:29:10] <ygrek> топ-лепел имена должны быть глобально различные
[00:29:30] <ygrek> т.е. получаеся в alberto.cmxa есть упакован тоже helpers.cmx
[00:29:36] <ygrek> поэтому один надо переименовать
[00:29:40] <bobry> тык в обоих библиотеках они Internal
[00:29:49] <ygrek> (либо в cmxa использовать pack)
[00:30:04] <ygrek> это не важно
[00:30:06] <bobry> хмм, я могу себе представить что много камлолиб имеет модуль Util / Utils etc
[00:30:13] <bobry> они тоже конфликтуют?
[00:31:07] <ygrek> вообще надо бы проверить, но конфликты - да, это проблема
[00:36:29] <bobry> странно что не гуглится ничего
[01:02:02] ygrek вышел(а) из комнаты
[01:02:29] shaggie вышел(а) из комнаты
[01:42:26] ftrvxmtrx вышел(а) из комнаты
[03:08:13] digimmortal вошёл(а) в комнату
[03:14:39] zinid вошёл(а) в комнату
[03:36:29] Typhon вышел(а) из комнаты
[04:41:07] digimmortal вышел(а) из комнаты
[09:34:55] Kakadu вошёл(а) в комнату
[10:02:10] mrm вошёл(а) в комнату
[10:05:54] ermine вошёл(а) в комнату
[10:26:31] gds вошёл(а) в комнату
[10:42:37] <gds> bobry: везде M.catch -- для порядку.  Чтобы ловить как ошибки монады, так и нормальные исключения (везде, где это возможно, конечно).
[10:46:06] <gds> а хотя вот, даже сейчас код пишу, где скорасть -- так вот, из монадной функции вызываю явно немонадную, и ловлю исключения через try IO.return (f x) with [ e -> IO.error e ].
[10:51:06] <ermine> экспшны - родные зубы верблюда, в отличие от монад!
[10:52:47] bobry- вошёл(а) в комнату
[10:55:49] iNode вошёл(а) в комнату
[10:56:50] <ermine> отличные такие зубы, не гнилые
[10:58:13] bobry- вышел(а) из комнаты
[10:58:23] bobry- вошёл(а) в комнату
[10:58:49] <bobry-> gds: а ты чего нибудь расскажешь про конфликт модулей?
[10:59:12] <bobry-> я вчера в #ocaml спросил -- сказали тоже что ygrek посоветовал, либо переименовать, либо pack
[10:59:35] <gds> дык вроде рассказали.  Плохо, но делать нечего.
[11:00:04] <komar> О, знакомая проблема.
[11:00:21] <bobry-> жаль, вроде и модули то внутренние :(
[11:00:32] <bobry-> komar: ты какой вариант выбрал?
[11:00:33] <komar> Может, взять за правило все в pack упаковывать?
[11:00:40] <komar> bobry-: я переименовал.
[11:00:53] <bobry-> в новом оазисе по слухам буит Pack: true
[11:01:03] <komar> Тьфу.
[11:01:10] <bobry-> правда у меня вчера патч который это реализует не наложился
[11:11:59] <f[x]> а ещё есть потенциальный вариант - https://github.com/OCamlPro/ocaml-namespaces
[12:02:36] ermine удалила депендсы на свою могучую либлу перекодировок, теперь надо удалить stream parsers, интересно, на что заменять их - на pcre?
[12:03:14] <gds> итераты же!
[12:03:15] <ermine> f[x]: похоже там кто-то очень любит с++
[12:04:45] <ermine> итераты как-то громоздко и не удобно из-за монад
[12:06:17] <ermine> даже не категориально
[12:10:00] Kakadu вышел(а) из комнаты
[12:10:09] Kakadu вошёл(а) в комнату
[12:14:30] <gds> ну, есть манатка Identity, никто не заставляет честные манатки тащить.
[12:50:36] shaggie вошёл(а) в комнату
[13:40:03] Typhon вошёл(а) в комнату
[14:26:42] ftrvxmtrx вошёл(а) в комнату
[14:41:15] digimmortal вошёл(а) в комнату
[16:31:58] bobry- вышел(а) из комнаты
[16:34:37] bobry- вошёл(а) в комнату
[16:38:47] digimmortal вышел(а) из комнаты: Replaced by new connection
[16:38:49] digimmortal вошёл(а) в комнату
[16:43:33] ftrvxmtrx вышел(а) из комнаты
[16:44:05] ftrvxmtrx вошёл(а) в комнату
[16:47:45] komar вышел(а) из комнаты: Replaced by new connection
[16:47:46] komar вошёл(а) в комнату
[17:59:57] <bobry-> товарищи, а можно параметризовать сигнатуру типом? допустим у меня есть module Foo : sig val f : some_type -> some_type end. и я хочу сделать два модуля с разными значениями some_type. какой для этого синтаксис?
[18:00:30] <bobry-> вроде как можно просто объявить type some_type а потом сказать module Bar : Foo with type some_type = int
[18:00:49] <bobry-> но тогда в struct модуля Bar придется тоже писать type some_type = int
[18:00:53] <gds> module Foo (T : sig type t end) : sig val f : T.t = ...
[18:01:13] <gds> таким же образом параметризуется модуль значением.
[18:01:17] <bobry-> т.е. только через модуль?
[18:01:30] <gds> так -- точно работает.
[18:01:34] <bobry-> это же сахар для функтора, если я не путаю
[18:01:54] <gds> ну да, цель -- сделать функтор.  сахаром или без -- не суть важно.
[18:02:31] <bobry-> спасибо :)
[18:02:49] <bobry-> я думал можно как то по другому, ан нет
[18:03:15] <gds> может и можно, но так -- точно работает.
[18:03:28] <bobry-> тогда такой вопрос
[18:03:45] <bobry-> как мне это дело объявить в интерфейсе?
[18:03:56] <bobry-> module type PORT(IO : sig type ic and oc end) = sig ... end не работает :(
[18:05:57] <gds> сходу вышло:
# module type Funct = functor (T : sig type t end) -> sig val f : T.t -> T.t end;;
module type Funct =
  functor (T : sig type t end) -> sig val f : T.t -> T.t end
[18:16:53] <bobry-> и точно работает, спасибо еще раз
[18:21:26] <bobry-> There is no equivalent to functors at the level of signature: it is not possible to build a signature by application of a ``functorial signature'' to other signatures.
[18:21:28] <bobry-> aww
[18:22:37] <bobry-> хотя почему тогда этот код работает, ведь тут как раз sig -> sig
[18:26:48] <f[x]> в 3.12 можно делать (module type of (примениние функтора))
[18:28:20] <zinid> господа, посоветуйте хороший мануал по этой теме
[18:28:30] <zinid> из официальной доки нифига непонятно ;)
[18:28:41] <bobry-> zinid: да они надоели своими Set'ами
[18:28:45] <bobry-> как функтор, сразу Set
[18:28:55] <bobry-> в общем присоединяюсь к вопросу
[18:29:31] <gds> это в теории категорий, как что, так сразу Set.  Тут ещё радуйтесь, окамловский пример с Set весьма приличен ещё.
[18:29:34] <f[x]> мануал, читать и экспериментировать с топлевелом паралельно
[18:29:43] <zinid> вообще с обучающей литературой всё печально в камле
[18:30:00] <zinid> учитывая что язык сильно отличается от других...
[18:30:07] <bobry-> f[x]: может я чего не понимаю, но module type of немного другое делает
[18:30:20] <bobry-> мне надо параметризовать sig двум типами
[18:30:27] <f[x]> есть доки по модулям - applicative vs generative, etc - но там обычно много матана
[18:31:23] <zinid> вово
[18:31:38] <zinid> я пытался найти что означает -'a, чуть не попутал ;)
[18:31:57] <f[x]> # module Z(T:sig type x type y end) = struct type x = T.x type y = T.y end;;
module Z :
  functor (T : sig type x type y end) -> sig type x = T.x type y = T.y end
# module type ZZ = module type of (Z(struct type x = int  type y = string end));;
module type ZZ = sig type x = int type y = string end
[18:32:37] <gds> zinid: ЧТИ МЕНЯ ЛОЛ http://gds.livejournal.com/54767.html
[18:32:55] <zinid> вот я на тебя и наткнулся
[18:33:07] <zinid> и мне перехотелось вникать ;)
[18:33:21] <zinid> зачем писать такое, для кого? :)
[18:33:49] <Typhon> нам с пацанами нравится
[18:33:50] <gds> для людей чо.  Что непонятно?
[18:33:51] <Typhon> !
[18:34:03] <bobry-> f[x]: а что если мне нужно параметризовать только сигнатуру, а не struct?
[18:34:34] <f[x]> bobry: так а struct чисто вспомогательный, чтобы из него сигнатуру получить
[18:34:48] <f[x]> т.е. его потом отбрасываешь
[18:35:19] <f[x]> zinid: алгоритм, идёшь на http://caml.inria.fr/pub/docs/manual-ocaml/language.html и думаешь -'a это что? определение типа (судя по контексту)
[18:35:34] <bobry-> f[x]: все, понял, круто :)
[18:35:38] <f[x]> значит идём в type definition - http://caml.inria.fr/pub/docs/manual-ocaml/manual016.html
[18:35:41] <bobry-> gds: вот ты суровый пацан ...
[18:36:21] <f[x]> и там видим плюсики и минусики
[18:36:22] <gds> это не я суровый, это самое простое+полезное объяснение суровое.  Более простые -- менее полезные.
[18:37:03] <f[x]> gds: кстати мог бы ссылки на свои ocaml псты собрать на камлунити
[18:37:15] <zinid> f[x]: да я там на каждом термине начинаю спотыкаться
[18:37:20] <gds> f[x]: идея грамотная, так и сделаю.
[18:37:27] <Typhon> gds: удваиваю f[x]!
[18:37:56] <f[x]> zinid: ну раз так тогда это ещё рано разбирать, рекурсивно разбирай все подтермины сначала :)
[18:38:35] <zinid> в том то и дело, что влом разбирать :)
[18:38:45] <zinid> пишу примитивно щас
[18:39:06] <zinid> let, pattern-matching, вот в общем-то и всё ;)
[18:39:16] <zinid> ну типы там какие простые создаю
[18:39:37] <zinid> причём сразу головняк вылезать что юзать: варианты или полиморфные варианты
[18:39:45] <zinid> *вылезает
[18:40:13] <f[x]> zinid: э, так ты определись - надо разбирать или не надо? ;)
[18:40:31] <f[x]> если не надо - то ок - можно вполне себе писать и не знать всех тонкостей
[18:40:37] <zinid> f[x]: ну из того что есть сложно разобраться
[18:40:52] <zinid> надо реально убить кучу времени
[18:40:55] <f[x]> ну, life is not a bed of roses
[18:41:27] <zinid> угу, поэтому нада всё усложнить ;)
[18:41:36] <zinid> так сказать для илиты...
[18:41:37] <f[x]> да, надо реально убить сколько-то времени чтобы понять матан стоящий за камловой системой типов - это нормально
[18:41:47] <f[x]> но можно писать и не знать матан - это тоже нормально
[18:41:50] <zinid> а какой там матан то?
[18:42:16] <zinid> там народ делает вид что знает матан и пишет хню
[18:42:23] <zinid> илитарность же
[18:42:59] <bobry-> f[x]: так, чую что недопонимаю пример -- если мне надо в сигнатуру Z добавить еще пару функций то надо для них заглушки писать чтоли?
[18:43:46] <f[x]> там нормальный матан
[18:44:08] <gds> zinid: ну докажи мне.  Возьми ту же подтипизацию и попробуй сформулировать её "ни-илитически", в простых терминах.  Предрекаю либо фейл, либо недостаточно общий результат, либо изоморфизм текущим реалиям.
[18:44:15] <f[x]> док-во обоснованности системы типов
[18:44:23] <f[x]> gds: +1
[18:45:09] <zinid> "кратко: +'a означает, что данный параметр ковариантно входит в тип. -'a — соответственно, контрвариантно."
[18:45:13] <zinid> вот например
[18:45:17] <zinid> сразу вопрос
[18:45:26] <zinid> что значит входит ковариантно?
[18:45:32] <f[x]> дальше написано
[18:45:39] <zinid> а
[18:45:57] <gds> "Первый случай обозначается в окамле как type t +'a = .., второй — type t -'a = .., третий — type t 'a = ..."
[18:46:46] <zinid> Ssup → Tsub
[18:46:46] <gds> я пытался описать исходя из концепций, а не из синтаксиса, вот потому так и вышло.
[18:46:51] <zinid> чо это значит?
[18:46:59] <zinid> выше  определений стрелки нет
[18:47:09] <zinid> это отображение или что?
[18:47:23] <gds> обычно так и есть, отображение.  В общем случае -- морфизм, тут -- просто функция.
[18:49:29] <f[x]> bobry-: получается да
[18:51:41] <f[x]> bobry-: можно тогда проще - это старый известный трюк :
# module Z(T:sig type x type y end) = struct module type Q = sig type x = T.x type y = T.y val f : x -> y -> unit end end;;
module Z :
  functor (T : sig type x type y end) ->
    sig
      module type Q =
        sig type x = T.x type y = T.y val f : x -> y -> unit end
    end
# module TEMP = Z(struct type x = int  type y = string end);;
module TEMP :
  sig
    module type Q =
      sig type x = int type y = string val f : x -> y -> unit end
  end
[18:52:08] <f[x]> и используешь TEMP.Q
[18:54:12] <zinid> gds: отображение? а что означает ⊆ для отображений?
[18:54:27] <gds> zinid: "Факт того, что везде, где применимо значение с типом B, применимо  значение с типом A, назовём "A является подтипом B", и обозначим как A ⊆  B."
[18:54:39] <zinid> ну
[18:54:52] <zinid> это про типы
[18:54:57] <zinid> а отображения?
[18:55:14] <gds> ну вот, если есть подтипизация определённого вида между доменами и кодоменами, то есть подтипизация между отображениями.
[18:55:48] <gds> "На русском языке это формулируется так:" -- вот там про узкие/широкие типы описал, как бы "интуицию".
[18:56:25] <zinid> что такое кодомен?
[18:56:29] <zinid> и вообще домен
[18:57:17] <ermine> математега какая-то
[18:57:25] <zinid> да это не математега
[18:57:48] <zinid> математега, это когда следишь за терминами, которыми оперируешь
[18:58:00] <zinid> а тут чиста "крутые слова"
[18:58:23] <zinid> возможно они имеют смысл, не спорю, но в статье это не описано
[18:58:37] <ermine> математега - это когда много научных слов
[18:58:38] <gds> http://ncatlab.org/nlab/show/domain если правильно.  А так -- домен это отображение морфизма на его левую часть.  Кодомен -- на правую.  То есть, любой морфизм -- от домена в кодомен.  Следи за терминами!
[18:58:43] <Typhon> неделя чтоле такая?
[18:58:47] <Typhon> третий раз спор на одно и тоже
[18:58:57] <Typhon> "арнольдофаги vs. бурбакофаги"
[18:59:14] <zinid> бгг
[18:59:16] <gds> Typhon: у онцеламмира видел, а ещё одно где видел?
[18:59:36] zinid не шарит в теории категорий
[18:59:49] <zinid> так что про морфизмы не могу ничо сказать
[18:59:59] <Typhon> на, прости госпади, хабре http://habrahabr.ru/blogs/programming/125782/ ( я туда не хожу, я ссылку увидел! :-) )
[19:00:34] <Typhon> и даже, возможно, 4ый спор: http://ivan-ghandhi.livejournal.com/1717084.html
[19:01:00] <ermine> интересно, есть ли теория категорий для маленьких детей?
[19:01:09] <zinid> ermine: вряд ли
[19:01:13] ermine бы почитала
[19:01:13] <gds> ну, в посте я не упоминал морфизмы, домены, кодомены, так что статьи это не касается, разве что я тут их упомянул.  В частном случае, когда морфизм это функция, домен -- это тип аргумента, кодомен -- тип результата.
[19:01:14] <zinid> это ахтунг тот ещё
[19:01:53] <zinid> gds: дык в статье упоминается ⊆ для отображений
[19:02:14] <zinid> это явно что-то с морфизмами связано
[19:02:24] <zinid> хотя из статьи неясно
[19:02:31] <gds> да, там я предполагал, что читатель ассоциирует стрелку с отображением / функцией.
[19:03:20] <gds> ну вот, в статье я индуктивно констатирую подтипизацию для отображений/функций на основании подтипизации "того, что слева и справа от стрелки".
[19:03:30] <ermine> а стрелка - это как раз математега
[19:03:33] <bobry-> f[x]: хитрооо :)
[19:03:38] <zinid> а теория категорий - муть та ещё
[19:03:55] <zinid> вообще вся гомология - муть жёсткая
[19:04:16] <ermine> zinid: ну вообще всё является мутью, пока в это не начнешь играть серьезно
[19:04:20] <zinid> её, имхо, в универе тока спец-курсами проходят
[19:04:29] <zinid> не
[19:04:57] <ermine> zinid: можно еще почитать все научные труды святого Окасаки
[19:05:11] <ermine> он понаписал больше чем св. Киселев
[19:05:12] <zinid> ermine: фсё читать - жизни не хватит
[19:05:59] <ermine> а некоторые ж успевают и понаписать и переписать свои же труды
[19:06:07] <gds> теория категорий -- может и муть, но я не копенгаген утверждать это.  Я её только базово знаю, кое-какую интуицию она мне даёт, это полезно, вот и всё.  И, упаси С-т-на, никому её не навязываю.  Просто вот, она кое-что хорошо обобщает.
[19:06:19] <ermine> академики - такие академики
[19:07:28] <ermine> а вообще я чота даже больше никого и не вспомню, кроме этих двоих
[19:09:29] <f[x]> ermine: а прпдбн. Jacques Garrigue?
[19:09:35] <Typhon> Кардели
[19:09:55] <Typhon> и Пирс
[19:12:13] <f[x]> ermine: алсо, брат Rossberg и брат Ramsey
[19:12:19] <gds> вообще вот, хоть и [с]вербит, но http://imperium.lenin.ru/~verbit/MATH/programma.html -- вот такие универы полезны.  А "универ!  спецкурсы!  матан!" -- ну не знаю.
[19:12:24] <zinid> хто все эти люди...
[19:13:07] <zinid> Второй курс
    Алгебраическая топология (Фукс-Фоменко)
[19:13:09] <zinid> o_O
[19:13:10] <zinid> жесть
[19:14:23] <zinid> школьная прога - первый курс универа щас
[19:14:30] <zinid> а что это за список?
[19:14:31] <gds> там жесть и в "школьной программе", весьма многое я там не знаю.
[19:14:37] <zinid> ага
[19:14:54] <zinid> кто-то решил понтануться? :)
[19:15:16] <zinid> 99% учеников не знают скока будет a в степени 0
[19:15:22] <zinid> в 11-м классе
[19:16:11] <gds> список -- некто вербицкий / тифарет читает в НМУ лекции и говорит, как оно по идее должно быть устроено, из своего опыта.
[19:16:36] <zinid> а как он за такой короткий срок это всё расскажет?
[19:16:42] <zinid> там будет несвязная хня
[19:16:53] <zinid> нереал имхо
[19:17:39] <gds> это не "он расскажет", это "студенты изучат".
[19:17:44] <zinid> Комплексный анализ одного переменного (по книге Анри Картана)
[19:17:54] <zinid> бурбкист детектед? :)
[19:18:22] <gds> рассказы нужны только в ключевых точках.  их много, но вполне можно сделать так, чтобы на каждую лекцию таковая попадала.
[19:20:20] <ermine> а за один семестр выучивают всю теорию категорий?
[19:20:30] <zinid> первая глава книги
[19:20:39] zinid помнит ту книгу
[19:20:44] <f[x]> и разгоняют весь поток :)
[19:20:44] <zinid> там тока определения
[19:21:35] <zinid> его разгонят уже в школе ;)
[19:21:45] <ermine> zinid: попробуй почитать еще раз, за 10 лет должно стать проще
[19:21:59] <zinid> ermine: поздняк, я ужо всё зобыл
[19:36:08] bobry- вышел(а) из комнаты
[19:41:17] zinid вышел(а) из комнаты
[20:59:55] <bobry> товарищи, а можно как нить заставить модуль реализовывать *хотя бы* функцию f
[21:00:09] <bobry> но если у него есть еще функции, не закрывать их
[21:06:34] digimmortal вышел(а) из комнаты
[21:07:49] <gds> можно: добавить в код "module QQQWWW = (Yourmodule : sig val f : a -> b end)"
[21:18:03] <bobry> но это же закроет все остальные функции кроме f
[21:19:09] <gds> в модуле QQQWWW -- да.
[21:19:27] <bobry> а, ты имееешь ввиду сделать фейковый модуль
[21:19:27] <Typhon> bobry: а как ты представляешь себе потом работу с этим модулем?
[21:19:55] <bobry> похоже я какой то фигней занимаюсь :)
[21:20:00] <Typhon> ну типа, пишешь ты в коде "Ololo.blabla"
[21:20:03] <bobry> ага
[21:20:05] <Typhon> и хз, есть ли оно или нет
[21:20:27] <Typhon> ну или типа, этими функциями никто пользоваться не будет
[21:20:38] <Typhon> я может под вечер туплю, но кажется, это нафиг не надо %)
[21:20:52] <bobry> я хотел сделать два модуля для эрланговских портов -- один с обычными channels, другой с Lwtшными
[21:21:24] <bobry> пока получается плохо
[21:21:51] <bobry> т.е. сами модули уже написаны, но привести их к одной сигнатуре не получается
[21:21:57] <bobry> может оно и не надо
[21:23:17] <Typhon> да просто два модуля сделать :-) с ним же работать по-разному придётся
[21:23:25] <Typhon> и интерфейс общий вряд ли нужен
[21:23:32] <bobry> нет, фишка в том что высокоуровневый api один и тот же :)
[21:23:41] <bobry> а вот уровнем пониже уже весь в Lwt.t
[21:24:46] <gds> полностью один и тот же не получится -- в одном случае мне надо чистое значение 'a, в другом без Lwt.t 'a не обойдётся.  Можно, конечно, всё описать над монадой IO_Lwt в одном случае и над монадой Identity в другом -- я так делаю вот.
[21:25:28] bobry еще не настолько крут, только пощупал Lwt то
[21:26:51] <gds> как отправную точку я сделал https://bitbucket.org/gds/ocaml_monad_io/src -- там по крайней мере сигнатуры есть.  Ну и можно расширять как надо.  Конечно, в случае манатки Identity лучше "прямой" апи предоставить как обычные функции, не монадно, но имплементация будет монадной, раз уж есть Lwt хоть где-нибудь.
[21:30:13] <gds> кстати вот, удивительно, если есть монадный код, есть парсинг, но нет итератов -- почему так?
[21:30:37] <bobry> потому что еще не осилил
[21:31:00] <bobry> вообще все затевалось ради упражнений со Stream.t
[21:31:06] <bobry> итератов даже в планах не было
[21:37:44] shaggie вышел(а) из комнаты
[21:38:35] <gds> ну вот, считай, что Stream.t -- это такие итераты, которые по одному элементу за раз получают.
[21:43:36] mrm вышел(а) из комнаты
[21:47:47] <bobry> gds: а можешь показать какой нить код с lwt пожирнее?
[21:47:59] <bobry> чтобы много всего было :)
[21:48:08] <bobry> мне интересно в плане композиции
[21:51:14] <Typhon> ocsigen можно посмотреть ^___^
[21:51:38] <gds> bobry: проще рассказать на пальцах.  Последовательность -- ">>=", параллельность -- join, сообщения от процесса к процессу -- Lwt.wait или типа того, но не помню, смотри establish_server (где-то в src/lwt_io.ml наверное).  Вообще, этот establish_server (и Lwt_mbox) вполне показывают всю композицию, и очень даже нормально.  Кажется, что сложно, но это потому, что предмет вообще не прост, скажем так.
[21:55:12] <bobry> ок, вот есть у меня lwt тред, и хочу я поймать в нем исключение -- куда принято catch засовывать
[21:55:31] <bobry> Lwt_io.read stdin 20 >>= (fun data -> ...)
[21:56:03] <bobry> если верить сигнатуре то надо писать catch (Lwt_io.read stdin ... >>= (fun data -> ...)) (fun exn -> ...)
[21:56:07] <bobry> но это как то совсем некрасиво
[21:59:42] <gds> ну вообще-то так и есть, catch (где ловим) (как ловим).
с другой стороны, lwt'шный catch должен пропускать нативные исключения -- ещё бы, ему Lwt.t 'a дают на вход, а если есть значение, то исключение, если и было, ушло вверх.  Поэтому у меня catch берёт на вход unit -> M.t 'a.  То есть,
catch : (unit -> M.t 'a) -> (exn -> M.t 'a) -> M.t 'a
тут точно ловится всё.  Кстати, про этот момент писал вчера, про "почему один catch".  Удобно, что не надо думать лишний раз.
[22:00:23] <gds> про некрасивое -- есть синтаксические расширения.  Ну и вообще, монадный код без сахара -- он такой.
[22:00:57] <gds> можно придумать супер-оператор, который этому catch будет тупым синонимом.
[22:04:17] Typhon вышел(а) из комнаты
[22:05:21] <gds> ах да, вот супероператор:
(fun () -> сделать) /* catch */ fun e -> обработать
[22:05:28] <bobry> что то я не понял про Lwt.t 'a на входе catch
[22:05:38] <bobry> этот супер-оператор мне совсем не нравится :)
[22:07:22] <gds> он мало кому нравится.  Придумай другой синтаксис камлу, чтобы было предсказуемо, тупо, в среднем удобно.
Про Lwt.t 'a -- представь код: Lwt.catch (raise Exit) (fun _ -> Lwt.return 123).  Формально, "raise Exit" имеет тип, в том числе, Lwt.t int.  Но Lwt.catch его не словит.
[22:08:08] <bobry> хитрый какой код, lwtшный catch по моему тоже unit -> Lwt.t 'a хоче на вход
[22:09:04] <gds> а, вот, ты меня дезинформировал.  Не стыдно?
[22:09:26] <gds> я-то думал, почему у меня IO.catch = Lwt.catch, и думал, не накосячил ли где.
[22:09:27] <bobry> был не прав -- звиняюсь :)
[22:09:41] <gds> чуть не стал лезть разгребать исходнее.
[22:09:58] <bobry> ой ой, буду аккуратней :)
[22:10:07] <gds> ну вот и ок, что ок.  :]
[22:10:50] <bobry> gds: ты меня прямо вдохновляешь на изучение камла своим энтузиазмом лол
[22:12:04] <gds> у меня блин кодобаза и ответственность за свой софт, где тред может в случае чего может уронить всё камло сразу нахрен и процесс и распи...асило по серверу!111  самое время думать про Lwt.catch.
[22:14:47] <gds> в общем-то, я на опасни штуку пошёл: пихаю разный код в пределы одного рантайма (в будущем -- в пределы нескольких, но без чёткого разделения, какой куда).  Понятно, надо сделать так, чтобы каждый кусок не мог влиять на работу другого куска.  Даже если куски пишу сам.  Оттуда и паранойя в плане ловли ошибок и вообще корректности.
[22:22:39] <bobry> gds: слушай, а если пишешь с lwt, то надо обязательно использовать Lwt_unix вместо Unix?
[22:23:14] <gds> если допустимо блокироваться, то можно и Unix.  Иногда допустимо, иногда нет.
[22:23:16] <bobry> мне вот надо зарезолвить хостнейм, я с одной стороны понимаю шо Unix.getaddrinfo все нафик заблокирует, но с другой засовывать туда Lwt.t ой как не хочится
[22:23:37] <gds> а как туда Lwt.t засунешь?  Никак же.
[22:23:37] <bobry> ну лады, попробую и так и так
[22:23:55] <bobry> в смысле можно заюзать Lwt_unix.getaddrinfo
[22:24:01] <bobry> там результат обернут в Lwt.t
[22:24:33] <gds> ну смотри, блокироваться будешь же.  Если тредов мало и неймсервера работают хорошо, может никто и не заметит.
[22:24:42] <gds> иначе -- жопка же.
[22:25:48] <bobry> вот еще какая штука, в ерланге например принято делать падающие матчи
[22:26:00] <bobry> например let x :: _ = some_list in ...
[22:26:13] <bobry> и где нибудь на верхнем уровне можно ловить match failure
[22:26:19] <bobry> в камле лучше так не делать?
[22:35:50] shaggie вошёл(а) в комнату
[22:36:46] <gds> именно так.  Конечно, Match_failure бросят, и даже можно словить, но кривота: полнота матчей -- первое подспорье при рефакторинге.
[22:37:23] <gds> если до рефакторинга были полными и непротиворечивыми, а после изменились, и это отражается в предупреждениях/ошибках компилятора, это знакЪ.
[22:40:33] <gds> кстати, в revised даже выпилили теоретически-падающие матчи из value/let-in и из fun.  Если надо матчить неполно -- match с явным осознанием делаемого.
[22:40:48] ygrek вошёл(а) в комнату
[22:41:20] <gds> и для облегчения исправления своих ошибок потом, ясное дело: match проще дописать, чем let [_ :: tl] = lst in ..
[22:42:33] abiogenesis вошёл(а) в комнату
[22:44:17] bobry принял к сведению :)
[22:45:31] abiogenesis вышел(а) из комнаты
[22:58:10] Typhon вошёл(а) в комнату
[22:59:55] <Typhon> а ещё все знают, но никогда не поздно повторитьЖ let () = side_effects_function () вместое let _ = side_effects_function ()
[23:01:03] <bobry> видел в факе ага
[23:14:39] <ermine> интересно, скоро ли вынесут функторы из камла
[23:15:51] <bobry> куда вынесут?
[23:16:50] <ermine> на свалку истории
[23:17:10] <bobry> как же без них?
[23:17:58] <ermine> а они разве используются плодотворно?
[23:18:45] bobry сегодня первый раз столкнулся с необходимостью
[23:20:49] <ermine> бывает
[23:20:57] <ermine> я тоже в детстве сталкивалась
[23:26:18] <gds> ermine, рассказывай, как оно -- выросла?
[23:47:17] <ermine> gds: фиг изготовленный модуль посигнатуришь
[23:51:56] <Typhon> что такое "посигнатурить"?
[23:58:14] <ermine> module M : S
[23:58:38] <ermine> c with type
[23:58:48] <ermine> убийца можно
[23:59:31] <ermine> а щас посмотрела навскидку в популярные библиотеки и не увидела там слова функтор в сигнатурах
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!