Home
Objective Caml
ocaml@conference.jabber.ru
Четверг, 23 июня 2011< ^ >
gds установил(а) тему: Камль -- http://caml.inria.fr | Логи -- http://chatlogs.jabber.ru/ocaml@conference.jabber.ru/ | Светлое будущее -- http://camlunity.ru/ | Нефильтрованное настоящее -- https://github.com/camlunity/kamlo_wiki | Портер прошлое -- http://gdsfh.dyndns.org/kamlo/ | Верблюды грязи не боятся! | release crap, enjoy NIH | репортьте баги официальным дилерам | ocaml мёртв, move on
Конфигурация комнаты
Участники комнаты

GMT+4
[00:36:57] zert вышел(а) из комнаты: Replaced by new connection
[00:36:58] zert вошёл(а) в комнату
[00:42:29] gds вышел(а) из комнаты
[00:46:10] <Typhon> https://gist.github.com/1038558 чуваки хвастают монадическими (де)сериализаторами
[01:07:43] zert вышел(а) из комнаты
[01:19:51] ermine вышел(а) из комнаты
[02:27:16] Typhon вышел(а) из комнаты
[03:22:17] zinid вошёл(а) в комнату
[09:01:50] gds вошёл(а) в комнату
[09:39:53] bobry вышел(а) из комнаты
[09:40:40] <gds> подскажите, как через _tags выключить определённый warning, зная его номер?  Допустим, 4 (fragile match).
[11:06:01] ermine вошёл(а) в комнату
[11:11:59] komar вышел(а) из комнаты: Replaced by new connection
[11:11:59] komar вошёл(а) в комнату
[11:38:10] ftrvxmtrx вышел(а) из комнаты
[11:49:25] zert вошёл(а) в комнату
[11:58:16] komar вышел(а) из комнаты
[11:58:28] komar вошёл(а) в комнату
[12:17:20] <komar> Typhon, круто.
[12:18:21] <gds> komar: а что именно круто?
[12:19:21] <komar> gds: то, что оно работает.
[12:19:23] <komar> Можно заюзать.
[12:19:30] <komar> Программа работать будет.
[12:19:32] <komar> Круто!
[12:20:33] <gds> ааа!  обнимемся!  обнимемся!
а picklers зырил?
[12:21:47] <komar> Нет. Что это?
[12:22:10] <gds> это такие сериализаторы, которые пишутся одновременно для чтения и для записи.
[12:22:20] <komar> Круто! А где скачать?
[12:22:49] <gds> https://github.com/jaked/deriving/blob/master/lib/pickle.mli
[12:22:58] <gds> ну и вообще, deriving это умеет.
[12:23:24] <gds> насколько они монадные -- надо подумать.
[12:24:35] <gds> доломать deriving и иметь автоматически-сгенерированные сериализаторы -- это было бы ок.
[12:25:17] ftrvxmtrx вошёл(а) в комнату
[12:49:04] <ermine> таак, щас будем смотреть можно ли юзать ocaml-iterates в деле
[12:49:40] <ermine> смущает наличие типизации IO
[12:53:17] <gds> чего-чего?
[12:54:23] <ermine> а еще "а что тут является библиотекой?"
[12:55:11] <gds> и это не понял.
[12:55:51] <gds> .mllib есть, .cm[x]a собираются, что-то ещё надо?
[12:56:32] <ermine> ну кого опенить в своем файле и откуда брать функции, iteratees.ml - это ведь пример реализации с итератами
[12:57:02] <ermine> реально в библиотеке достаточно типов и функций ie_cont, run, еще чего по мелочам
[12:57:21] <ermine> а break, drop, take, etc - хмм
[12:58:08] <gds> линкуй -package iteratees (pkg_iteratees в _tags), далее
module IO = твой_нужный_IO
module I = Iteratees.Make(IO)
open I.Ops
и вперде
[12:58:24] <gds> I.take и подобное будет
[12:58:29] <gds> если не нравится, то open I сделай
[12:59:04] gds скоро away на часик, если чо
[12:59:24] gds вышел(а) из комнаты
[13:02:28] <ermine> и да, надо таки запретить писать библиотеки на ревизед
[13:15:05] Typhon вошёл(а) в комнату
[13:21:24] <komar> ermine: почему?
[13:24:47] <Typhon> читать сложно :-(
[13:24:57] <Typhon> а контрибьютить и того сложнее
[13:27:23] <komar> Ты просто ниасилила.
[13:27:55] <Typhon> я — он!
[13:32:17] <ermine> komar: а ты осилил?
[13:32:43] ermine вчера закончила осиливание хаскильной версии (он же оригинал)
[13:33:01] <ermine> теперь вот еще одна версия на чужеродном языке
[13:33:11] <komar> ermine: кого именно? Ревизед синтакс вроде да, и даже прелесть понял — легче отлаживать.
[13:34:19] <ermine> komar: ocaml-iteratees
[13:34:29] <komar> Нет.
[13:35:17] <ermine> слабак!
[13:36:32] <komar> Мне не нужно было.
[13:36:37] <komar> Я уже все понаписал.
[13:41:29] <ermine> и без документации совсем напряг, да
[13:42:29] <ermine> а еще какой-то >>% появился
[13:46:51] <komar> Документация не нужна же ж.
[13:46:58] <komar> По крайней мере, gds так говорит.
[13:49:47] <ermine> ага, в iteratees.ml длинные комменты, упаришься их все прочесть и запомнить
[13:53:12] <ermine> хотя не, надо почитать, после освоения хаскильной версии их читать стало легче
[13:55:21] gds вошёл(а) в комнату
[13:55:39] ermine пытается воткнуть в joinI
[13:57:13] <gds> документация на ocaml-iteratees не нужна почти.  Разве что то, что я в чятике час назад писал, вот то нужно.
[13:59:17] <ermine> gds: простой пример бы положил туда
[14:00:09] <ermine> gds: кста, а что такое >>%?
[14:00:21] <gds> >>% -- это bind_rev монады IO.
[14:01:05] <ermine> а что она делает?
[14:02:25] <gds> это то же самое, что bind, только с переставленными аргументами.  А именно,
( >>% ) : IO.m 'a -> ('a -> IO.m 'b) -> IO.m 'b
[14:04:15] <gds> iteratees, видите ли, удобно рассматривать как монаду.  >>= -- это её bind_rev.  Но в iteratees необходимо уметь делать сайд-эффекты, оттуда их сплетение с монадой IO, которая является отдельной монадой от iteratees.
[14:04:43] <ermine> функция жрет стрим и выдает результат монаде?
[14:05:41] <gds> функция, которая в IE_cont?  Да, выдаёт монадный результат,
IE_cont of option err_msg
            and (stream 'el -> IO.m (iteratee 'el 'a  *  stream 'el))
