Home
Objective Caml
ocaml@conference.jabber.ru
Вторник, 16 марта 2010< ^ >
f[x] установил(а) тему: Камль -- http://caml.inria.fr | Логи -- http://chatlogs.jabber.ru/ocaml@conference.jabber.ru/ | Верблюды грязи не боятся! | release crap | voice по запросу | ocaml мёртв, move on
Конфигурация комнаты
Участники комнаты

GMT+3
[00:09:05] <Typhon> недавно думал, что было бы круто, если б компилятор проверял не только типы выражений, но и исключения, которые бросаются/ловятся. а вчера полез в логи конфы и наткнулся на ocamlexc -- как раз то, о чем думал :) (для тех кто не в курсе про: http://pauillac.inria.fr/caml/ocamlexc/ocamlexc.htm)
[00:11:30] Kakadu вышел(а) из комнаты
[00:12:25] <ygrek> Typhon: напильник в комплекте прилагается?
[00:13:13] <Typhon> это же опенсорц -- нужно принести свой :)
[00:13:41] <ygrek> верно
[00:18:29] <Typhon> "Then, if you need, install the OCamlTk library..." -- "if" там на самом деле лишнее :)
[00:19:46] olegfink вышел(а) из комнаты
[00:19:47] olegfink вошёл(а) в комнату
[00:37:25] ermine вышел(а) из комнаты
[00:41:58] valexey вышел(а) из комнаты
[01:04:59] digital_curse вышел(а) из комнаты
[01:11:44] ygrek вышел(а) из комнаты
[03:07:58] Typhon вышел(а) из комнаты
[03:51:45] daapp вошёл(а) в комнату
[06:58:14] digital_curse вошёл(а) в комнату
[08:08:18] gds вышел(а) из комнаты
[08:54:54] gds вошёл(а) в комнату
[09:44:39] sceptic вышел(а) из комнаты
[09:52:39] Typhon вошёл(а) в комнату
[10:04:44] ygrek вошёл(а) в комнату
[10:06:59] serp256 вошёл(а) в комнату
[10:57:57] gds вышел(а) из комнаты
[10:58:43] gds вошёл(а) в комнату
[11:10:57] valexey_ вошёл(а) в комнату
[11:19:36] f[x] вошёл(а) в комнату
[11:42:10] digital_curse вышел(а) из комнаты
[11:52:32] ermine вошёл(а) в комнату
[12:31:33] ostahandland вошёл(а) в комнату
[13:08:11] ygrek вышел(а) из комнаты
[13:39:13] daapp вышел(а) из комнаты
[14:08:57] Typhon вышел(а) из комнаты
[14:09:10] Typhon вошёл(а) в комнату
[14:45:48] shoroh-net вошёл(а) в комнату
[14:52:32] shoroh-net вышел(а) из комнаты
[15:23:26] <f[x]> http://repo.or.cz/w/dormin.git
[15:23:33] <valexey_> "Появляется ощущение, что надо рекурсивно вызывать функцию оптимизации, подавая выход на вход, пока разница не станет меньше некоей дельты, так как каждый шаг оптимизации порождает артефакты, которые вырезаются процедурой оптимизации."
[15:23:57] <valexey_> f[x]: это что такое?
[15:47:38] <valexey_> о-о! какой я шикарный баг нашел в F#!
[15:47:54] <valexey_> проявляется по кр. мере в интерпретаторе.
[15:49:26] <valexey_> ref -- похоже не является зарезервированным словом. посему:
let ref a = 10;;
[15:49:27] <valexey_> и всё хорошо.
[15:50:13] <valexey_> только вот потом:
let i = ref 10;; -- даст совсем не тот результат ;-)
[15:50:35] <valexey_> какой ожидаем ;-)
[15:50:37] <valexey_> или это в камле тоже такая же ошибка?
[15:50:48] <gds> это не ошибка, это области видимости.
[15:51:12] <valexey_> ref должно быть зарезервированным словом. нет?
[15:51:38] <valexey_> почему вот например не прокатывает:
let in b = 12;; ?
[15:52:03] <valexey_> let open hh = 44;; (* тоже не прокатывает *)
[15:52:27] <valexey_> let type c = 42;; тоже
[15:52:40] <valexey_> а вот let ref b = 10;; прокатывает.
[15:52:48] <valexey_> явная ошибка.
[15:54:03] <gds> разная степень зарезервированности :)  ref'ы добавлены не в сам язык, а реализованы средствами языка (плюс синтаксический сахар для get/set).
[15:54:53] <valexey_> гыгы. ужоз
[15:56:24] <valexey_> где-то в стандартной либе объявлены, что импортируется по умолчанию... как бишь её тут зовут то.. забыл. короче аналог Prelude.
[15:57:08] <gds> да, Pervasives.
[15:57:23] <gds> в случаях ненависти -- Perversives.
[15:58:23] <valexey_> Ж-)
[16:00:14] Typhon вышел(а) из комнаты
[16:00:35] <valexey_> в общем я всё понял. перенаправляю лучи ненависти на хабрахабр.
[16:01:25] <valexey_> тамошние умельцы ref в исходнике выделили как ключевое слово.
[16:01:40] <valexey_> да ещё и обозвали его ключевым:
"Для этого всего лишь надо поставить ключевое слово ref перед вычислениями"
[16:01:57] <valexey_> НЕНАВИСТЬ!!!
[16:06:31] <gds> да, в окамловских мануалах (смотрел на Introduction/The core language и The Objective Caml language/Expressions) не указывают, ключевое слово это или нет.  В первом тексте просто вызывают как функцию, во втором вообще не указывают (указан только синтаксис для get/set).
[16:08:10] <valexey_> дас, с документированностью языка у камла большие проблемы.
[16:09:48] <valexey_> но вообще оный ref должен присутствовать в описании Pervasives
[16:10:47] <valexey_> о! есть.
[16:11:00] <valexey_> type 'a ref = {
    mutable contents : 'a;
}
The type of references (mutable indirection cells) containing a value of type 'a.
val ref : 'a -> 'a ref
[16:15:36] <gds> какие такие проблемы?  Если не указывают, что это не ключевое слово, значит это не ключевое слово, чо тут думать.
[16:42:41] <valexey_> хм. а ссылок в камле нету? ведь этот ref по сути эквивалентен чему-то типа:
template <typename T> struct Ref {T content;};
[16:50:30] <gds> вот именно тому и эквивалентен (более того, mutable contents : 'a и всё тут).  А что, не хватает?
[16:50:51] <valexey_> ну, в С++ оно сразу mutable :-)
[16:52:24] <valexey_> ну-у... вот всякие хитрые структуры данных ваять можно тут только через рекурсивные типы данных, или же можно старыми добрыми императивными средствами? ну, скажем зобразить по старинке односвязный список.
[16:53:18] <gds> односвязный список, например, в самом описании типа будет содержать рекурсию.  А так-то -- конечно, можно и императивно его.
[16:54:36] <valexey_> а как? без ссылок то.
[16:55:55] <gds> type 'a mutlist = { opt_head : mutable 'a option ; tail : mutable 'a mutlist }
('a option в бошке -- чтобы уж совсем императивно)
[16:56:38] <gds> тьфуты, ('a mutlist) option в хвосте.
[16:57:07] <valexey_> эмм.. а добавление нового элемента в голову тут случаем не будет ли приводить к копированию всего хвоста?
[16:57:25] <gds> не будет.  Хотя смотря как накодить, можно и так, чтобы приводило :)
[16:57:42] <gds> ну а далее --
let new_cell () = { opt_head = None; tail = None }
let c1 = new_cell () and c2 = new_cell ()
c1.opt_head := Some 1
c1.tail := Some c2
c2.opt_head := Some 2
[16:59:26] <valexey_> пардон, а как тут без копирования?
[17:00:34] <gds> все три операции присвоения напрямую меняют изменяемые поля значений c1 и c2 соответственно.
[17:01:51] <gds> например, в "c1.tail := Some c2" указатель на c2 сначала заворачивается в option (в выделенный блок памяти, содержащий один указатель -- тот, который нам нужен), а затем адрес этого option'а помещается в ячейку памяти c1[1] (второе поле структуры).
[17:01:57] <gds> конечно, что-то копируется, но не хвост.
[17:04:04] <f[x]> дожились, обучение присваиванию
[17:04:08] <f[x]> расскажи ещё что такое указатель
[17:04:11] <f[x]> и сегфолт
[17:05:09] <gds> Obj!1111
[17:05:31] <gds> не, ну иногда императивно гораздо прямее получается :)
[17:06:14] <f[x]> я не спорю
[17:07:10] <f[x]> просто предлагаю сразу дать ссылку на учебник паскаля
[17:07:19] <valexey_> option, как я понимаю, это нечто вроде Maybe в хаскеле?
[17:09:48] <gds> человек испорчен хаскелем.  Надо показать, что нормальная здоровая императивщина -- тоже бывает, и этого не надо стесняться и стыдиться.  Понятно, что многие говорят, что они ни разу в жизни не присваивали ничего, но соц.опросы показывают лишь ничтожную долю таких людей.  Конечно, среди женщин таких людей больше.
[17:10:01] <gds> 'a option -- да, None | Some of 'a
[17:10:39] <valexey_> спокойно. я испорчен ещё и С++. А хаскель это был шаг в функциональщину. Теперь надо перекинуть мостик ;-)
[17:12:38] <valexey_> gds я знаю что на прямую меняют значение полей. на то они и mutable. также я думаю что типы по большей части в окамле ссылочные на самом деле (кроме примитивных типов).
[17:13:22] <valexey_> но я думал что когда мы делаем присваивание, то у нас будет таки создана копия.
[17:14:27] <valexey_> копия не ссылки, а содержимого.
[17:14:36] <valexey_> соответственно адресочки что лежат в ссылках будут таки различаться.
[17:14:38] <valexey_> нет?
[17:16:36] <gds> во многих случаях идут ссылки, но даже user-defined типы могут быть не ссылочными (например, type my = A | B -- будет A==A и B==B всегда, т.е. физическое равенство).
Копию содержимого делают руками, если надо.  По умолчанию -- максимальный data sharing.
[17:18:34] <valexey_> ну, перечисляемый тип очевидно хорошо отображается на примитивный тип.
[17:18:35] <valexey_> на какой-нибудь int
[17:18:53] <gds> именно.
[17:18:58] <valexey_> ведь никого не шокирует что это так в Си :-)
[17:19:16] <valexey_> и а паскале, и в Аде и в Обероне, и много где ещё.
[17:21:11] <gds> это да.  Так если бы содержимое копировалось, то окамл был бы очень плохим императивным языком.
[17:28:36] gds вышел(а) из комнаты
[17:29:37] <valexey_> о, таки да. сумел сцепить два ref'а
[17:29:48] <valexey_> меняешь потроха одного, меняются потроха и другого.
[17:30:30] <valexey_> как интересно.. прям ява какая-то.
[17:30:48] <valexey_> различие семантики для примитивных и ссылочных типов при присваивании.
[17:35:18] <valexey_> гм. как интересно типы съехали.
[17:36:25] <valexey_> а, нет. это я ушами прохлопал.
[17:54:23] <valexey_> как интересно. содержимое не переменных переменных может таки меняться, хотя и косвенно.
[17:56:41] valexey_ понял что mutable переменные лучше не закапывать куда-то глубоко.
[17:56:49] <valexey_> а то потом сюрприз может случиться. внезапно.
[17:59:00] Typhon вошёл(а) в комнату
[18:09:53] <valexey_> гм. а как сделать глубокое копирование?
[18:12:05] gds вошёл(а) в комнату
[18:14:20] <gds> > содержимое не переменных переменных может таки меняться, хотя и косвенно
да, это так.  Поэтому мутабельность -- только по нужде, и, если можно, с функциональным интерфейсом.
глубокое копирование -- зависит от деталей.  Всегда сработает копирование руками, в некоторых случаях сработает копирование через сериализацию с последующей десериализацией.
[18:15:07] <valexey_> а сериализация как делается?
[18:15:27] <valexey_> вопрос звучит нубски, но мало ли, вдруг в языке есть что-то для автоматической сериализации произвольных структур данных
[18:15:39] <valexey_> т.е. тех которые ничего не знали о оной сериализации на момент создания
[18:16:23] <gds> http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html
[18:16:37] Typhon вышел(а) из комнаты: Replaced by new connection
[18:16:39] <gds> плюс {input,output}_value из Pervasives.
[18:16:40] Typhon вошёл(а) в комнату
[18:17:01] <valexey_> ага. спасибо.
[18:17:45] <gds> но с сериализацией есть явные ограничения, и иногда это вдобавок ко всему не гибко бывает.
[18:18:02] <valexey_> гм. например?
[18:20:25] <gds> сишные штуки не всегда сериализуются, функциональные значения -- только между программами с одинаковым бинарником (другие ограничения -- см. доку на Marshal), негибкость -- из-за того, что некоторые вещи иногда и не надо копировать вовсе, а лучше оставить расшаренными.
[18:21:10] <valexey_> ну, это то понятно.
[18:21:58] <gds> а, ну ещё классическое ограничение на строку -- на 32битных платформах сериализованное значение не может превышать 16Мб.
[18:22:30] olegfink вышел(а) из комнаты
[18:22:30] olegfink вошёл(а) в комнату
[18:22:32] <valexey_> а инфиксным оператором может быть только функция состоящая из спецсимволов? или же можно как-то также как в хаскеле: a `plus` b
[18:23:34] <valexey_> гм. а откуда именно 16 мегабайт для 32бит взялось?
[18:23:59] gds вышел(а) из комнаты: Replaced by new connection
[18:24:00] gds вошёл(а) в комнату
[18:24:51] <valexey_> 16 мегабайт это вроде как 24 бита.
[18:24:58] <valexey_> 8 бит остальных куда дели? ;-)
[18:25:12] <gds> 16Мб -- из-за кодирования строк в рантайме.
[18:25:43] <valexey_> эмм... не понял.
[18:26:29] <gds> при принятом кодировании в заголовке не хватило бит на более длинные строки.
[18:26:36] <valexey_> там какое-то хитромудрое представление строк?
[18:27:35] <gds> да, длина пишется в заголовке вместе с другими битовыми флагами.
[18:27:58] <valexey_> а заголовок усиленно хочется поместить в одно машинное слово?
[18:28:03] <gds> инфиксные операторы -- http://gdsfh.dyndns.org/kamlo/InfixOperators
[18:28:16] <gds> заголовок -- да.
[18:29:35] <gds> более того, хочется ещё интересные свойства строк получить, поэтому выбрали кодирование извращённое, но эффективное.
[18:31:08] <valexey_> ну, это всё операторы из спец. символов. я имел ввиде следующее:
let >+< a b = a+b;;
10 >+< b;; (* тут всё ок *)
let plus a b = a+b;;
10 plus 10;; (* естественно не правильно. можно ли сделать правильно? но не plus 10 10 *)
[18:31:28] <valexey_> ой. в первой строчке конечно же let (>+<) a b = a+b;;
[18:31:47] <gds> ну можно 10 /* plus */ 10
[18:32:32] <valexey_> ха.
[18:32:36] <valexey_> а в f# не работает.
[18:33:28] <valexey_>   10 /* boo */ 10;;
  ---^^
