Home
Objective Caml
ocaml@conference.jabber.ru
Среда, 2 июня 2010< ^ >
ygrek установил(а) тему: Камль -- http://caml.inria.fr | Логи -- http://chatlogs.jabber.ru/ocaml@conference.jabber.ru/ | Верблюды грязи не боятся! | release crap | judge by commits, not comments | ocaml мёртв, move on
Конфигурация комнаты
Участники комнаты

GMT+4
[00:00:40] <olegfink> Obj.magic тут, конечно, совершенно хамский, но мне уж очень хотелось 'a
[00:07:28] <gds> вот как раз об извращениях говорили недавно :)
[00:08:36] <olegfink> ну это вроде как не извращение пока
[00:08:46] <olegfink> извращением оно станет, когда я его заюзаю для чего-нибудь
[00:09:01] <olegfink> а пока -- это "красивая фича типовой системы"
[00:38:54] gds вышел(а) из комнаты
[00:46:55] ermine вышел(а) из комнаты
[00:56:18] digital_curse вышел(а) из комнаты
[02:53:59] olegfink вышел(а) из комнаты
[07:29:07] digital_curse вошёл(а) в комнату
[08:28:37] iNode вошёл(а) в комнату
[09:15:13] Mon вышел(а) из комнаты: Replaced by new connection
[09:15:15] Mon вошёл(а) в комнату
[09:55:00] gds вошёл(а) в комнату
[10:04:26] serp256 вошёл(а) в комнату
[10:20:44] iNode вышел(а) из комнаты
[10:29:58] <gds> "fun" имеет необычайно низкий приоритет, из-за чего конструкция вида
a >>= fun x ->   b >>= fun y ->   c
парсится как
(a >>= (fun x ->   (b >>= (fun y ->   (c)))))
и, как я понимаю, не существует такого оператора OP, чтобы
a >>= fun x ->   b >>= fun y ->   c  OP  q
распарсилось как
(a >>= (fun x ->   (b >>= (fun y ->   (c)))))  OP  (q)
прав ли я?
[10:35:41] iNode вошёл(а) в комнату
[10:46:10] Typhon вышел(а) из комнаты
[11:09:03] ermine вошёл(а) в комнату
[11:12:07] ʇsʎɯ вошёл(а) в комнату
[11:26:58] iNode вышел(а) из комнаты
[11:27:16] iNode вошёл(а) в комнату
[11:43:35] olegfink вошёл(а) в комнату
[11:45:15] <ʇsʎɯ> http://pastebin.com/qEJnSxr5 - подправил пару мест. кому нечего делать - прошу к засиранию. кому есть что - не отвлекайтесть, это не важно
[11:55:01] <gds> "
    let n,  addr = Unix.recvfrom sock buf 0 in_dgram_size [] in
    if n < in_dgram_size then buf.[n]  <- ' ';
