Home
Objective Caml
ocaml@conference.jabber.ru
Четверг, 30 июля 2009< ^ >
f[x] установил(а) тему: Камль -- http://caml.inria.fr | Логи -- http://chatlogs.jabber.ru/ocaml@conference.jabber.ru/ | Верблюды грязи не боятся!
Конфигурация комнаты

GMT+4
[03:59:24] daapp вошёл(а) в комнату
[04:22:06] daapp вышел(а) из комнаты
[04:43:50] sevenov вышел(а) из комнаты
[04:44:06] sevenov вошёл(а) в комнату
[08:26:47] alermo вышел(а) из комнаты
[09:02:28] gds вошёл(а) в комнату
[10:22:46] daapp вошёл(а) в комнату
[10:24:10] Typhon вошёл(а) в комнату
[10:51:42] f[x] вошёл(а) в комнату
[11:40:00] DiGiTAL_CuRSe вышел(а) из комнаты
[11:55:52] DiGiTAL_CuRSe вошёл(а) в комнату
[12:02:58] sevenov вышел(а) из комнаты
[12:31:58] <gds> умом французов не понять.
type cell 'a = ref (option ('a * cell 'a)); -- требует -rectypes
type cell 'a = { va : mutable option ('a * cell 'a) }; -- работает и без -rectypes, хотя по сути эквивалентно.
[12:36:48] <f[x]> хых
[12:36:59] <f[x]> option и ref/mutable тут не играют
[12:37:12] <f[x]> т.е. важно заворачивание в структуру почему-то
[12:39:43] <gds> оно считает rec type когда ref, tuple, но не считает, когда record/variant.
например, с типом вида type inflist 'a = ('a * inflist 'a) -- всё понятно, почему разумно считать его rec type.
насчёт ref вот удивило слегка.
[12:40:41] <f[x]> type 'a x = 'a x;;
[12:42:03] <f[x]> не понятно вообще
[12:42:44] <gds> а тут даже -rectypes не помогают, тогда как в случае с cell помогли.
[12:44:00] <f[x]> ой, точно
[12:44:51] <f[x]> тогда тем более не понятно чем рек тупл лучше чем одно рек значение? :)
[12:46:00] <gds> тем, что
let rec my_tuple = (1, my_tuple)
, а в случае с type 'a x = 'a x такой фокус не пройдёт, тип как бы "неконструктивный".
[12:47:08] <f[x]> с type 'a x = A of 'a x тоже проходит
[12:47:37] <f[x]> типа дополнительный слой индиректа
[12:49:05] <f[x]> а, ну логично, чтобы было куда указателю указывать
[12:49:13] <gds> ага, и создать такое значение получается.
[12:56:51] <f[x]> а ещё я недавно просёк пользу от того что модули с сайд-эффектами. Можно параметризовать модуль не только по "чисьым" функциям, а и по значениям/замыканиям, т.е.
module Log = Logger.Simple(Logger.TargetChannel(struct let ch = stderr end))
open Log
[12:57:38] <f[x]> и дальше log_info "dsds" вместо log_info Config.logch "dsds"
[12:59:48] <gds> дадада, сейчас мелочь одну пишу почти только на функторах, тоже использую.
и логгер (с хитрым printf), и конфиг.
[13:00:33] <gds> только главное тут -- ровно в одном месте создать module Log, и оттуда его использовать.
[13:01:02] <f[x]> хитрый printf это ksprintf?
[13:08:01] <gds> не, проще.
value to_log_prefix () = Printf.printf "[%s] " S.service_name;
value to_log fmt = ( to_log_prefix () ; to_log_raw fmt );
(модуль S -- параметры конкретной "службы")
[13:26:28] <gds> кстати вот, надо как-то избавиться от постоянных "...\n%!" в конце сообщений лога, чтобы автоматически их добавлять. но руки не дошли разобраться.
[13:36:36] <f[x]> у меня так http://paste.org.ru/?ryiy7k
[13:41:26] <gds> ага, в TargetChannel.put передаёшь сообщение в виде строки. Так не интересно.
[13:43:03] <f[x]> на верхнем уровне log_* функции - там fmt
[13:43:53] <f[x]> плюс у меня много потоков поэтому форматтить сразу в канал нельзя
[13:48:43] <gds> чото думается, что в окамле почти пофиг (с точностью до небольшого увеличения расходов на шедулинг), форматтить ли напрямую в канал или через строку. Или нет?
[13:49:45] <f[x]> учитывая что канал с буфером то наверное да
[13:50:53] <ermine> в камле висят мутексы на каналах
[13:51:17] <f[x]> а, ведь точно
[13:51:24] ermine прочитала только два последних сообщения в конфе, если что...
[13:51:31] <f[x]> значит я перестраховался
[13:53:00] <gds> конечно, мутексы на каналах есть, но думаю, что fprintf ch "%s\n%!" превратится в 3 разных вызова, которые вместе не будут атомарны.
имхо перестраховался правильно.
[13:54:18] <ermine> у каналов, в отличие от сокетов, есть команда flush
[13:59:15] ermine в свое время тоже страдала этим вопросом, потом забила на этот вопрос поскольку теоретическая катастрофа на практике так и ни разу не случилась
[13:59:44] <f[x]> да, лок на уровне сишных примитивов
[14:00:24] <f[x]> но я почему-то ни разу не сталкивался с разрывом printf output'а, а при output_string output_string - видел
[14:00:31] <f[x]> наверное вещло просто
[14:00:36] <f[x]> * везло
[14:00:54] <gds> ха, разобрался с ksprintf. крутая штука, буду юзать.
[14:02:22] <ermine> а что там особенного?
[14:03:20] <gds> точнее, не в нём именно, а в методе организации отладочной печати с украшениями. по ссылке выше был код.
[14:03:54] ermine посмотрела в свой логгер - да, там ksprintf используется
[14:04:54] <ermine> у вас мой логгер есть в исходниках сульци, libs/logger/logger.ml
[14:05:12] <ermine> а-ля сислог
[14:06:01] <f[x]> ага, видел, на обьектах.
[14:06:33] <ermine> да без объектов лениво было придумать как подставить таргет печати
[14:06:51] <f[x]> кстати, почему бы не опубликовать git репу suci, а то диффы-патчи -- low-tech
[14:07:39] <ermine> потому что у меня myocamlbuild.ml до сих пор один на все репы (снаружи них)
[14:08:03] <f[x]> ermine: читай весь лог, там про то как функторы для этого приспособить
[14:08:54] <sceptic> ага, на каком-нибудь github
[14:09:03] <ermine> да, надо бы на функторы перейти, я объекты не очень-то люблю
[14:09:37] <f[x]> а что за проекты такие что в разных репах но с одним myocamlbuild?
[14:09:54] <ermine> но с функторами неудобно, когда в конфиге программы указывается метод логгирования и надо на ходу создавать таргет
[14:10:07] <f[x]> я вообще копирую myocamlbuild_config.ml между проектами - некузяво, но шарить слишком неудобно
[14:11:40] <ermine> f[x]: при переходе на гит мне говорили, что проекты принято держать в разных репах :) а я спрашивала как в гите ограничить доступ к разным проектам (как это возможно в svn)
[14:12:35] <f[x]> ermine: ну да, но тогда реально копировать и не заморачиваться. или выложить myocamlbuild.ml в отдельное репо и задекларировать dependency :)
[14:12:44] <ermine> держать myocamlbuild.ml в каждой репе неудобно, тогда бы пришлось инсталлить отдельный проект куда-нить, чтобы его увидели другие репы при сборке
[14:13:16] <f[x]> репы - либы?
[14:13:28] <ermine> например
[14:13:34] <f[x]> тогда выход сборки этого репо - cma файл
[14:13:40] <f[x]> он исопльзуется главным проектом
[14:13:47] <f[x]> и myocamlbuild у них разный
[14:13:49] <f[x]> не?
[14:14:41] <f[x]> ну т.е. по логике - если проект в отдельной репе - то планируется что его будут использовать отдельно - а раз так то он должен быть самодостаточным
[14:14:57] <ermine> мне удобнее когда поковыряешь в либле и сразу запускаешь сборку основного проекта - тогда камлобилд пересоберет все что надо
[14:15:13] <ermine> а не порождать сначала готовую либлу
[14:15:27] <ermine> вообще все это бесит
[14:15:30] <f[x]> ой, ну пусть скрипт обновляет зависимые либы
[14:15:52] <f[x]> это обычная трабла когда факторизуешь либу из кода
[14:16:00] <f[x]> либо либа, либо one-click build
[14:16:49] <ermine> я пока так оставлю как есть, мне так удобнее
[14:17:10] <ermine> зато это "неудобно" чтобы публиковать
[14:17:16] <f[x]> вот именно :)
[14:17:34] <f[x]> это неудобно всем кроме автора. раз уж ты хочешь либы отдельно
[14:17:39] <ermine> надо пробовать метапроекты
[14:17:45] <ermine> точнее осваивать
[14:18:06] <f[x]> я бы просто либы не выделял. до тех пор пока реально они не нужны будут отдельно
[14:18:42] <ermine> я так и делаю
[14:22:25] <ermine> f[x]: а ты презираешь объекты?
[14:22:47] <gds> я люблю объекты!11111
[14:23:18] <gds> printf "[tid=%i] %s\n%!" + printf "got int = %i" i =>
[5[[t] [ttigot int = 5tiid
idd=d==3[=21]t6]] i] got int = 5d got int = 5got int = 5
=got int = 5
[14:23:19] <ermine> gds: тогда этот логгер - для тебя :)
[14:23:44] <gds> ну если нужно динамически выбирать цель логгирования, то объекты являются вполне разумным выбором.
[14:30:01] daapp вышел(а) из комнаты
[15:16:40] <f[x]> пока что камлевские объекты я боязливо уважаю :)
[15:18:21] <f[x]> gds: понял
[15:18:45] <gds> чуял одним местом, что наткнусь на проблему, и наткнулся: байткод и нативный код по-разному хранят значения от сборщика мусора. Нативная прога кушает положенные пару метров, байткод отжирает память с постоянной скоростью.
А хотел сделать красиво: очередь сообщений со многими читателями (каждый получает все значения, отправленные в очередь), а для взятия значений -- функцию вида
pop : q 'a -> option ('a * q 'a)
let (val, new_queue) = pop old_queue
А байткод хранит ссылку на old_queue, сучечка.
Теперь даже не знаю -- потвикать байткод и выработать метод написания кода, который не будет течь, или превратить функциональную очередь в императивную, заставив каждого "читателя" вызывать какое-нибудь
let new_reading_end = clone old_reading_end
Выбор между двумя уродствами.
[15:21:20] <f[x]> может у байткода сборщик реже выхывался?
[15:21:34] <f[x]> как это он хранит?
[15:22:44] <f[x]> код давай
[15:23:09] <f[x]> "байткод и нативный код по-разному хранят значения от сборщика мусора"
это что значит?
[15:23:26] <gds> вот читалка:
value rec reader2 r =
match (Mrq.pop r) with
[ None ->
let () = sleep 0.1 in
reader2 r
| Some (v, r') ->
match v with
[ `Fin -> ()
| `Data _ -> reader2 r'
]
]
;
читал в caml-list о подобном. сейчас найду.
[15:23:58] <f[x]> типа не tail-call'ы получаются?
[15:24:23] f[x] в недоумении
[15:24:24] <gds> в плане живости значений -- не tail-call. в плане стека -- tail-call.
[15:24:45] <f[x]> если стек константный то где эти старые значения могут хранится?
[15:25:20] <gds> ща найду сообщение из рассылки либо набросаю более независимый пример.
[15:38:48] sevenov вошёл(а) в комнату
[15:38:53] <gds> http://caml.inria.fr/pub/ml-archives/caml-list/2001/01/c18ccf7365aec7066820d5d316de4ba2.fr.html
[15:40:43] <gds> http://caml.inria.fr/pub/ml-archives/caml-list/2007/11/3739bbe40688d5afe2639747827a0323.en.html и вся ветка
[15:42:19] ermine опять валяется в агонии под столом, пытаясь написать хоть пару строчек кода
[15:43:23] <gds> ermine: вылезай испацтала! ПИШИ @ КОМПИЛЯЙ!
[15:44:16] <ermine> а это поможет?
[15:54:11] <ermine> скорее поможет застрелиться и родиться заново
[16:41:36] <gds> ermine: кстати, есть такой обманный манёвр, когда всё лень. открываешь любимый редактор на фоне, чтобы был виден, иногда в ходе жизни смотришь туда, листаешь код. иногда моск включается и начинает работать. Это легче, чем похмеляться техническим спиртом, уверяю :]
[16:46:38] <f[x]> мне иногда помогает открыть список todo и начинать педалить какую-нибудь рутинную таску над которой думать не надо. потом либо включаешься либо минус один todo (что тоже полезно :)
[16:51:27] <gds> хороший метод. Собственно, единственная штука, зачем думаю завести себе todo list.
Пока же делаю подобное с задачами, которые в памяти есть.
[16:51:50] <f[x]> todo - просто файлик-список
[16:52:00] <f[x]> пытался всякие программки/вики исопльзовать - не катит
[16:53:07] <sceptic> org-mode
[16:53:19] sevenov вышел(а) из комнаты
[16:53:35] sevenov вошёл(а) в комнату
[16:54:22] <gds> для работы у меня такой файлик есть, а дома предпочитаю бумажку, если надо план изобразить. Там можно разные неприличные символы дорисовать карандашом, что стимулирует умственную деятельность.
[16:54:30] <gds> sceptic: это же целую ОС надо ставить ради такого!
[16:55:00] <f[x]> надо к сульци плагин написать - автобанилка за упоминание емакса :)
[16:55:08] <sceptic> :) думаю те кто пользуются emacs, найдут его удобным
[16:55:17] sceptic vimer
[17:05:58] <gds> мда, некрасивенько с байткодом получается.
let x = .. in E
если x мутабельный и будет увеличиваться, то пока окамл не посчитает результат E, он не освободит x, даже если он не нужен.
и та же фигня вроде бы не только с let-in.
[17:20:30] sevenov вышел(а) из комнаты: Replaced by new connection
[17:20:31] sevenov вошёл(а) в комнату
[17:31:24] gds вышел(а) из комнаты
[17:39:02] sevenov вышел(а) из комнаты
[17:39:24] sevenov вошёл(а) в комнату
[18:13:36] sevenov вышел(а) из комнаты: Replaced by new connection
[18:13:37] sevenov вошёл(а) в комнату
[18:17:36] sevenov вышел(а) из комнаты: Replaced by new connection
[18:17:44] sevenov вошёл(а) в комнату
[18:45:10] gds вошёл(а) в комнату
[18:57:55] sevenov вышел(а) из комнаты: Replaced by new connection
[18:58:00] sevenov вошёл(а) в комнату
[19:07:06] sevenov вышел(а) из комнаты: Replaced by new connection
[19:07:07] sevenov вошёл(а) в комнату
[19:13:32] sevenov вышел(а) из комнаты: Replaced by new connection
[19:13:34] sevenov вошёл(а) в комнату
[19:43:27] Typhon вышел(а) из комнаты
[19:58:06] sceptic вышел(а) из комнаты
[20:00:06] f[x] вышел(а) из комнаты: Computer went to sleep
[20:01:10] sceptic вошёл(а) в комнату
[20:06:53] telinit вошёл(а) в комнату
[20:12:10] sevenov вышел(а) из комнаты
[20:12:26] sevenov вошёл(а) в комнату
[20:19:42] telinit вышел(а) из комнаты
[21:04:57] gds вышел(а) из комнаты: Replaced by new connection
[21:04:58] gds вошёл(а) в комнату
[22:04:04] ermine размышляет над тем, какими способами в камле можно сварганить fsm (или нужная последовательность функций в зависимости от данных)
[22:06:42] <gds> если обрабатывать данные поэлементно -- любыми способами.
[22:07:37] <ermine> получил данные - функция, отправил данные - считал данные - функция, отправил данные - считал данные ...
[22:08:56] <ermine> при линейном программировании код уйдет за правый край редактора
[22:09:33] <ermine> если использовать оператор >>= из lwt, то получится примерно то, что надо
[22:11:21] <gds> имхо тут проще надо быть. Выбирай нормальный тип данных для хранения состояния, и дальше функциями.
>>= -- что-то вроде привязки/bind?
[22:12:59] <ermine> а вот есть еще такой момент: state в таких fsm можно определять либо типом sum, либо сохранят функцию для следующего этапа
[22:13:33] <ermine> традиционно используют sum, а почему? :)
[22:17:11] ygrek вошёл(а) в комнату
[22:18:01] <ermine> ygrek: а у тебя есть fsm?
[22:18:51] <ygrek> неа
[22:19:13] <ermine> gds: там еще проблема есть в том, что надо где-то сохранять промежуточные данные
[22:20:18] ermine прокатилась вечером на роликах и теперь мается фигней
[22:20:29] <gds> предполагаю, что sum используют потому, что для данных используют типы данных, а для функций -- функциональные значения.
[22:20:35] <gds> чоза промежуточные данные?
[22:21:53] ygrek думает для разреженных fsm'ов могут полиморфные варианты хорошо подойти
[22:23:15] <ermine> gds: sum: type t = | Start | Continue | End (ну, три фукнции) и соответсвенно
let abc state data =
match state with Start -> do_start data | Continue -> ....
[22:23:49] <ermine> а данные - то что вон этот do_start сам вычислил и надо бы где-нить сохранить для будущих вызовов
[22:23:51] <gds> ygrek: мысль звучит логично.
с другой стороны, сильно разреженная fsm -- обычно признак того, что нужно ещё чуть-чуть подумать над задачей.
[22:24:11] <ermine> в смысле промежуточные данные
[22:27:16] <ermine> можно сделать рекорд с мутабельными полями, чоль вариантов больше нет
[22:27:47] <ermine> ых
[22:38:08] <gds> ну, конкретно данные сохранять -- отвести для них тип данных и хранить рядом с текущим состоянием машины.
или что-то недопонял?
[22:40:52] <ermine> это я страдаю фигней
[22:41:13] <ermine> у меня данные всегда одни - xml
[22:42:44] <ermine> в ерланге fsm реализован как модуль, а за счет динамической типизации там нет такой проблемы с промежуточными данными
[22:44:06] <ermine> реально шикарная штучка
[22:45:28] <gds> зато там динамическая типизация не позволяет защититься от ошибок типизации в рантайме. Конечно, эрланговцам пофиг -- let it fail, я их могу понять. Как же иначе работать-то..
[22:47:25] <gds> так а тут какая проблема? Если бы была гарантия того, что сохранённые данные ты разберёшь нормально, то можно попробовать выразить эту гарантию посредством системы типов. Всё делается. Вещий Олег привнёс GADTs, можно и с ними поиграться для такого дела.
[22:47:47] <ygrek> сделай себе динамическую типизацию в камле
[22:47:48] <gds> конечно, такой же лёгкости неописуемой тут не будет.
[22:49:09] <ermine> ygrek: это json :)
[22:50:29] <gds> уже научились пихать в json код? или всё сводится к статической типизации и разборкам с sum types?
[22:51:39] <ermine> это я про "сделай динамическую типизацию в камле"
[22:52:00] <gds> так даже с помощью json не будет динамической типизации.
[22:52:27] <ermine> ну пчу не будет
[22:53:30] <gds> ну про разбор sum type вида Int of int | String of string -- это я понимаю, будет. Но это разве тру?
[22:54:47] <ermine> ну это смотря как подходить к такому мазохизму
[22:55:23] ermine пошла страдать в емаксе
[22:56:00] <gds> чорт, не люблю я задачи, где нужно "чтобы всё красиво", но без практического применения. Они слишком провоцируют на, так сказать, полировку нефритового стержня до блеска идеализма.
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!