stdin(87,4): error FS0043: Method or object constructor 'op_DivideMultiply' not
found
[18:33:47] <Typhon> valexey_, по ссылке ходил? :)
[18:33:52] <Typhon> let ( /* ) x y = y x
let ( */ ) x y = x y
[18:34:42] <valexey_> а оно в Pervasives?
[18:34:50] <valexey_> похоже что таки нет.
[18:34:52] <gds> да, ссылку я давал не просто так.
[18:36:24] <valexey_> но вообще, смотрится жутко. думаешь при чем тут коментарий? ;-)
[18:38:24] <gds> инфиксные операторы усложняют понимание кода (в моём случае), поэтому мне для полутора раз использования /* */ было не сложно его воспринимать.
[18:40:24] <valexey_> "Эта вики содержит материалы, касающиеся языка программирования OCaml. А именно, всё, что по формату не влезает в наш гламурный чятик "
[18:40:26] <valexey_> жжоте!
[18:40:47] <Typhon> valexey_, ну а ты лого то заценил, а? это вам не >>= с сиськами всякие! ^_^
[18:41:29] <valexey_> :-)
[18:41:32] <valexey_> дас. жжость!
[18:47:01] <valexey_> интересно, а как работает printf в камле? Это ж вроде некий аналог сишного притнтфа.
[18:47:02] valexey_ полез в хелп искать сигнатуру printf
[18:48:14] <gds> кстати, про строки -- http://caml.inria.fr/pub/ml-archives/caml-list/2002/08/e109df224ff0150b302033e2002dbf87.en.html
[18:48:18] <gds> printf хитри
[18:48:47] valexey_ что-то пока ничего не понял с принтфом
[18:51:04] <valexey_> а printf он ведь в батарейках, да?
[18:51:22] <Typhon> valexey_, нет
[18:51:31] <Typhon> Printf модуль
[18:52:00] <valexey_> хм. а чего ж я его в батарейках нашел?
[18:52:01] <valexey_> http://batteries.forge.ocamlcore.org/doc.preview:batteries-beta1/html/api/Printf.html
[18:52:07] <valexey_> val printf : ('a, 'b Extlib.InnerIO.output, unit) t -> 'a
[18:53:07] <Typhon> valexey_, ну потому что искал там, искал бы тут: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html, нашел бы иное
[18:53:27] <valexey_> искал в гугле
[18:54:07] <valexey_> откровенно говоря легче не стало ;-)
[18:57:41] <valexey_> printf "%d" имеет тип int->unit, printf "%s" имеет тип string->unit
[18:58:05] ostahandland вышел(а) из комнаты
[18:58:06] <valexey_> нифига не понимаю. тут закрадываются шальные мысли о зависимых типах
[18:58:58] <valexey_> или о рантаймном неявном инстанцировании каких-то параметризуемых модулей.
[19:00:01] <Typhon> или о магии ^_^
[19:00:54] <valexey_> магией является всё, что мы не знаем и не представляем как делается :-)
[19:09:49] <valexey_> "Type format6 is built in."
[19:09:52] <valexey_> упс. приехали
[19:10:40] <gds> а вот printf уже сделан с серьёзной поддержкой со стороны языка, это тебе не ref :)
[19:14:29] <gds> если есть желание, можно посмотреть в ocamlsources/stdlib/print.ml, там разбирают значение типа format6 в функции kapr.
[19:14:34] <olegfink> причем она достаточно мощная, я знаю аж одно применение format6, не связанное с форматированным i/o
[19:14:55] <Typhon> olegfink, какое? :)
[19:14:56] <gds> интересно, какое?
[19:16:32] <f[x]> dlopen
[19:17:02] <valexey_> а что, больше шести аргументов в результате printf не примет?
[19:17:03] <olegfink> угу
[19:17:11] <valexey_> или эта шестерка не связана с числом параметров?
[19:17:15] <f[x]> valexey_: открой наконец топлевел
[19:17:30] <valexey_> у меня топлевел только f# тут имеется.
[19:17:35] <valexey_> и там всё хорошо.я проверил
[19:17:40] <olegfink> в dlopen оно применяется для указания типа функции в рантайме, во внутрях же оно просто разбирает format6 как строку
[19:17:56] <f[x]> ну и отлично, нафига увеличивать энтропию вопросами которые проверяются за две секунды
[19:18:27] <valexey_> ну, это ж фшарп, фиг знает что они там наворотили.
[19:18:47] <f[x]> ну тогда открой топлевел камля
[19:18:53] <valexey_> тут нету
[19:18:59] <olegfink> поставь?
[19:18:59] <f[x]> это твои проблемы
[19:19:22] <f[x]> хинт - этот чат - не топлевел
[19:20:02] <valexey_> f[x]: printf " %s %d %s %d %s %d %s %d %s %d %s %d %s %d"
[19:20:14] <valexey_> ну вот. завис.
[19:21:29] <olegfink> f[x] тоже не топлевел
[19:21:56] <olegfink> а вообще ты ;; в конце выражений писать не пробовал?
[19:22:11] <valexey_> о! точно! периодически таки забываю.
[19:22:17] <valexey_> f[x]: ;;
[19:24:47] <olegfink> самая забавная часть магии, по-моему, в том, что у format_of_string тип format6 -> format6
[19:29:16] <valexey_> гм. кстати, а насколько магична эта магия? т.е. строка должна ли быть известна на этапе компиляции, или же её можно подсосать скажем из сети в рантайме?
[19:29:27] <valexey_> предположим что мы компилим в нативный код.
[19:30:28] <Typhon> valexey_, опять же, попробуй :) let make_printf tmpl = Printf.printf tmpl ;;
[19:30:54] <olegfink> очевидно, что если ты хочешь, чтобы был тайпчекинг, то тип (== format string) должен быть известен во время компиляции
[19:31:23] <valexey_> очевидно, да.
[19:31:30] <valexey_> Typhon: это просто создаст синоним.
[19:31:36] <valexey_> для принтфа
[19:31:57] <olegfink> сама функция форматированного ввода-вывода, естественно, к этой магии никакого отношения не имеет и прекрасно будет работать (если дашь правильное количество аргументов правильного типа) и со сгенеренной в
[19:31:59] <olegfink> рантайме форматной строкой
[19:32:00] <Typhon> да, я плохой пример сгенерил
[19:33:43] f[x] вышел(а) из комнаты
[19:48:46] sceptic вошёл(а) в комнату
[20:06:38] serp256 вышел(а) из комнаты
[20:33:42] valexey_ вышел(а) из комнаты
[20:52:21] digital_curse вошёл(а) в комнату
[21:23:12] valexey вошёл(а) в комнату
[22:05:10] gds вышел(а) из комнаты: Replaced by new connection
[22:05:12] gds вошёл(а) в комнату
[22:07:45] gds вышел(а) из комнаты: Replaced by new connection
[22:07:46] gds вошёл(а) в комнату
[22:10:17] gds вышел(а) из комнаты
[22:44:28] abiogenesis вошёл(а) в комнату
[22:45:31] abiogenesis вышел(а) из комнаты
[23:37:46] ygrek вошёл(а) в комнату
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!