"
я бы это в отдельную функцию вывел, типа "recv_and_terminate_by_space" (условно), заодно отвязать проверку индекса (которая в голове, при чтении кода) в выражении buf.[n] от in_dgram_size (которая связана через String.create).  Т.е. чтобы функция читала не больше, чем строку, и, если надо, завершала пробелом.
Ну и ловля исключения Failure отличается от ловли других исключений, есть ли на это причины, кроме как "потому что изначально так написал и лень переделывать"?
[11:59:00] <ʇsʎɯ> Failure: я искренне верю в то, что программу можно написать корректно (иначе писал бы на Java), поэтому те, исключения, которые кидаю не я, должны обрушивать всё нахрен. а) это будет стимулировать к фиксу бага, а не (сделаем обработчик), б) так легче отловить
[12:00:49] <ʇsʎɯ> с recv согласен в принципе, но я не люблю оверабстракционизм, "иногда лучший способ реюзабилити - копипаста" (с) Д.Е.К.
[12:01:09] <ʇsʎɯ> тем более, что терминируется инпут не всегда
[12:03:51] <gds> обрушивать нафиг -- правильный ход, но штука для отлова Failure тоже это же делает (exit 1).  А так -- можно централизованно добавить печать бэктрейса например, или ещё что-то.  Хотя надо будет думать, как вытаскивать n из Failure n в случае, если словили действительно Failure n.
[12:04:29] <ʇsʎɯ> flamebait: ещё раз посмотрел revised синтаксис - не моё это. я не люблю скобочки, кроме (). да и те не особо. поэтому и пишу на ML, а не на Lisp :) Ну и из-за АТД ещё, конечно
[12:05:06] <gds> recv -- тут не абстракция является целью, тут безопасность и хранение одинаковых вещей в одном месте.
[12:05:29] <ʇsʎɯ> gds: хм, а знаешь, ты прав, я добавлю туда | _ -> 0. /. 0.
[12:05:37] <ʇsʎɯ> чтобы падало в кору
[12:05:42] <ʇsʎɯ> там сразу и разобраться можно
[12:06:03] <ʇsʎɯ> радикально, конечно, но...
[12:06:33] <gds> а нафиг?  по-моему, выйти через exit 1 и выдать бэктрейс стека -- самое то.
[12:07:19] <gds> в revised экстра-скобочки нужны для ограничения паттерн-матчинга, остальное согласуется с original syntax coding style (там тоже рекомендуют последовательности ограничивать begin-end, они же появились в новых версиях revised).
[12:08:30] <ʇsʎɯ> ну посмотрю ещё
[12:08:56] <ʇsʎɯ> кстати, Zipper и Finger tree для моих нужд не подошли
[12:09:05] <gds> finter tree почему не?
[12:09:16] <f[x]> 0./.0. не упадёт в кору
[12:09:58] <f[x]> failure ловить не надо
[12:10:43] <f[x]> лучше оборачивать let () = try main () with exn -> Printexc.to_string exn; print_endline (Printexc.get_backtrace ()) и всё
[12:17:03] <f[x]> btw unix.time возвращает с точностью до секунды
[12:22:06] <ʇsʎɯ> f[x]: ну так да, до секунды и надо, зачем точнее?
[12:29:09] <ʇsʎɯ> gds: потому что мне нужно добавлять быстрее, чем O(n) и индексировать за O(1). А Finger tree индексирует за O(log n) и не гарантирует, что фингеры отсортированы. Или я чего-то не дочитал...
[12:29:15] <ʇsʎɯ> но Zipper точно не подходит
[12:34:05] <gds> "индексировать" -- ?
[12:36:46] <ʇsʎɯ> ну вот, запихал я очки в таблицу, потом мне надо выдать тех, кто над этим местом и после этого места, сами номера мест (индекс) тоже нужны
[12:49:13] <gds> по какому критерию ищешь -- по известному номеру места?
[12:49:59] <ʇsʎɯ> нет, на входе у меня только очки
[12:50:24] <ʇsʎɯ> на выходе список [<место>:<очки>:<ник>]
[12:51:08] <gds> тогда быстрее, чем O(log(n)), никакая структура данных не позволит, кроме массива, в котором индекс равен этим самым очкам.
[12:51:44] <ʇsʎɯ> ну вот и я думаю, ограничить кол-во очков на 16 млн. и не париться
[12:51:56] <ʇsʎɯ> завести массивчик и няшно там жить
[12:53:57] <gds> только неизвестно, будет ли это дешевле, чем что-то более умное (если бы для диска, всякие btree предложил бы, но для памяти тоже аналоги есть, сходу не скажу).
[12:58:39] <ʇsʎɯ> T-tree
[12:58:50] <ʇsʎɯ> мне умно не надо, мне надо просто и быстро
[12:59:03] <ʇsʎɯ> а чё не будет дешевле-то?
[12:59:18] <ʇsʎɯ> в каждом эл-те массива живёт список
[12:59:23] <ʇsʎɯ> вставка О(1)
[12:59:37] <ʇsʎɯ> индексация О(1)
[12:59:45] <ʇsʎɯ> а мне больше ничего и не нужно
[12:59:59] <ʇsʎɯ> заверну это в няшную Scoretbl и будет ок
[13:01:05] <gds> короче, бери субд, умеющую sql, далее добавляй через insert, поддерживай индекс по очкам, и бери слева-справа запросом вида "select /*+ first_rows // если актуально */ * from таблица where очки<=нужных order by очки desc" и соответственно ".. where очки>нужных order by очки", читая нужное количество записей или выбирая его через "select .. from (тот запрос) where rownum < n".  Оракл строит нормальные планы, проверил :)
[13:01:52] <ʇsʎɯ> бгг
[13:02:05] <ʇsʎɯ> тут я не сомневаюсь насчёт оракла
[13:02:10] <ʇsʎɯ> я думал sqlite собсна
[13:02:15] <ʇsʎɯ> но он тормоззз
[13:02:30] <ʇsʎɯ> у меня Fx3.5 который на нём запускается секунд 5-6
[13:02:44] <ʇsʎɯ> через два месяца после очистки кэша
[13:04:02] <f[x]> маркетоидный fud
[13:04:11] <f[x]> на какой операции sqlite тормоз?
[13:04:54] <ʇsʎɯ> откуда я знаю?
[13:05:11] <ʇsʎɯ> firefox запускается долго, а у него всё сныкано в sqlite
[13:05:14] <f[x]> я и говорю - fud
[13:05:16] <ʇsʎɯ> причём тут маркетинг?
[13:05:40] <f[x]> при том что вывод не от сути, а от балды
[13:09:29] <ʇsʎɯ> ну я ради прикола посмотрю куда там io идёт
[13:09:50] <ʇsʎɯ> но не порнуху же мою он на диске сканит
[13:40:40] <gds> подумалось, что можно сделать структуру типа
type 'a arraytree = Node of index_begin * multiplier * 'a arraytree | Leaf of 'a array
значение Node index_begin multiplier arr будет содержать массив таких деревьев, хранящих значение от index_begin до index_begin + (Array.length arr) * multiplier.  При небольшом количестве уровней будет почти O(1) добавление/изменение, почти O(1) поиск.  Сложнее, вот это да.
[14:02:03] <gds> попал я с LogicM.  Хочется, чтобы гламурно было.  А для этого иногда нужна операция, которую называют msplit, и, в результате, мне нужно для данного s : 'a Stream.t извлечь из него head : 'a и tail : 'a Stream.t так, чтобы для непустого s: 1. Stream.peek s = Some head, 2. поток s после выполнения Stream.junk s и поток tail давали одни и те же данные (возможно, чтобы были физически равны, пофиг).
А для этого -- только патчить поток s.  Что требует Obj.  В stdlib это сделали, но то stdlib, а то моя библиотека, а это две большие разницы.
Есть идеи?
[14:11:43] <f[x]> ну а нельзя s вернуть как обертку над tail?
[14:11:51] <f[x]> хотя наверное без obj никак?
[14:12:01] <f[x]> то что stream не расширяемый это epic fail
[14:12:11] f[x] юзает патченый ExtStream
[14:12:20] <f[x]> для extlib.IO
[14:13:12] <gds> можно вернуть s, но надо бы ещё заменить все ссылки на s ссылками на новый поток.
[14:13:18] <gds> а насколько патченный?
[14:29:47] Typhon вошёл(а) в комнату
[14:35:11] olegfink вышел(а) из комнаты
[14:40:19] <gds> http://pastebin.com/98QhCKNb -- покритикуйте :]
на практике в частных случаях работает, судоку решает на отличненько.
[14:51:58] olegfink вошёл(а) в комнату
[14:52:09] olegfink вышел(а) из комнаты
[14:52:09] olegfink вошёл(а) в комнату
[14:57:49] <gds> а в целом же, судоку с помощью LogicM я решаю так: http://pastebin.com/mJdcdFEr -- тупаково (например, можно было оформить empty_cells как список, который один раз родить и по которому шариться), но решил оставить всё так, как оно писалось.  А изначально писалось именно так.
[15:02:10] <ʇsʎɯ> gds: у меня основное требование, чтобы от a.(i) можно было легко перейти к a.(i-1) и a.(i+1). Как только появляются деревья, всё усложняется
[15:02:29] <ʇsʎɯ> как вариант - хранить индекс дерева
[15:03:48] <f[x]> gds: of_channel тупо заменён на of_input
[15:06:31] <gds> m, если брать более классические деревья, то можно при поиске нужного индекса сохранять все поддеревья (отдельно правые, отдельно левые), в которые _не_ вошли, и, имея найденный лист, можно легко перейти влево-вправо без прохода по всему дереву.  зипперы вроде дают подобное.  зиппер при поиске строится, добавляя постоянный оверхед на каждый уровень дерева, лазить по нему можно быстро, а обновлять с его помощью никто и не заставляет.
[15:12:02] <ʇsʎɯ> да, зиппер так и работает
[15:12:25] <ʇsʎɯ> но это мне надо будет пробежать по дереву по дереву, а не a.(i-1) сделать
[15:12:44] <ʇsʎɯ> а если каким-то образом родить индекс вершин, то... нихера не будет
[15:12:52] <ʇsʎɯ> потому что его обновлять те же яйца
[15:13:05] <ʇsʎɯ> короче, ограничу 10mil очков и всё
[15:13:14] <ʇsʎɯ> а потом сделаю 2.0 на sqlite3
[15:13:18] <ʇsʎɯ> заодно и проверим ))
[15:13:30] <gds> 40Mb памяти чисто на массивчик?  жырненько.
[15:13:32] <ʇsʎɯ> под это дело я ещё и байндинги зафигачу
[15:13:50] <ʇsʎɯ> это мелочи по сравнению с примерно миллионом рекордов
[15:14:06] <ʇsʎɯ> а хотя...
[15:14:17] <ʇsʎɯ> ай, всё, что до 400-500 метров - нормально
[15:14:22] <ʇsʎɯ> на тачке 4гига
[15:14:34] <gds> а, покатит.
[15:14:46] <ʇsʎɯ> "When in doubt, use bruteforce" (c) Ken Thompson
[15:16:43] <ʇsʎɯ> массив 40метров + хотя бы млн рекордов (30 метров) = 70 метров
[15:16:48] <ʇsʎɯ> вполне нормально
[15:17:11] <ʇsʎɯ> главное, чтобы gc не тормозил на обходе всего этого добра
[15:17:16] <ʇsʎɯ> я же хз как он там работает
[15:22:05] <gds> как я понимаю, в массиве будешь хранить список людишек, имеющих нужное количество очков.  Пустые списки в массиве обрабатываются мусорщиком очень быстро.
[15:40:51] f[x] вышел(а) из комнаты
[15:44:14] f[x] вошёл(а) в комнату
[15:46:42] <gds> олег киселёв таки ответил насчёт поддержки revised syntax в pa_monad.  Логично, но печально.
==========
       I don't think we have even designed the perform notation for the revised syntax. To be sure, the bulk of pa_monad is syntax-independent (since they operate on AST). Still, there are parts that hook-up to the grammar for a particular concrete syntax. We don't have such hooks for the revised syntax. Mainly, we don't know how the perform notation should_properly_  look like in the revised syntax. By `properly' I mean respecting the spirit and overall design of the revised syntax.
       The main trouble is very few users of the revised syntax; one could hardly find any. It's hard to justify the effort to design a notation (this is the hardest part of extending pa_monad to the revised syntax) when hardly anyone would use it.
