lapinou changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | http://www.ocaml.org | OCaml 4.01.0 announce at http://bit.ly/1851A3R | Public logs at http://tunes.org/~nef/logs/ocaml/
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
nikki93 has joined #ocaml
ollehar has quit [Ping timeout: 240 seconds]
ollehar has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
nikki93 has quit [Ping timeout: 240 seconds]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
zpe has joined #ocaml
zpe has quit [Ping timeout: 252 seconds]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
lostcuaz has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
nikki93 has quit [Ping timeout: 252 seconds]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
nikki93_ has joined #ocaml
nikki93 has quit [Ping timeout: 252 seconds]
nikki93_ has quit [Remote host closed the connection]
* whitequark sighs
<whitequark> how do I make ctypes give me the real address of a string character buffer?
<whitequark> IOW, String_val(str).
<whitequark> it seems very keen on not allowing that.
<whitequark> oh. no way.
* whitequark sighs again and forks ctypes.
Topher has left #ocaml []
zpe has joined #ocaml
zpe has quit [Ping timeout: 240 seconds]
q66 has quit [Quit: Leaving]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
nikki93 has quit [Ping timeout: 240 seconds]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
nikki93 has quit [Ping timeout: 258 seconds]
nikki93 has joined #ocaml
ollehar has quit [Ping timeout: 250 seconds]
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
arjunguha has joined #ocaml
clan has quit [Quit: clan]
nikki93 has quit [Ping timeout: 276 seconds]
nikki93 has joined #ocaml
clan has joined #ocaml
zpe has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
zpe has quit [Ping timeout: 240 seconds]
studybot has quit [Read error: Connection reset by peer]
nikki93 has quit [Read error: Connection reset by peer]
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
arjunguha has joined #ocaml
nikki93 has joined #ocaml
nikki93 has quit [Remote host closed the connection]
nikki93 has joined #ocaml
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
arjunguha has joined #ocaml
nikki93 has quit [Remote host closed the connection]
tidren has quit [Remote host closed the connection]
studybot has joined #ocaml
tidren has joined #ocaml
studybot has quit [Remote host closed the connection]
studybot has joined #ocaml
tidren has quit [Ping timeout: 245 seconds]
tlockney_away is now known as tlockney
tidren has joined #ocaml
clan has quit [Quit: clan]
clan has joined #ocaml
clan has quit [Quit: clan]
steshaw has quit [Quit: Leaving.]
yacks has quit [Quit: Leaving]
studybot has quit [Read error: Connection reset by peer]
ygrek has joined #ocaml
yacks has joined #ocaml
MisterGeppetto has joined #ocaml
lostcuaz has joined #ocaml
claudiuc_ has quit [Remote host closed the connection]
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
zpe has joined #ocaml
maattdd_ has quit [Ping timeout: 252 seconds]
zpe has quit [Ping timeout: 240 seconds]
tab1293 has joined #ocaml
<tab1293> If I have List.iter running a function on list items that in turn returns a list, how can I concatenate all the lists return with List.iter into one list?
arjunguha has joined #ocaml
<tautologico> seems like you want a flatmap / concatMap
<tautologico> if for every element in the list you generate a list, then maybe you should use map and not iter... then you can use concat on the result of the map
<tab1293> tautologico, okay I will look into map
<tab1293> I am new to ocaml so excuse my noobiness
axiles has joined #ocaml
<tautologico> no problem
arjunguha has quit [Client Quit]
<tautologico> map is very common in functional programming, it transforms a list (or another container) in another list by transforming each element
<tautologico> List.map (fun x -> x * x) [1; 2; 3; 4] will result in [1; 4; 9; 16]
<tautologico> squaring each element of the list
<tab1293> tautologico, okay that is exactly what I want then
<tab1293> thank you
<tab1293> tautologico want to look at some code? I am getting a type mismatch error but I can't figure out how to fix it
<tautologico> ok
<tautologico> where is it?
<tab1293> the last line calling the function is_rule_terminal is throwing the error shown at the bottom of the paste
<tautologico> first thing to try is to reload the whole code, it seems the interpreter is seeing different versions of the same types
<tautologico> as if you loaded some code then changed something and reloaded only part of it
<tautologico> it seems symbol_type/2169 and symbol_type/1800 are different types
<tab1293> I actually see a bug in the code, on line 38 that is_terminal should be is_symbol_terminal
<tab1293> idk if that will change anything but I'll try
<tab1293> seems to have got rid of that type error
<tautologico> ok
<tab1293> tautologico, any suggestions on my style? I am not really sure how ocaml code should look
<tautologico> it's ok I guess, one thing is that in files you'd generally not use the double semicolons to finish definitions
<tab1293> tautologico, okay I am a little confused as to when to use double semicolons vs single ones and where they are actually needed
<tautologico> they're always needed in the toplevel / interpreter / REPL (ocaml, utop, etc)
<wwilly> bonjour
<tautologico> you normally don't need them if you're writing a file to be read by the interpreter or compiled
<tautologico> bonjour
<tautologico> ça va?
<wwilly> fine
<wwilly> and you?
<tautologico> good
Kakadu has joined #ocaml
zpe has joined #ocaml
arjunguha has joined #ocaml
zpe has quit [Ping timeout: 252 seconds]
arjunguha has quit [Client Quit]
<tab1293> tautologico, if I have a list of tuples, is there anyway to have an if statement to check if the first member in each tuple of the list matches to something?
<tab1293> I tried doing this but it is not right: "List.mem (lhs, _ ) terminal_list "
<tab1293> where lhs is what I am trying to match to the first member of the tuple and the underscore meaning I dont care what the second member of the tuple is
Simn has joined #ocaml
lostcuaz has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
tlockney is now known as tlockney_away
yacks has quit [Ping timeout: 276 seconds]
MisterGeppetto has quit [Ping timeout: 245 seconds]
zpe has joined #ocaml
zpe has quit [Ping timeout: 258 seconds]
ggole has joined #ocaml
arjunguha has joined #ocaml
arjunguha has quit [Ping timeout: 240 seconds]
tane has joined #ocaml
tani has joined #ocaml
ggole has quit [Read error: Connection timed out]
ggole has joined #ocaml
tane has quit [Ping timeout: 258 seconds]
zpe has joined #ocaml
zpe has quit [Ping timeout: 252 seconds]
tab1293 has quit [Ping timeout: 245 seconds]
rand000 has joined #ocaml
nikki93 has joined #ocaml
elfring has joined #ocaml
<adrien> I doubt many are going to be interested (for the time being) but just to mention it, I've found a not too ugly way to find out whether a windows application is started from a graphical shell or from a cmd.exe prompt
<adrien> (basically, get ppid, use tasklist to check whether the intersection of processes with pid = ppid and image_name = cmd.exe, pipe to 'find "cmd.exe"' to get a usable return code)
yacks has joined #ocaml
nikki93 has quit [Remote host closed the connection]
<Drup> It's ugly.
<adrien> you're a carebear
<adrien> you're Perfect Panda
<adrien> (and your mate is Polite Panda)
<gasche> (today I learned: care bear)
<adrien> the above is clean in real world! :P
<gasche> ok so apparently they have names and adrien knows their names and character
<adrien> wikipedia has lists for everything ;-)
<gasche> no dude, you should totally check out carebears.wikia.com
<adrien> oh, on wikia? that's probably going to be epic :D
tautologico has quit [Quit: Connection closed for inactivity]
<gasche> on the other hand, Wikipedia has a Care Bear *category*
<gasche> and they removed the Alice ML article, not notable
<gasche> the world is a strange place
<adrien> hahaha
<adrien> not notable = no money has been used for marketing
<adrien> (I think rks is Funshine Bear btw)
<Drup> I know the term only because it's used in eve online to describe risk-adverse players :]
WraithM has quit [Ping timeout: 258 seconds]
<gasche> "America Cares Bear (2003) is a happy, patriotic, and energetic bear who believes that America's greatest strengths are caring, helping others, and teamwork."
<gasche> this is hilarious
<adrien> shouldn't he be Stakanov instead? :P
Snark has joined #ocaml
ikaros has joined #ocaml
zpe has joined #ocaml
yacks has quit [Ping timeout: 240 seconds]
zpe_ has joined #ocaml
zpe has quit [Read error: Connection reset by peer]
<ggole> Hmm, just realised that GADTs pose a serious code size problem for any compiler that implements polymorphism by specialisation :/
<ggole> You would get a number of specialisations linear in the size of the terms ever passed to the GADT... which is quite awful.
angerman has joined #ocaml
yacks has joined #ocaml
pminten has joined #ocaml
tobiasBora has joined #ocaml
<gasche> ggole: I don't follow
<gasche> (but I don't believe in monomorphization anyway)
ikaros has quit [Quit: Ex-Chat]
tidren has quit [Remote host closed the connection]
divyanshu has joined #ocaml
pminten has quit [Quit: Leaving]
maattdd_ has joined #ocaml
tobiasBora has quit [Quit: Konversation terminated!]
Thooms has joined #ocaml
<Kakadu> if we have pair. is (x=y) <=> ((fst x)=(fst y)) && ((snd x)=(snd y)) ?
<jpdeplaix> Kakadu: yes
* Kakadu is realising how silly this question sounds without a context
yacks has quit [Ping timeout: 240 seconds]
Submarine has joined #ocaml
<Kakadu> left: let cmp_t: t->t->bool = fun (a,b) (c,d) -> (a=c) && (b=d)
<Kakadu> right: let cmp_t: t->t->bool = fun (x:t) y -> (x=y)
bnwr has joined #ocaml
<Kakadu> My question should sound like 'Why compiler can't generate the same code for both examples?'
divyanshu has quit [Ping timeout: 245 seconds]
rta has quit [Ping timeout: 246 seconds]
divyanshu has joined #ocaml
araujo has quit [Quit: Leaving]
ollehar has joined #ocaml
<mrvn> Kakadu: because the second I believe simply uss the generic compare.
<mrvn> s/uss/uses
<Kakadu> Yes
<mrvn> The compiler doesn't monomorphise.
<mrvn> (except for a verry select set of core types)
<Kakadu> mrvn: So, it can do it theoretically but current implementation doesn't?
malc has joined #ocaml
<mrvn> sure
<mrvn> Kakadu: Note that for a more complex t, one that isn't 2 ints, the left side would c_call caml_equal twice.
<Kakadu> mrvn: in (a=c) && (b=d) ?
<mrvn> yes
tani has quit [Quit: Verlassend]
martintrojer has quit [Remote host closed the connection]
tidren has joined #ocaml
yacks has joined #ocaml
martintrojer has joined #ocaml
tidren has quit [Ping timeout: 252 seconds]
<ggole> gasche: specialisation (at least, naively) is one copy per type: functions over GADTs can produce many types.
<mrvn> and exponential with the number of arguments
<ggole> Say you have type _ term = | Int : int -> int term | Float : float -> float term | Pair : 'a term * 'b term -> ('a, 'b) term | Fst : ('a, 'b) term -> 'a term | Snd : ('a, 'b) term -> 'b term
<ggole> Imagine compiling a recursive eval function over this term: each call to eval would induce a new copy of eval, recursively
<ggole> So you would get a very serious code explosion
<mrvn> ggole: why? normal recursion doesn't either.
<gasche> I'm not sure I see the difference between ('a term -> 'a) and just ('a -> 'a) in term of specializations that have to be performed
<mrvn> ggole: The recusion would just call the already generated specialized function
<ggole> No it wouldn't, the type would be different
<mrvn> It would be _term in both cases
<ggole> If you wrote eval over that term, you would have a case like, say, | Pair (a, b) -> (eval a, eval b)
tobiasBora has joined #ocaml
<ggole> And the return type of eval would be different for each call.
<gasche> there is the well-known problem that polymorphic recursion can lead to arbitrary many ground instances used during execution
<ggole> Which is *not* true of non-GADT types.
<ggole> Thus the difficulty.
<mrvn> ggole: if you recursively specialize the type then you get one function for every used type. Same with or with gadt.
<gasche> recursion over GADTs is often polymorphic, but we had polymorphic recursion before GADTs
<gasche> consider
<gasche> type 'a full_tree = Tree of 'a | Succ of ('a * 'a) full_tree
<ggole> mrvn: if you don't have a GADT, then each eval has the same type
<mrvn> ggole: no.
<ggole> You just have a simple mapping term -> value which is the same everywhere
<gasche> let rec length : 'a . 'a full_tree -> int = function Tree _ -> 1 | Succ t -> 1 + length t
malc has quit [Quit: leaving]
<mrvn> ggole: let cmp x y = Pervasives.compare x y. Specialize that for int, float, char, unit, int list, float list, char list, unit list, int array, float array, ....
<ggole> gasche: presumably polymorphic recursion suffers the same problem
<gasche> I think what you find problematic with GADTs is precisely polymorphic recursion
<ggole> You may be right.
<mrvn> ggole: specialize i for int * (float * (char * (int array * (float array * ( ....)))))
<ggole> mrvn: how is that problematic?
<mrvn> ggole: The (polymorphic) recursion just means that a single call will go through many different types.
<ggole> You produce it once, done.
<mrvn> ggole: The problem is that every single type creates a new function.
martintrojer has quit [Quit: ZNC - http://znc.in]
<ggole> That's fine. That's simply the program you would have written by hand if you didn't have a polymorphic comparison.
<mrvn> ggole: the same happens with GADT
<mrvn> one function per type
martintrojer has joined #ocaml
<ggole> Yes, and how many types does a GADT function have?
<ggole> A large family!
<mrvn> ggole: as many as a non GADT function
<mrvn> any polymorphic type can be as complex and deep as you want.
<gasche> let id n = let rec loop : 'a . 'a tree -> int -> int = fun t -> function 0 -> length t | n -> loop (Succ t) (n - 1) in loop (Tree ()) n
<gasche> calling (id n) will make n recursive calls with n different type instantiations
<gasche> (or (id @@ read_int ()) for more fun and profit)
<ggole> mrvn: unlike normal variants, GADT types "grow" in the size of terms
<ggole> Consider the difference in size between Int 1 and Pair (Int 1, Int 2) (using the definition I mentioned above)
<gasche> any sane person will understand that polymorphic recursion belongs to the etheral world of platonic ideas that The Ultimate Language Will Eventually Support, and that absolute specialization must either go away or be performed in a JIT fashion
<ggole> I don't think this is fatal to specialisation: it's a stumbling block though
ygrek has quit [Ping timeout: 245 seconds]
<mrvn> ggole: irelevant. A non GADT Pair (Int 1, Int 2) has the same size.
<ggole> mrvn: the *type* of that non-GADT pair is the same
<ggole> Int 1 : non_gadt_term
<ggole> Pair (Int 1, Int 2) : non_gadt_term
<ggole> etc, etc
<ggole> Same type, same specialisation
<gasche> ggole: it meant you cannot monorphize completely at compile-time
<gasche> monomorphization is not very interesting anyway, in the grand scheme of things
<mrvn> ggole: with and without gadt you end up with foo_(int,int)pair and foo_int.
<ggole> gasche: I think it can be repaired by "megamorphisation" of GADTs (ugh)
<gasche> the programming language debate in the next 20 years is the question of whether we'll prove the programs we write correct with respect to a specification
<ggole> With a little bridge between polymorphic-recursive code and flat monomorphic values
<ggole> But that's a huge hack :(
<gasche> feel free to spend your mental energy on improving the constant factors in some minor use-cases
<bernardofpc> gasche: like openssl ?
<gasche> (ok, I'm trolling a bit here, use cases are not necessarily minor)
<bernardofpc> (or, more realistically, the linux kernel / glibc / gcc which form the base of all our software stack)
<gasche> I'm just too bitter about the state of system design and security these days
<ggole> Great, lets make our safe languages nice and slow so everybody uses them.
<mrvn> the openssl desaster would have been avoided by the simplest security considerations.
<gasche> ggole: like Ruby on Rails
<mrvn> Like zeroing out memory that holds private keys before freeing them.
<gasche> yet for some reason nobody cared and used that software, and today is the right time to look shocked
shinnya has quit [Ping timeout: 245 seconds]
<ggole> There are programmers for whom performance is not a concern: I don't think you can reasonably assume that they will be the ones writing the OpenSSLs of the future
darkf_ has joined #ocaml
<gasche> I don't care if people write critical code in C, as long as I don't have to use their software
<gasche> besides, there are performance-competitive dialects of C (C-cured, Cyclone, and to some respect ATS) that can be used instead for partial correctness (memory safety)
<gasche> that's not as good as matching a specification, but already several orders of magnitude better than what we have (that is, dozens of buffer overflow attack in each LWN security bulletin)
<gasche> and maybe in twenty years people will have provided usable tools to prove C programs correct, instead of using a saner language as a basis
darkf has quit [Ping timeout: 258 seconds]
shinnya has joined #ocaml
<mrvn> ggole: FYI there is a paper where they reimplemented ssh and a few other things in ocaml and guess what: It was faster than openssh.
<gasche> (C is the only language for which we have a provably-correct compiler)
<mrvn> ggole: and who uses that?
<mrvn> gasche: ^^
<ggole> On the other hand, interest in these dialects of C is even more marginal than interest in languages like OCaml
<ggole> Which is sad
<ggole> Maybe this heartbleed thing will motivate a few people to look at them more seriously: we'll see.
<ousado> you're calling ATS a C dialect?
<gasche> "to some respect"
<gasche> by which I mean that it's possible to mimick C code in ATS; that looks like ugly C with a grotesque ML syntax, but nevertheless
<ousado> :D
<ggole> You can provide C-callable code by writing ATS, which is also interesting
<bernardofpc> gasche> I don't care if people write critical code in C, as long as I don't have to use their software -> you're writing your OS in which language ?
<ousado> yes, it's awesome. I don't understand why taste and beauty matter all of a sudden, when something solves/is about to solve real issues
darkf_ is now known as darkf
<Kakadu> mrvn: > FYI there is a paper where they reimplemented ssh
<Kakadu> mrvn: Who are they and what should I write in google?
<NoNNaN> how can I write critical code in ocaml? Is there any wcet (worst case execution tool) available? or other tool that map specification->code->executable code
<ousado> Kakadu: https://github.com/avsm/ocaml-ssh maybe?
<mrvn> Kakadu: can't remember. I tried to find it again recently and also failed.
<mrvn> ousado: isn't that just bindings for normal ssh?
<mrvn> NoNNaN: you press one key after the other.
<NoNNaN> Kakadu: it's comes from melange (Melange: Towards a "functional" Internet): http://anil.recoil.org/papers/2007-eurosys-melange.pdf
<ousado> hm, it says SSHv2 library, client and server implementation in OCaml
<Kakadu> thanks
<ousado> it looks like there's an actual implementation there
q66 has joined #ocaml
tidren has joined #ocaml
<mrvn> NoNNaN: Great. Time to move that into my own paper collection so I can find it again.,
tidren has quit [Ping timeout: 276 seconds]
ollehar has quit [Ping timeout: 258 seconds]
divyanshu has quit [Quit: Textual IRC Client: www.textualapp.com]
q66 has quit [Ping timeout: 252 seconds]
<NoNNaN> Kakadu: using a "safe" language is just a start, the next topic the (real world) provable security properties in all layer is a "bit" harder (eg.: http://realworldcrypto.files.wordpress.com/2013/06/stebila.pdf )
q66 has joined #ocaml
q66 has quit [Changing host]
q66 has joined #ocaml
<companion_cube> is ocaml-tls ready for production? :)
pminten has joined #ocaml
<adrien> what is it?
<companion_cube> TODO: bits and pieces from useful extensions (heartbeat)
<companion_cube> hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
<companion_cube> no ready, it is
<mrvn> hey, at least ocaml-tls didn't have the security bug then.
<adrien> heh
<adrien> but for the ssl stuff, I don't think there is a need to write the crypto in a language safer than C
<mrvn> adrien: yes there is
<adrien> well, at least that it's not the most pressing need
<adrien> for heartbleed, no crypto was involved
<adrien> it's parsing of data from untrusted sources
<NoNNaN> adrien: and than what is the most pressing need?
tidren has joined #ocaml
<mrvn> adrien: there are no trusted sources in crypto
<companion_cube> adrien: I think there is
<companion_cube> C makes it far too easy to shoot yourself
<adrien> byte buffer is byte buffer
<companion_cube> bound checking is bound checking
<companion_cube> malloc overlay is another issue
<adrien> and for something like SHA3, I haven't heard yet about a broken implementation
<mrvn> adrien: a secrity tuned language should naturally never ever put network data and private keys into the same memory region.
<NoNNaN> adrien: mitls has a verfieied referenc implementation, for start
steshaw has joined #ocaml
<mrvn> adrien: and a good language would have detected the uninitialized memory in the openssl bug.
<companion_cube> buffer overflows shouldn't happen at all in languages like OCaml
<mrvn> companion_cube: the openssl bug wasn't a buffer overflow
<adrien> in a sense it was
<companion_cube> it was a bound checking problem, definitely
<mrvn> adrien: no. If you request 64k it allocates 64k. It just never initializes them.
<NoNNaN> companion_cube: and can you prove it it will not happen?
<adrien> and in practice, the security issues are rarely in the crypto itself but in the protocol handling
<companion_cube> NoNNaN: there could be a bug in the runtime, indeed
<companion_cube> but that's far less likely than an error in a specific piece of code
<adrien> and that part doesn't require to get very close to the metal to get the best performance
<companion_cube> because the runtime is really used a lot
<mrvn> adrien: exactly: anil.recoil.org/papers/2007-eurosys-melange.pdf
<Drup> gasche: about the whole "C is terrible, let's use a better language" > I have hopes that rust is going to be that.
<adrien> (plus with stuff like AES-NI, you have even less to do yourself in some cryptos)
<companion_cube> me too
<mrvn> adrien: That is why they should be rewritten in e.g. ocaml with something like MPL.
<NoNNaN> adrien: this is why I mentioned the next step, proving the security properties
<companion_cube> rust has so many good decision choices...
tidren has quit [Ping timeout: 258 seconds]
<companion_cube> but then of course, it's also necessary to have model checking or even some verification of crucial parts
<Drup> gasche: do you have the paper/implementation for the ssh implementation in ocaml ?
<adrien> companion_cube: egg is good, sugar is good, doesn't make sugar+egg good :D
<companion_cube> is would if egg and sugar were orthogonal!
<companion_cube> it*
<mrvn> Drup: scroll a few lines up
<adrien> hmmm, fancy proving that? :P
<adrien> bah, too much lag; bbl
<NoNNaN> companion_cube: the whole crypto protocol is critical, one "mistake" makes it unusable
<mrvn> The biggest hole in crypto protocols exists between keyboard and chair.
<companion_cube> NoNNaN: indeed
<companion_cube> but my point is that if the language works against you, it's much more likely that at least one mistake will be present
<companion_cube> (of course I'd *love* a crypto library extracted from coq)
<ggole> Actually OCaml could easily leak info, what with String.create returning uninitialised memory
<companion_cube> (that would make a good research team actually, like compCert)
<mrvn> ggole: or unsafe_get. Don't use them. add compiler flags to error on them.
<mrvn> ggole: unless you (the compiler) can proof correctness.
<companion_cube> grep (unsafe
<companion_cube> |Obj)
<mrvn> companion_cube: get calls unsafe_get
<companion_cube> ah, you need to trust the compiler indeed
<ggole> Mmm, best to avoid unless there's a pressing need (and there almost never is)
<companion_cube> but as I said, the runtime/compiler are very thoroughly used pieces of code
<companion_cube> unlike, a priori, a specific path in one application
<ggole> The stdlib is full of unsafe_{get,set}
<ggole> But that's probably trustworthy enough
<companion_cube> things like Array.blit, sure
<companion_cube> but there's bound checking before
<ggole> Particularly since the operations are pretty simple
<mrvn> and you can verify correctness.
<ggole> The question is what happens when you screw up the bounds checking :)
<NoNNaN> companion_cube: there is a do178b certified ocaml (subset) compiler/runtime, Experience Report: Using Objective Caml to Develop Safety-Critical Embedded Tools in a Certification Framework
<companion_cube> ggole: you could use why3 ;)
<companion_cube> NoNNaN: interesting! which subset does it cover?
<ggole> There are some reasonable algorithms, like array partition/remove_if, that don't admit simple bounds checks
<ggole> But you can write them correctly quite easily by stating a clear loop invariant.
<companion_cube> they still admit bound checking whether you access elements of the array or not
<ggole> unsafe_get is probably OK in those circumstances
<ggole> (Although I'd leave it off unless I had a good reason.)
<mrvn> bounds check usualy is a runtime check though. so 2 years after deployment you get an exception.
<ggole> An exception is annoying, but acceptable. Undefined behaviour is not.
<mrvn> But one can use GADTs to check bounds at compile time. e.g. in a divide and conquer over an array.
<ggole> ...he says, running an IRC client running on a window system running on an OS, all written in C
<NoNNaN> companion_cube: "The main risk resided in the problems that could have been met to show the traceability between the different levels of specifications and the binary resulting from the compilation of a highly functional and polymorphic source code."
<mrvn> That makes using _unsafe safe then.
<companion_cube> mrvn: better have an exception than info leaking for 2 years
<mrvn> companion_cube: better to know the exception can't happen
<ggole> I'd actually like a -safe so that I could turn all bounds checking on, unconditionally
<companion_cube> mrvn: even better, for sure
<companion_cube> but if heardbleed had triggered exceptions/segfaults instead of leaking, we'd have found it earlier
<mrvn> companion_cube: it wouldn't. it wasn't a buffer overflow.
<mrvn> It was a String.create kind of problem.
<ggole> Info leaks are often quite subtle problems
<companion_cube> remind me, String.create does take a char?
<ggole> You can easily leak info via side channels in a totally safe language.
<companion_cube> oh, it doesn't
<ggole> No, Array.create takes an element
<companion_cube> I always use String.make
<ggole> You'd have to get a bit sophisticated to elide the initialisation safely
maattdd_ has quit [Read error: Connection reset by peer]
<ggole> Doing it for scalars or entire objects is easy
<NoNNaN> more or later due the constant security problems / bugs in software certification will become a requirement (it firms may be unwilling to install uncertified products, use of uncertified software may invalidate certain insurance coverages, etc)
<companion_cube> currently there is so little legal responsibility for releasing bugs
<companion_cube> (which is a good thing for open source)
<mrvn> NoNNaN: is there insurance against security exploits?
<companion_cube> let's just hope verification tools become easy enough to use that people do use them for critical software
<NoNNaN> companion_cube: not neceassary legal, but an economic incentive
<companion_cube> I don't believe in economic incentives that much
<companion_cube> most people don't understand those issues or don't care about privacy
<ggole> They understand the price tag though
<NoNNaN> companion_cube: eg.: something like this: http://pub.stefanbucur.eu/taas-2010.pdf
<mrvn> companion_cube: It's the only thing that works
<ggole> And the current marginal price of software is approximately zero
<ggole> Makes it hard to justify a large expenditure on verification measures that your competition may be skipping
<mrvn> companion_cube: e.g. online banking is only safe enough that the bank doesn't have to pay when accounts get hacked.
<companion_cube> mrvn: banks just augment their fee and that's it
<companion_cube> it's so opaque anyway
ollehar has joined #ocaml
elfring has quit [Quit: Konversation terminated!]
<mrvn> Anyone know of a module that implements an unmovable array? I need to access the array from C with the ocaml runtime lock released so the GC must not move it.
<companion_cube> I think bigarray are not movable
<mrvn> but only support integer types.
<mrvn> Specifically I need an array of bigarrays.
<ggole> Could you allocate the array from the C side?
<mrvn> ggole: if I write the relevant stubs.
<ggole> Right, nice not to have to do that.
<mrvn> I want a (Bigarray.t, Bigarray.bigarray_elt, Bigarray.c_layout) Bigarray.Array1.t
<whitequark> Bigarray.Array2.t ?
<mrvn> whitequark: That is a continious chunk of memory with 2 dimensional indexing.
<companion_cube> does the major collection also move eleemnts?
<companion_cube> hmm, compaction does, I guess
<whitequark> mrvn: oh.
<adrien> of a bigarray? no
<mrvn> compaction moves the bigarray but not the chunk of memory the bigarray points to for its elements.
elfring has joined #ocaml
tidren has joined #ocaml
tidren has quit [Ping timeout: 252 seconds]
avsm has joined #ocaml
avsm has quit [Ping timeout: 276 seconds]
jao has joined #ocaml
jao has quit [Changing host]
jao has joined #ocaml
elfring has quit [Quit: Konversation terminated!]
darkf has quit [Quit: Leaving]
elfring has joined #ocaml
jao has quit [Ping timeout: 240 seconds]
ygrek has joined #ocaml
tidren has joined #ocaml
tidren has quit [Ping timeout: 276 seconds]
pminten has quit [Quit: Leaving]
Hannibal_Smith has joined #ocaml
steshaw has quit [Quit: Leaving.]
q66 has quit [Ping timeout: 252 seconds]
q66 has joined #ocaml
jonludlam has joined #ocaml
tidren has joined #ocaml
martintrojer has quit [Quit: ZNC - http://znc.in]
tidren has quit [Ping timeout: 250 seconds]
martintrojer has joined #ocaml
malc_ has joined #ocaml
martintrojer has quit [Client Quit]
martintrojer has joined #ocaml
arjunguha has joined #ocaml
maattdd has joined #ocaml
studybot has joined #ocaml
studybot has quit [Remote host closed the connection]
studybot has joined #ocaml
MisterGeppetto has joined #ocaml
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
arjunguha has joined #ocaml
studybot has quit [Read error: Connection reset by peer]
studybot_ has joined #ocaml
maattdd has quit [Ping timeout: 245 seconds]
studybot_ has quit [Remote host closed the connection]
studybot has joined #ocaml
jonludlam has quit [Ping timeout: 252 seconds]
shinnya has quit [Ping timeout: 245 seconds]
tidren has joined #ocaml
tidren has quit [Ping timeout: 240 seconds]
elfring has quit [Quit: Konversation terminated!]
avsm has joined #ocaml
zpe_ has quit [Remote host closed the connection]
zpe has joined #ocaml
tane has joined #ocaml
lostcuaz has joined #ocaml
zpe has quit [Ping timeout: 252 seconds]
tidren has joined #ocaml
ollehar has quit [Ping timeout: 245 seconds]
lostcuaz has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Thooms has quit [Quit: WeeChat 0.3.8]
zpe has joined #ocaml
tlockney_away is now known as tlockney
pminten has joined #ocaml
zpe has quit [Ping timeout: 245 seconds]
WraithM has joined #ocaml
maattdd has joined #ocaml
testcocoon has quit [Quit: Coyote finally caught me]
Thooms has joined #ocaml
testcocoon has joined #ocaml
pminten has quit [Quit: Leaving]
tlockney is now known as tlockney_away
zpe has joined #ocaml
MisterGeppetto has quit [Ping timeout: 245 seconds]
<ygrek> gasche, why don't you believe in monomorphisation?
<ygrek> that sounds like a natural approach to leverage the maximum of type information known statically to compiler
<ygrek> that should probably be bounded to some degree - but there are lots of locally contained places where it could help a lot
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<ygrek> and global too but that's much more complex I suppose
zpe has quit [Ping timeout: 258 seconds]
ollehar has joined #ocaml
lostcuaz has joined #ocaml
<mrvn> ygrek: make them weak symbols and export them and you got global.
<mrvn> I think monomorphization should be controled by the source. You specify the amount of types that should be spezialised.
<mrvn> One question though is wether that should be extensible. E.g. module only specialises for int and you want float too. Can you add that?
nikki93 has joined #ocaml
<gasche> ygrek: I think the idea of making polymorphism go away is dumb
<mrvn> gasche: nobody wants it to go away.
<gasche> that said, restricted form of monomorphization in some circumstances sure make sense
<gasche> but I think people have been avoiding the good questions on that
<gasche> (such that "what part of the type information do I actually care about for this information?")
<gasche> mrvn: that's what, say, MLton people do, and they're reasonably happy with this choice as SML lacks polymorphic recursion
<mrvn> Look for eaxmple at Pervasives.compare. It is monomorphized for [unit | bool | char | int | 'a] (maybe some more).
<gasche> specialized
<mrvn> You want spezialized code for the basic types where it makes a difference and generic code for the humongous amount of types where it makes no difference.
<def-lkb> is this only for the sake of performance?
<mrvn> def-lkb: yes
<ggole> Mixing specialised and non-specialised code isn't so easy, though
<ggole> Calling conventions and data layouts make assumptions over where things are placed that need to be consistent over the entire program
<ggole> You can't just change part of it without regard to the rest
<mrvn> ggole: they are in ocaml
araujo has joined #ocaml
<ggole> Because OCaml does almost no specialisation
<mrvn> ggole: neither the calling conventions nor the data layout gets changed if you spezialize functions.
<mrvn> It just takes advantage of a known layout instead of having to handle any layout.
<ggole> Most of the *point* of specialisation is to change calling conventions and data layout
<ygrek> I am confused - monomorphization <> specialization?
<ygrek> or the one is more general?
<ggole> Monomorphic just means "single typed" - specialisation means making some (hopefully profitable) change in response to some fact (such as the knowledge that something is monomorphic).
<ggole> You can also do things like specialise a function for a constant argument, though.
zpe has joined #ocaml
<NoNNaN> and also important if you have monomorphic functions, and you work on bulk structures (eg.: array) you could also improve the performance with vectorization/simd
<mrvn> I would be happy already if passing (=) to a function that works on ints would not produce c_calls.
nikki93 has quit [Remote host closed the connection]
<flux> but appetite grows while eating ;)
<flux> (translated from Finnish, I suppose that's not an English phrase?)
Hannibal_Smith has quit [Quit: Sto andando via]
malc_ has quit [Quit: leaving]
<NoNNaN> flux: well, there is a "Law Of Diminishing Marginal Utility"
<mrvn> and only if the food is any good
<mrvn> (don't try this on my cooking)
elfring has joined #ocaml
tobiasBora has quit [Ping timeout: 240 seconds]
<whitequark> Error: This pattern matches values of type 'a Static.ptr
<whitequark> but a pattern was expected which matches values of type
<whitequark> ex#16 Static.typ
<ggole> I tried that with goat curry and rice earlier: it was just filling
<whitequark> why does this happen?
<ggole> Those are strange GADT-related type variables iirc
<whitequark> well, yes
<whitequark> oooooh, ptr/typ
<whitequark> nevermind
<nickmeha1ry> Hi all, I've been tinkering with the idea of a game engine in OCaml, but I can't get the component model to work.
<nickmeha1ry> http://pastebin.com/kZXk41w6 Here's my current sketch.
* ggole mumbles something about "GADTs" and "another hapless victim"
nickmeha1ry is now known as nickmeharry
maattdd has quit [Ping timeout: 252 seconds]
<whitequark> ggole: now combine that with ctypes and debugging libffi in gdb
<whitequark> I'm starting to question my sanity
<gasche> 19:50 < mrvn> I would be happy already if passing (=) to a function that works on ints would not produce c_calls.
<Drup> nickmeharry: have you looked at the blog about building a game engine in ocaml ?
<gasche> go help review Pierre's branch
<gasche> and your dreams might come true in a next OCaml version
<nickmeharry> Probably. Haven't looked at it again in a month or two.
<nickmeharry> IIRC the engine didn't actually exist, just hypotheticals.
<gasche> (currently I think Pierre doesn't actually run type-specialization after inlining but it's rather high on his TODO-list)
<Drup> afaik, it's just not open source
TerranceWarrior has joined #ocaml
<Drup> and there is a good amount of code examples in order to show how it encode the entity model
<nickmeharry> Ok, I'll look for it again.
zpe has quit [Ping timeout: 245 seconds]
<nickmeharry> I feel like there has to be a way to encode this without requiring typecasts (as the C++ examples use).
<nickmeharry> Drup: You're taking about this one, right? http://cranialburnout.blogspot.ca/2013/09/programming-game-in-ocaml.html
<Drup> the blog in general, yes
nikki93 has joined #ocaml
<mrvn> gasche: closures aren't inlined. That is the problem there.
<mrvn> nickmeharry: what is your problem specifically?
<nickmeharry> mrvn: From the code sample, I don't know how to express an Actor.t having multiple components, while still allowing components to read each other's data.
marks has quit [Quit: leaving]
<nickmeharry> In the example, PhysicsComponent needs LocationComponent's data.
<nickmeharry> It seems like the problem is related to needing to specify the dependency, but I couldn't figure out how to do that.
<nickmeharry> I tried adding in polymorphic variants as a tagging system, but I'm not sure that helped.
maattdd has joined #ocaml
<Drup> can't you just use functors ?
<mrvn> nickmeharry: you already pass the actor as argument. Now the actor needs a method to lookp the physics component
arjunguha has joined #ocaml
<mrvn> aeh LocationComponent I mean
<mrvn> nickmeharry: I would make the physics component extend (and replace) the location component.
<nickmeharry> mrvn: Right, but if all it knows about it's component list is that they're all COMPONENT module types, then it can't get the right component at runtime.
<Drup> that's just because you restrict the type too much
<nickmeharry> But if I didn't, wouldn't the list be hetergenous (which the type system disallows)
<nickmeharry> ?
<mrvn> nickmeharry: you have 2 problems: 1) components must be declared in the order of dependencies. No loops alowed unless you do recursive modules.
<nickmeharry> I'm ok with my components requirements forming a DAG.
<mrvn> 2) the list of components isn't an universal container. So you can't lookup a component and use that components specific interface.
<nickmeharry> #2 is the part I've been stuck on.
zpe has joined #ocaml
<nickmeharry> I'm going back over the blog Drup mentioned and trying to figure out how he did it.
<gasche> 20:28 < mrvn> gasche: closures aren't inlined. That is the problem there.
<mrvn> nickmeharry: You can use a GADT to make an universal container. That way the physics component can request the (or list of) location component and get a LocationComponent type back.
<gasche> as I said: go help review Pierre's branch
<mrvn> gasche: sounded like Pierre's branch was about spezialisation, not inlining.
<nickmeharry> mrvn: Ok. I've not familiar with those. Time for some more reading.
<Drup> Pierre's branch is about inlining, which is needed for specialisation
ygrek has quit [Ping timeout: 245 seconds]
<gasche> mrvn: go review his branch?
<mrvn> nickmeharry: let me look for an example
<gasche> you'll have a better idea of what's inside
<Drup> gasche: regardless of code review, is the branch in an usable state ?
<gasche> yes, but why would you ask?
<Drup> to test it.
<gasche> feel free to
<gasche> so that it motivates you to review it
<Drup> (I don't mind a link to the ticket too)
maattdd has quit [Ping timeout: 276 seconds]
<Drup> no ticket on mantis for the merge, no mail asking for review ?
<gasche> Pierre hasn't requested a merge yet, because review is still pending
<Drup> I mean, no shit there is nobody doing review if the only way to know about this branch is by having pierre in the next office.
<gasche> (... and until recently he was hunting some tricky bugs)
<gasche> I think Pierre talked about it in blog posts as well
<Drup> yes, a few month ago, by saying the work was still on going
<Drup> on going as it "not ready for review"
<gasche> well the work is still ongoing
<gasche> but there is a review branch with a part of it
<Drup> no mention on the review branch and no ask for review on the last blog entry
<Drup> and it was july 2013
<Drup> I mean, I'm very happy that it progressed, but don't rant that people don't review something that is invisible
<Drup> and yes, from my end, it sounded like ranting.
<gasche> I'll admit the reason I recommend people to go review it here is not merely to get more reviews (which *is* useful), but rather to offer an alternative to improductive whining about the current compiler's optimization capabilities
* ggole looks guilty
<gasche> ggole: to be fair, most optimizations *you* talk about (memory representation) are not remotely concerned
<gasche> inlining and specialization certainly are
<ggole> It's true: it's also true that I talk a lot and contribute nothing.
<gasche> Drup: so when I suggest that people review the branch
<gasche> I'm not saying they knew about it and should have done it before (which would presuppose better communication on Pierre's part)
<gasche> only reacting to the current discussion
arjunguha has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
tane has quit [Quit: Verlassend]
zpe has quit [Ping timeout: 276 seconds]
clan has joined #ocaml
<nickmeharry> Thanks. Reading it over now.
<nickmeharry> Interesting. Might be a bit before I fully grok it, but that looks like what I needed.
<mrvn> nickmeharry: The trick is that "get" will return a type dependent on the kind you search.
Snark has quit [Quit: leaving]
<mrvn> nickmeharry: the rest is basically just: type comp = Location of location | Physics of Physics type comp_list = comp list
<nickmeharry> So the only real downside I see here is that 1) the components must be listed twice and 2) all in the same place.
<nickmeharry> I think I can live with that, since the actual data types and functions can live elsewhere.
<mrvn> nickmeharry: yes
<nickmeharry> mrvn: Thank you so much.
<mrvn> nickmeharry: you could use let comps = [`Physics phys; `Location loc; ...] if you want independent and extensible.
<nickmeharry> That's the box in your example? Does that extend to kind as well?
<mrvn> nickmeharry: no. kind and box go hand in hand. The kind is a witness type. The box is the container.
<mrvn> nickmeharry: by matching the kind against the box I make the ocaml type checker see what the type inside is and return that type directly.
<mrvn> nickmeharry: "type a . a kind -> ulist -> a"
<mrvn> nickmeharry: the "match (kind, box) with" looks like a normal match but in this case is matches against the type of kind.
<nickmeharry> mrvn: Ok. More reading to do to see how that works. In the type declaration of kind the parameter is ignored, but you're doing what looks like a "for all" match on it.
* whitequark exhales
<mrvn> nickmeharry: I would probably go with `Physics phys if you've never used GADTs.
<whitequark> this took an entirely inordinate amount of effort.
<mrvn> nickmeharry: just makes it a bit more to type to lookup a component
<whitequark> seven hours of nonstop screwing with ctypes -_-"
<nickmeharry> mrvn: I think I'll just start here and play around with it until I get a feel for what works and what doesn't.
<nickmeharry> mrvn: Again, thank you so much.
<mrvn> nickmeharry: np. Had to wait for my potatoes to boil
zpe has joined #ocaml
<gasche> I don't know whether mrvn is actually german, but boiled potatoes suit the German cliché just right
igitoor has quit [Ping timeout: 246 seconds]
igitoor has joined #ocaml
zpe has quit [Ping timeout: 276 seconds]
igitoor has quit [Changing host]
igitoor has joined #ocaml
tobiasBora has joined #ocaml
maattdd has joined #ocaml
maattdd has quit [Ping timeout: 245 seconds]
Thooms has quit [Quit: WeeChat 0.3.8]
arjunguha has joined #ocaml
zpe has joined #ocaml
arjunguha has quit [Client Quit]
axiles has quit [Remote host closed the connection]
tidren has quit [Remote host closed the connection]
ggole has quit []
bobry has joined #ocaml
maattdd has joined #ocaml
<bobry> I wonder what is the status of ocamldoc? Is there an official maintainer? The code looks abandoned..
<Drup> bobry: what makes you say it's abandoned ?
zpe has quit [Ping timeout: 250 seconds]
<bobry> Drup: reading the code, very unreadable most of it
<Drup> that's not abandoned, just bad :p
<Drup> people are working on a replacement, anyway
<bobry> well, I'm assuming that if there's a maintainer it's their responsibility to make the code better (constantly)
<bobry> you mean the new opam-doc thing?
<Drup> yes
<gasche> Maxence Guesdon is still the maintainer of ocamldoc
<bobry> does it make sense to send patches which improve readability of the code?
maattdd has quit [Ping timeout: 245 seconds]
<Drup> since opam doc is going to replace it, not sure
<bobry> if there's opam-doc, which I guess will replace ocamldoc eventually
<gasche> readability patches are a mixed bunch
<gasche> there is a risk of introducing a regression when you include them
<gasche> so they should either be obviously correct, or have other good arguments in their favor than just "readability"
<bobry> makes sense
<gasche> one thing I'm much in favor of is "explaining patches" that comment on subtle parts of the code
<bobry> actually, I was just trying to improve the error messages, generated by ocamldoc, but the code is really hard to follow..
<gasche> there is someone working on ocamldoc error message locations, are you the same person?
<bobry> yup
<bobry> as for "explaining patches", obviously the original author can do this with significantly less efort
<gasche> hm
<gasche> (1) they don't remember themselves more often than not (that's the problem with not commenting your code) (2) they feel like they've more interesting things to do
<gasche> it's nice if the original author does it
<gasche> but if that doesn't happen, and you yourself spend time making sense of a bunch of code, taking a bit of time to summarize your newfound understanding in form of a comment is worth it
<bobry> yeah, I agree
<Drup> afaik, ocamldoc code has been ugly for a long time
<gasche> I do agree that ocamldoc is one of the less pleasant part of the compiler
<Drup> it's not going to change
<gasche> ocamlbuild's code is not easy to get your head around, but it's doing something interesting in a thought-over way
<adrien> obviously you haven't seen the build system :D
<gasche> the bad thing about ocamldoc is that part of it are hacks
<penryu> I have a toy module (Lazy_list) in $PWD/lazy_list.ml; I'd like to use it interactively in a utop session; what build products and/or command line options are required for this?
<gasche> I think they made sense to cut corners and get something that works relatively well
<bobry> anyway, the original question was: should I invest my time in ocamldoc or I should better switch to opam-doc?
<gasche> penryu: #mod_use "lazy_list.ml";;
<Drup> adrien : the implicit next part of the sentence is "if someone else that the other try to do it"
<Drup> the author*
TerranceWarrior has quit [Quit: leaving]
<adrien> ah :)
* adrien thinks he'll toss a coin for his question on the ML
<penryu> gasche: success! thanks!
<gasche> bobry: opam-doc looks nice, shiny and with a better long-term design than ocamldoc
<gasche> but it hasn't been released yet, and I don't know what the timeline is
zpe has joined #ocaml
<gasche> meanwhile, ocamldoc has users whose life you *can* make a tiny bit better by improving error reporting
<gasche> I'd say it's worth it -- if the cost is not *too* high
<gasche> I haven't looked too closely at your last pull request
<bobry> okay, this sounds convincing, I think I'll give ocamldoc it a try :)
elfring has quit [Quit: Konversation terminated!]
<gasche> I think I remember that you already had something useful, but that people asked for the next thing in the comments
<bobry> yup, location information for warnings
<gasche> having a complete change is nice, but if you feel like you've done enough, say it clearly and what's there may be integrable already
<gasche> (I haven't looked too closely as you seemed motivated to come up with something even better)
tobiasBora has quit [Quit: Konversation terminated!]
tlockney_away is now known as tlockney
Submarine has quit [Quit: Leaving]
wwilly has quit [Quit: This computer has gone to sleep]
Arsenik has joined #ocaml
dant3 has quit [Quit: I'm using a Free IRC Bouncer from BNC4FREE - http://bnc4free.com/]
maattdd has joined #ocaml
maattdd has quit [Ping timeout: 245 seconds]
Arsenik has quit [Remote host closed the connection]
avsm has quit [Quit: Leaving.]
arjunguha has joined #ocaml
steshaw has joined #ocaml
Kakadu has quit [Quit: Konversation terminated!]
arjunguha has quit [Quit: Textual IRC Client: www.textualapp.com]
Simn has quit [Quit: Leaving]
divyanshu has joined #ocaml
rand000 has quit [Quit: leaving]
maattdd has joined #ocaml
nikki93 has quit [Remote host closed the connection]
maattdd has quit [Ping timeout: 240 seconds]
tnguyen has joined #ocaml
Topher has joined #ocaml
steshaw has quit [Quit: Leaving.]
tlockney is now known as tlockney_away
bobry has quit [Quit: Connection closed for inactivity]
zpe has quit [Remote host closed the connection]
zpe has joined #ocaml
zpe has quit [Ping timeout: 240 seconds]
nikki93 has joined #ocaml
divyanshu has quit [Quit: Computer has gone to sleep.]
maattdd has joined #ocaml
madroach has quit [Ping timeout: 252 seconds]
madroach has joined #ocaml
angerman has quit [Quit: Bye]
maattdd has quit [Ping timeout: 258 seconds]
NoNNaN has quit [Remote host closed the connection]
NoNNaN has joined #ocaml
darkf has joined #ocaml
lostcuaz has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]