[14:07:16] <ermine> а в этом твоем коде можно получить подстроки, которые удовлетворяют матчингу, чтобы не нужен был свой аккумулятор?
[14:07:42] <gds> конкретнее опиши, что нужно.  подстроки -- какие/как?
[14:08:02] <ermine> например, получить из текста строчку урла
[14:08:41] ermine начинает смеяться
[14:08:43] <gds> нет, в качестве парсеров мои итераты не очень.
[14:09:36] <ermine> gds: но я уже разогналась, меня уже не остановишь
[14:09:37] <gds> то есть, конечно, можно, но надо бы пару комбинаторов написать, полезных для этого.
[14:09:57] <gds> дык давай вместе и напишем, мне выгодно расширять ocaml-iteratees.
[14:10:05] <ermine> собственно на вопросе "а как выдрать подстроку" я бросила свои парсеры и побежала исследовывать итераты
[14:10:20] <gds> подстроку -- смотря по какому критерию выдрать.
[14:10:44] <gds> "пока элемент удовлетворяет условию" -- можно, break_chars.
[14:10:53] <gds> это для char'ов, ну и break для остального.
[14:11:03] <ermine> по парсеру, не по ('a -> bool) функции
[14:11:25] <ermine> на функции - слишком просто
[14:11:48] <ermine> ладно, буду копать дальше
[14:12:03] <gds> смотря какой парсер.  Горизонтальная композиция есть ( >>= ), "альтернатива" есть (показывал как-то кодэ, могу присунуть его в репку).
[14:12:18] <ermine> но сегодня блин у меня мало времени
[14:13:15] <ermine> gds: вот надо объединение результатов >>=
[14:13:23] <gds> как это?
[14:15:04] <ermine> gds: в моем исследовании я дошла до того, что такой предикатный комбинатор просто должен не свалиться в Failed, а в Parsed тип результата - unit, чтобы сэкономить на операции выкусывания промежуточных подстрок
[14:15:38] <gds> не понял.  приведи пример того, где это будет использовано в конкретной задаче.
[14:16:54] <gds> а, понял.
[14:18:45] <gds> у меня "выкусывание результата" = создание Subarray.t = выделение блока памяти из 3 слов.  мелочи.
Если есть конкретные штуки, типа "игнорировать конкретную строку" или "игнорировать символы, пока они соответствуют чему-то" (I.drop_while), то их надо накодить так, чтобы они с Subarray.t работали, т.е. обрабатывали Stream of Subarray.t.
[14:26:15] <ermine> gds: вопрос - твоя реализация take что выдает?
[14:26:23] <ermine> список или подстроку?
[14:26:50] <gds> она выдаёт enumeratee 'el 'el 'a
[14:27:31] <gds> где type enumeratee 'elo 'eli 'a = iteratee 'eli 'a -> iteratee 'elo (iteratee 'eli 'a);
то есть, применив итерат : iteratee 'el 'a к take n, мы получим iteratee 'el (iteratee 'el 'a)
[14:28:07] <gds> и это не моя реализация, а олеговская.
[14:29:08] gds слышит шипение чьих-то мозгов
[14:34:49] ermine сравнила "переписанный" свой take с gds'шным вариантом
[14:34:52] <ermine> ужос
[14:35:14] <gds> а у тебя он что делает?
[14:36:16] <gds> небось, то же, что мои "joinI & take n stream2list" :]
[14:36:38] <ermine> у меня там еще нет абстракции для стрима
[14:36:56] <gds> а что обрабатываешь тогда?
[14:37:01] <ermine> а помницо, долго билась над уговариванием  типизации этой функции, чтобы скомпилилось
[14:37:45] <ermine> gds: ну в моем переложении пока только char list в стриме, чтобы только скомпилилось
[14:38:19] <gds> ну и нормально, всё это завелось бы.
[14:38:41] <ermine> вдобавок ты не юзаешь fst
[14:40:44] <ermine> вот бы еще научиться ездить по чанкам не только вправо, но и влево
[14:42:17] <gds> я не юзаю fst, он засирает код.  Сравни k s >>% (IO.return % fst) и k s >>% fun (it, _s) -> IO.return it
[14:42:26] <gds> влево -- вроде бы они "не про это".
[14:42:49] <ermine> gds: кстати, есть еще одно опасение - моя та реализация парсера xml тормозила из-за частых вызовов партиал аппликешнов функций
[14:42:59] <gds> может быть да.
[14:43:05] <gds> конечно, посимвольно читать оно не ок.
[14:45:37] <zinid> ermine: а ты парсер чего пишешь?
[14:59:46] <ermine> zinid: всего текстового
[14:59:52] <ermine> zinid: впрочем бинарного тоже
[15:00:40] <ermine> zinid: собственно парсер-то есть, надоели заморочки на стороне IO
[15:08:35] <gds> не, ну а чо "заморочки" -- если, например, монадным образом по 4 байта на каждый int32 читать, то и мусорщику работа будет, и шедулеру IO, и может даже операционке перепадёт, если буферизации нет -- все при делах :)
[15:11:19] <gds> ололо: http://paste.in.ua/2633/
[15:12:17] <ermine> gds: в камле нет классов типов, два раза >>= из разных либл (или трех, учитывая lwt) не заюзаешь
[15:12:58] <gds> правильно, поэтому >>%.  А где третяя монада?  Только две насчитал: iteratees + io.
[15:13:09] <ermine> а в моем случае я еще не поняла, как скрешивать тип парсинга с типом итератов
[15:13:34] <ermine> zinid: ну монады парсеров
[15:13:39] <ermine> ой
[15:13:41] <ermine> gds:
[15:14:39] <gds> да, третяя манатка.  Но можно сделать такие парсеры, к которым применим >>= итератов.  Или что у тебя в парсерах вообще делает bind?
[15:15:48] <ermine> угу, хочу попробовать такое сделать
[15:17:27] <ermine> let (>>=) p1 p2 s =
match p1 s with
| Parsed (r, s') -> p2 r s'
| Failed -> Failed
[15:17:33] <ermine> тривиально всё
[15:19:07] Digimmortal вошёл(а) в комнату
[15:19:41] <gds> а, ну так вместо Failed бери throw_err Failed, а >>= у тебя будет итератовский.  Ровно то же самое будет: если распарсилось и есть результат, то остаток передастся следующему парсеру.
[15:20:53] <gds> РАСП...АРСИЛО КРОВЬ КИШКИ МОНАДЫ
[15:24:27] ermine было спросила "а как же в ||| это реализовать... и задумалась, тем более что (a >>= b) ||| (c >>= d) тут выглядит непонятно
[15:27:15] <gds> что именно "в |||" реализовать?  Саму по себе ||| надо реализовать, вот это да.  Но какая должна быть семантика её?  Представь разные случаи.
[15:35:50] <komar> Интересно, а если вместо Parsed _ | Failed использовать _ | raise Failed, то быстрее будет?
[15:37:24] <gds> если везде обмазываться try-with, то можно по стеку вылететь, да и вообще, везде ловить надо будет.  И с манатками исключения не очень хорошо кидаются-ловятся.
[15:40:53] <gds> komar: рассмотри, например, исключения в lwt.  "и так у них всё."
[15:50:38] <ermine> gds: let (|||) p1 p2 s =
match p1 s with
| Failed -> p2 s
| Parsec _ as ok -> ok
[15:52:01] <gds> то есть, "пробовать первый, но если он выдал ошибку, то идти вторым"?
[15:52:47] <ermine> да, с тем же инпутом
[15:53:16] <ermine> если учесть что p1 сам по себе может иметь внутри себя кучу ||, >>=, то это выглядит феерично
[15:53:38] <ermine> накапливать чанки
[15:53:48] <ermine> ужос
[15:56:20] <ermine> но это, конечно, в случае кошмарных парсеров, которые заставляют бегать туда-сюда
[15:57:59] <ermine> легко придумывающийся пример - поиск урлов в тексте, если строка начиналась на http://, но дальше чота данные совсем не похожи на урл, возвращаемся и бросаем в другой парсер искать что-то другое
[15:59:35] <ermine> а сам урл, сам по себе тоже ахтунг
[16:01:25] <gds> можно параллельно давать чанки обоим итератам.  но вроде не получится реализовать такую штуку: если первый парсер наломался, скушав 10 чанков, а второй парсер скушал только 2 чанка и выдал результат, то остальные 8 чанков прощёлканы.  или я чего-то не понимаю.  или не подумал.  но я подумаю ещё.
[16:01:56] <gds> просто "несколько итератов, а там какой первый кончит, тот и победил" -- это я умею.
[16:04:15] <ermine> gds: ну до такой подробности я не додумалась, но видимо где-то так, хотя я вообще думала про грязную систему чанков, где 8 чанков не прощелкиваются, а сложены в кладовке
[16:06:13] <ermine> gds: мне поначалу вообще казалось, что твоя архисложная система массивов для стримов как раз это умеет
[16:06:17] <gds> вот, про кладовку тоже думал.  В принципе, мне не сложно написать комбинатор, который будет сохранять чанки в себе, кормить ими итераты по очереди, и возвращать первого, у кого получилось, и копировать остальные элементы в здоровый чанк, который возвращают из IE_cont.
[16:07:11] <gds> да ничего архисложного там нет.  В общем, сейчас я кое-чем другим займусь, а то моск не варит, но под вечер или завтра вернусь к этой проблеме.  Что-то тут нечисто, причём, не исключено, на концептуальном уровне.
[16:07:40] <ermine> итерат вместо чаков, мммм
[16:08:15] <gds> в общем, разной степени паршивости решения могу предложить хоть сейчас, но не буду.
[16:10:25] <ermine> надо уметь запихнуть данные обратно в сокет
[16:11:17] <gds> ололо
не, вернуть чанк с необработанными данными -- это нормально для любого итерата.  Фактически, так всегда и делается, см. IE_cont.
[16:11:32] ermine пытается понять -- сокет - это мутабельное или нет
[16:12:17] <ermine> типа обычно бэктрейс выполняется в том виде, что на нужном шаге получаешь нужный срез инпута, который уже получил однажды
[16:14:06] <ermine> ладно
[16:16:07] <ermine> gds: вот ты говоришь, что знаешь как побеждает один итерат из нескольких, а вот в такой схеме (a ||| (b ||| (c ||| d))) ?
[16:18:05] <gds> тут тоже понятно -- либо a, либо b|||(c|||d), а в итерате b|||(c|||d) -- понятно тоже, одно либо другое.  даём чанк общему итерату, ||| расписывает его на два итерата, во втором из них ||| снова расписывает этот же чанк на два, и так далее.  По идее, даже такая схема будет работать нормально.
[16:20:10] <ermine> а, да
[16:20:38] <ermine> а в чем ты видишь сложность тогда?
[16:20:49] <ermine> в 8 чанках?
[16:21:49] <gds> в случае "первый парсер мучить до упора, а если облом, то второй мучить" -- в том, что второй может остановиться после 2-го чанка.
[16:21:56] <gds> а первый -- обломаться после 10го
[16:23:47] <ermine> надо чтобы облом тоже возвращал остаток инпута, хе-хе
[16:24:17] <ermine> если errmsg сделать полиморфным, то наверное можно
[16:24:51] <gds> облом -- который "после 10го чанка"?  ну, вернёт остаток 10го, допустим, а дальше что?  Откуда брать чанки 3..9?
[16:27:42] <ermine> функция бинда знает оба варианта стрима, который пришел, и который вернулся из веток Parsed и Failed, ну тогда это три варианта
[16:27:51] <ermine> вот тут где-то надо подумать
[16:30:15] <gds> не, сохранять чанки -- это не проблема на практическом уровне, но на теоретическом как-то не ок.
[16:30:20] <gds> точнее, ||| это не ок.
[16:32:57] <ermine> почему? потому что идеи имплементации грязные?
[16:33:11] <gds> потому что не "потоковый".
[16:35:58] <ermine> ну тогда ой, а бывают разные "или"?
[16:36:45] <gds> вот над этим буду думать.
[16:36:50] <ermine> тут наверное надо покопаться в теории конечных автоматов, но куда мне до этого
[16:37:24] <gds> тут такое рассуждение приходит в голову: а что, если первая альтернатива скушает 100Гб данных, а потом внезапно ей что-то не понравится?
[16:39:31] <ermine> gds: ну, а как это в случае одного-единственного итерата, который строит структуру, скушает 100Gb, а в конце внезапно обнаружит неперевариваемые данные?
[16:39:51] <ermine> может, в качестве слабого утешения подойтет
[16:40:14] <gds> структура = полезные данные, тем более, она может быть и сильно меньше, а вот пришедшие 100Гб надо где-то хранить.
[16:41:54] <gds> думаю вот над таким "решением": с помощью комбинатора ввести "явный бектрекинг" с возможностью сказать "всё, эта ветка пойдёт дальше сама независимо от фейлов", соответственно, с освобождением кладовки.
[16:42:21] <ermine> а вообще надо свопить!
[16:43:54] <gds> а своп будем хранить на рамдиске!
[16:45:10] <ermine> не, чанки - это таки зло
[16:45:17] <ermine> а не оператор |||
[16:46:03] <ermine> чанки слишком независимы друг от друга и их можно перепутать, потерять, подмахнуть
[16:46:05] <gds> чанки -- всего лишь средство потоковой обработки.
[16:46:26] <gds> если напрямую с ними работают мало, то ошибиться сложно.
[16:47:00] <ermine> а поток ли они?
[16:47:25] <gds> последовательность чанков -- да, причём, в виде весьма эффективного представления.
[16:48:47] <ermine> но эта последовательность не позволяет получить срез последовательности, который был вот тут 5 минут назал
[16:49:23] <ermine> может еще посмотреть на модуль Weak
[16:49:32] <gds> мне -- позволяет.  достаточно сохранять её.
[16:49:50] <ermine> хотя он конечно не запоминает нифига состояние, но терять оно умеет, если не нужны данные
[16:50:48] <ermine> gds: ну поэтому ты говоришь, что ||| - не ок
[16:51:27] <gds> потому что "не потоковый".  Точнее, он-то ок, но для каких-то других случаев.  Потом подумаю ещё, сейчас ничего нового не придумаю.
[16:55:40] <gds> вообще, насчёт ||| и прочего "умного" парсинга -- всё-таки склоняюсь к тому, что надо разделять "потоковую обработку" и "парсинг с возвратами".  Но, опять же, мысль какая-то туповатая.
[16:57:05] <komar> А шо, итераты возврат не держат?
[16:58:02] ftrvxmtrx вышел(а) из комнаты
[16:59:29] <gds> ни у кого не было пока потребности их это попросить.
[16:59:30] <ermine> komar: итерат получает стрим и возвраает тьюпл итерата и остатка стрима
[17:00:04] <komar> Тю, а зачем они тогда нужны вообще?
[17:00:13] <gds> для потоковой обработки.
[17:00:38] <komar> Стримы со СКОРАСТЬЮ, что ли?
[17:01:24] <gds> да уж не поэлементные.
[17:01:31] <komar> Понял.
[17:01:49] <ermine> komar: для преоделевания задниц со блокировками в IO и недостаточными данными из IO
[17:02:14] <komar> Не понял, ну да ладно. Потом потыкаю.
[17:02:19] <ermine> komar: как и многое в хаскиле, это унифицированный API, освоить суть которого дано только некоторым
[17:02:29] <gds> и ещё многих задниц, кстати.  Изначально проблема была в х-евой модели ввода-вывода.
[17:03:11] rren вошёл(а) в комнату
[17:03:14] <ermine> lazy io?
[17:03:37] <ermine> ну я даже не знаю, какие там проблемы, но они любят эти слова
[17:05:29] <ermine> komar: а еще это вполне удобный "откусывающий" парсер, когда надо строго идти вперед и откусывать отработанные данные
[17:05:54] ftrvxmtrx вошёл(а) в комнату
[17:07:47] ftrvxmtrx вышел(а) из комнаты
[17:16:59] ftrvxmtrx вошёл(а) в комнату
[17:28:49] <ermine> gds: итерат в "или" может вернуть не ошибку, а следующий итерат, как и все нормальные итераты
[17:28:58] <ermine> или даже должен
[17:29:05] ftrvxmtrx вышел(а) из комнаты
[17:33:08] ftrvxmtrx вошёл(а) в комнату
[17:34:26] <ermine> кстати, там был maybe в итерате read_chunk
[17:35:30] <ermine> итерат с тремя итератами
[17:35:38] <ermine> gds: опять плохая идея?
[17:39:19] <ermine> да, похоже, понятно как комбинировать парсеры с итератами, дело осталось с gds с хитрим стримом
[17:41:12] <gds> ermine: насчёт "или" -- если не будем сохранять то, что понравилось первому итерату, то не сможем дать это второму, как ни крути.
[17:43:06] <ermine> gds: итерат в или возвращает result option и остаток стрима, который в случае None как бы идентичен начальному (без оглядки на коллекцию накопленных чанков)
[17:46:59] <ermine>   maybe (frame_err (exc ("Bad chunk size: " ++ str)) iter) read_chunk $ read_hex 0 str
[17:47:17] <ermine> вот так выглядит или, и оно, пожалуй, мне нравиццо
[17:48:24] <gds> не, представь такой расклад.  обрабатываем a|||b, и первый кушает 10 чанков, а второй, даже если ему запихивать, кушает 2 чанка.  Первый после 10 чанков обламывается.  Чем кормить второго?
[17:51:42] <ermine> gds: ну облом пусть вернет IE_cont (None, maybe_handler), stream
[17:51:56] <gds> да, ок, дальше что?
[17:52:04] <ermine> или как там
[17:52:09] <gds> stream, заметь, будет содержать либо кусок 10го чанка, или ничего.
[17:52:14] <ermine> чота запамятовала, куда девать результа :)
[17:52:23] <ermine> с непривычки еще
[17:52:49] <gds> представь, что первый итерат -- "drop 10000000 >>= fun () -> throw_err Ehahaha"
[17:53:38] <ermine> у тебя только деструктивные парсеры
[17:54:37] <ermine> они деструктивные и без "или", от них никакого толку
[17:56:43] <ermine> а я вот хочу еще такой конкретный пример: в markdown можно выделить текст _выделением_, я вот решила, что если в тексте встретилось начало выделения _, но текст завершился пустой строкой (абзац кончился), то в этом случае нет никакого выделения и текст остается с сиротливым знаком форматтера в виде обычного символа
[18:00:17] <komar> ermine: тебе написать парсер маркдауна на моих велокомбинаторах?
[18:01:17] <ermine> komar: у меня есть парсер маркдауна на одной цельной длинной строке
[18:01:46] <komar> И что, плохо работает?
[18:01:52] <ermine> komar: а тебе не слабО парсить не на одной цельной строке?
[18:01:58] <komar> Не слабо.
[18:02:18] <komar> http://komar.bitcheese.net/src/textile-ocaml/doc/Textile_parser.html
[18:03:06] <ermine> komar: а как у тебя выглядит инпут в случае чтения из файла?
[18:03:07] <komar> Ну и здесь http://komar.bitcheese.net/src/textile-ocaml/doc/Textile_html.html example of use.
[18:03:16] <komar> ^^^
[18:03:32] <ermine> а, стрим с подкачкой
[18:04:12] <komar> В случае Lwt я пролетаю как фанера над Парижем, но пока нормально.
[18:05:00] <ermine> komar: а еще я хочу получить урл в виде строчки урла, без использования аккумуляторов при парсинге!
[18:05:10] <komar> Че?
[18:05:10] <ermine> komar: есть чем порадовать?
[18:05:57] <komar> А если у тебя будет http://www.goo*(&%F(D*S&BTD(*&FS%, то парсер завалиться должен?
[18:06:05] ermine через полчасика пойдет катать 60 км
[18:06:42] <komar> Он же должен откатиться и по-новой парсить.
[18:06:55] <Typhon> ermine: где ты катаешь 60 км в москве?
[18:07:00] <ermine> komar: ну урл должен быть урлом палюбому, иначе это просто набор букв
[18:07:14] <gds> ermine: в случае _выделения_ -- как скушали '_', через определённый комбинатор запускаем параллельно два жрущих итерата -- первый до следующего символа '_', второй до '\n', а какой из результатов вернуть (если оба '_' и '\n' есть в чанке) -- решать по параметру "у кого больше остаток потока".
[18:07:37] <ermine> Typhon: в лужниках, 12 кругов по центральной алее
[18:07:59] <komar> gds: плохой параметр какой-то.
[18:08:04] <Typhon> блин, круги неинтересно :-)
[18:08:31] <gds> komar: почему?  shortest match и все дела.
[18:09:27] <ermine> gds: интересный вариант, ага
[18:10:22] <komar> gds: точно помню, что мне хотелось, чтобы парсер вел себя обязательно по типу «второе только тогда, когда не получилось первое».
[18:10:34] <ermine> komar: вариант плох только с точки зрения извращения семантики, не более того
[18:10:51] <ermine> надо раскрепощаться
[18:10:59] <komar> Впрочем, для маркдауна сгодится.
[18:11:22] <gds> komar: ну так это тогда честный бектрекинг надо.  понятно, что поток надо где-то сохранять.
[18:11:30] <ermine> а вот правильно пропарсить урл?
[18:11:51] <komar> Вообще, учить парсер разбору того, «что же тут имелось в виду в этом lightweight markup language» — сущий ад.
[18:12:12] <gds> можно парсить урл строго, можно "среди текста".  Если строго -- все знают rfc.  Если "среди текста" -- тоже где-то в rfc были примеры, что эвристике следует считать за урл.
[18:12:30] <komar> gds: пруфлинк второго!
[18:13:07] <gds> хитрец.
[18:13:41] <ermine> Typhon: 12 кругов - по будням, тем более что до лужников тут всего 2.5 км, в выходные надо выползать катать 200 км за городом
[18:15:43] <ermine> gds: если сверять с rfc, то как итерить по тексту и вернуться с обломом?
[18:15:56] <gds> komar: rfc 1738, "Recommendations for URLs in Context"
[18:16:45] <ermine> сверять надо, чтобы не нарваться на яваскрипты и прочие xss
[18:16:55] <gds> а, не, rfc мимо.
[18:16:56] <komar> Надо бы забацать сервис человекочитаемых rfc'ов.
[18:17:34] ftrvxmtrx вышел(а) из комнаты
[18:17:46] <komar> gds: ето нето
[18:20:25] <ermine> и вообще, тут все упорно мыслят в терминах "а где б еще применить аккумулятор, чтобы не простаивал!"
[18:20:28] <gds> в rfc3986 получше с "урл в контексте", но всё же.
[18:20:43] <ermine> даже в случае с недобитым _ форматтером
[18:21:28] <gds> ermine: не знаю, с _ вроде всё ок: бегут параллельно, побеждает один.
[18:21:29] <komar> ermine: ничуть.
[18:21:56] <komar> ermine: йа мыслю в контексте «задолбетесь без аккумулятора, берите его, он вам гиг памяти не сожрет».
[18:22:30] <ermine> gds: мне показалось, что там два аккумулятора - _ и остальная строка
[18:23:47] <gds> если в этом смысле, то да.  А какие ещё варианты есть?
Вообще, можно было бы построчно разбить, а потом над каждой строкой измываться, имея гарантии того, что она не разбита на несколько чанков.
[18:26:20] <ermine> gds: вариант - отматчить и получить подстроку?
[18:26:32] <gds> недопонял.
[18:27:14] <ermine> gds: ты тут давно спрашивал, есть ли модуль подстрок
[18:27:22] <ermine> что-то такое в этом роде
[18:27:32] ermine натянула на себя велоформу
[18:28:22] <ermine> gds: короче, хотелось еще иметь функции для тестирования данных, а не только "получить, если годится"
[18:30:15] <gds> куда их запихивать, если не годятся, это вопрос.  Будем думать.
[18:33:46] <ermine> в модуль стрима
[18:34:08] ermine застегнула шлем и натянула варежки
[19:06:05] zinid вышел(а) из комнаты
[19:31:39] <gds> кто-нибудь собирал свежий "odn" своими руками?
[19:58:35] klapaucius вышел(а) из комнаты
[20:03:26] klapaucius вошёл(а) в комнату
[20:35:03] Digimmortal вышел(а) из комнаты
[21:08:49] <ermine> ох
[21:09:11] <ermine> 50 км, пробитая камера и наверняка две испорченные шины
[21:42:36] bobry вошёл(а) в комнату
[21:43:25] Typhon вышел(а) из комнаты
[22:57:39] bobry вышел(а) из комнаты
[22:59:22] bobry вошёл(а) в комнату
[23:12:57] ftrvxmtrx вошёл(а) в комнату
[23:48:37] avysk вошёл(а) в комнату
[23:48:45] avysk вышел(а) из комнаты
[23:49:25] <gds> ermine: ты чего issue не закрываешь?  https://github.com/ermine/mltls/issues/1  -- уже 3 месяца висит, емае.  нагуглилось случайно, но всё же.
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!