============
а значит -- от забора >>= fun othershit -> до обеда.
[15:59:19] <f[x]> открытие дня -
есть модуль, в нём функции возвращающие полиморфный вариант, ругается на contains type variables that are not generalized, причина понятна
прописывать полностью тип со всем параметрами лень
но! внезапно оказывается что можно просто аннотировать [`A|`B of 'a|`C of 'b] (не выписывая полностью параметры) и это работает т.к. типовыводилка унифицирует с аннотациями, а не точно следует им.
[16:02:16] <gds> в сигнатуре аннотируешь, а при компиляции структуры не ругается, я правильно понял?
[16:02:34] <f[x]> без сигнатуры, просто в теле модуля
[16:05:31] <gds> туплю.  почему ругается "contains .. not generalized"?
[16:12:19] digital_curse вышел(а) из комнаты
[16:13:29] <f[x]> потому что тип _[`A |`B .. |`C ..]
[16:15:47] <f[x]> module Q = struct let x = Hashtbl.create 2 let put y = Hashtbl.replace x y let f () = put 1 `A; print_endline "q"; put 1 `B end
[16:17:03] <f[x]> вообщем суть открытия в том что аннотации можно не выписывать до конца, а просто скучные места писать 'a
[16:18:33] <ʇsʎɯ> эм... а с кем ты сейчас разговаривал?
[16:22:49] <f[x]> ?
[16:22:57] <gds> агаа!  но надо сделать так, чтобы все использования аннотированного типа были описаны в нём же, т.е. типы [> `A], [> `B], [> ], [> `C] -- не канают.
[16:23:35] <f[x]> да
[16:24:05] <f[x]> т.е. в этом конкретном случае как раз надо было избваиться от этой implicit type variable в [>
[16:47:41] Kakadu вошёл(а) в комнату
[16:52:36] iNode вышел(а) из комнаты
[16:53:00] komar вышел(а) из комнаты
[16:55:17] iNode вошёл(а) в комнату
[17:09:51] Kakadu вышел(а) из комнаты
[17:18:13] iNode вышел(а) из комнаты
[17:31:27] gds вышел(а) из комнаты
[18:07:42] Kakadu вошёл(а) в комнату
[19:03:22] gds вошёл(а) в комнату
[19:27:23] ʇsʎɯ вышел(а) из комнаты
[20:00:39] serp256 вышел(а) из комнаты
[20:11:36] Kakadu вышел(а) из комнаты
[20:19:57] Kakadu вошёл(а) в комнату
[20:33:07] Typhon вышел(а) из комнаты
[20:48:35] vshender вошёл(а) в комнату
[20:57:56] Kakadu вышел(а) из комнаты
[21:06:57] Kakadu вошёл(а) в комнату
[21:35:40] Typhon вошёл(а) в комнату
[23:27:29] Kakadu вышел(а) из комнаты
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!