Yurik changed the topic of #ocaml to: http://icfpcontest.cse.ogi.edu/ -- OCaml wins | http://www.ocaml.org/ | http://caml.inria.fr/oreilly-book/ | http://icfp2002.cs.brown.edu/ | SWIG now supports OCaml| Early releases of OCamlBDB and OCamlGettext are available
palomer has joined #ocaml
<ionOS> palomer: did you try the google archive?
<palomer> of lablgtk?
<palomer> yhe
<palomer> a
<palomer> google cache has nothing
<palomer> neither does wayback machine
Kinners has joined #ocaml
Kinners has left #ocaml []
palomer has quit [Remote closed the connection]
Kinners has joined #ocaml
docelic is now known as docelic|sleepo
mattam_ has quit [Read error: 110 (Connection timed out)]
Kinners has left #ocaml []
palomer has joined #ocaml
<palomer> anyone with any experience with lablgtk?
<palomer> actually, no need
<palomer> I have a program, that opens GMain, then defines a let main () = ...
<palomer> what I don't understand is why Main.main is used
lament has quit ["Did you know that God's name is ERIS, and that He is a girl?"]
polin8 has quit [Remote closed the connection]
<palomer> I don't understand polymorphic variants!
polin8 has joined #ocaml
<palomer> wee this is fun
skylan has quit [Read error: 60 (Operation timed out)]
skylan has joined #ocaml
palomer has quit [Remote closed the connection]
ionOS has quit [Read error: 110 (Connection timed out)]
palomer has joined #ocaml
mattam has joined #ocaml
lament has joined #ocaml
lament has quit ["Did you know that God's name is ERIS, and that He is a girl?"]
xtrm has joined #ocaml
systems has joined #ocaml
systems has left #ocaml []
docelic|sleepo is now known as docelic
skylan has quit [Read error: 104 (Connection reset by peer)]
skylan has joined #ocaml
gene9 has joined #ocaml
mellum has quit [Read error: 110 (Connection timed out)]
mellum has joined #ocaml
gene9 has quit [Read error: 104 (Connection reset by peer)]
cm has left #ocaml []
cm has joined #ocaml
skylan has quit [Read error: 104 (Connection reset by peer)]
skylan has joined #ocaml
docelic is now known as docelic|away
pk5 has left #ocaml []
<palomer> is message passing left associative or right associative?
<palomer> omigosh ocaml is the biggest language, ever
<Riastradh> That's a silly thing to say.
<Riastradh> How do you measure a language's size?
<Krystof> weight of specification :-)
<smkl> ocaml has a lot of features, but it's still not very complex
<vegai> palomer: ever heard of java or c++? =)
<smkl> a#b#c = (a#b)#c
<vegai> ok, java (the language) isn't that big, actually
<smkl> err
* emu drops the Java API on vegai's foot
<smkl> a#(b#c) wouldn't make any sense
<vegai> emu: AUCH
<vegai> bye foot
* Riastradh drops the C++ standard on vegai's foot, too.
<emu> geez, that was just too mean
<vegai> Riastradh: look what you did. You broke the floor
<Riastradh> Whoops, I meant to drop it on palomer's foot.
* Riastradh apologises for the damage and buys a new floor...and, after looking through the hole down at other angry channels, about four more floors.
<emu> now you've infected the place
<Riastradh> No, it dropped through too fast to have infected anything.
<Riastradh> I hope it hits the head of someone in #c++.
<palomer> back
<palomer> are methods cascaded?
<palomer> does a#b#c mean pass b to a with argument c?
<palomer> c++ is complicated because of the little details
<Riastradh> palomer - a#b#c <=> (a#b)#c
<palomer> what does that mean???
<Riastradh> It means apply the method c to the object returned by a#b.
<palomer> ahh
<palomer> gotcha
<palomer> also, if I have an object a, with a mutable field, and I compile a, can I change the field?
<Riastradh> And you 'compile' a?
<palomer> well I compile the module in which a resides
<palomer> and I link it against something else
<palomer> are values still mutable even after compilation?
* emu would hope so
<emu> not values
<emu> fields
<palomer> err yhea, fields
<emu> 1 := 2
<emu> muhaha
<Riastradh> Aiee.
<emu> let + = *
<palomer> so they are? so if i do ocamlc -c test.ml and test.ml has a let foo = object val mutable a;; and I link it to something that does foo.a <- 4
<palomer> however will it affect previous bindings?
<palomer> redefining functions only affects bindings declared thereafter, if my understanding is correct
<vegai> can anyone suggest other (perhaps better?) tutorials than the ones found below ocaml.org?
<palomer> the oreilly book is good, though imcomplete
<emu> mutation is different
<palomer> s/imcomplete/incomplete
<palomer> so mutation is akin to references
<palomer> all bindings declared before the value was mutated also change, correct?
<emu> if you can see foo, then changes to foo.a will be seen
<palomer> ahh, gotcha
<palomer> even if foo is in a compiled module?
<emu> i couldn't tell you for sure, but i would be awfully surprised
<emu> if compiling it changed the bheavior
<palomer> also, why do records types have to be named+
<palomer> ?
<emu> what do you mean
<palomer> type r = { x : int ; y : int }
<palomer> why do we have to give that record a name?
<palomer> is it when we want to explicitally type a function?
<palomer> and does it have other uses?
<emu> well
<emu> somehow it's got to know that x and y are from the same record
<palomer> type = { x : int ; y : int} would serve all my purposes
<emu> more difficult to debug that i imagine
<palomer> sotit's for debugging purposes...
<palomer> also, why can't two records share a field name?
<emu> does ocaml allow reuse of field names in different records?
<emu> nm
* palomer is confused about all these restrictions
<emu> probably to allow type inference
<emu> if you create a record {x=1} it needs to know which that is
<palomer> why can't it do the same as values, which is take the most general type?
<palomer> ie make the function polymorphic
<palomer> so that it can be applied to both record types
<emu> later on you may add the field y
<emu> or z
<emu> or something
<palomer> you can add fields to types?
<palomer> whoa
<emu> um
<emu> i only specified x in the above
<emu> but y is also defined
<emu> but say a type r' had z too
<palomer> r has x y z and r' has z...
<palomer> go on!
<emu> type r = {x:int;y:int} ;; type r' = {x:int;y:int;z:int};;
<emu> all values should be decidable
<emu> {x=1} is a value
<palomer> yhea, so when you do let x = { x = 1 ; y = 3 } it knows its type r
<palomer> since all values have to be decidable
<palomer> on the other hand if you add z it's type r'
<emu> i don't think you have to specify a value for al lfields
<emu> which makes {x=1} ambiguous
<emu> or {x=1;y=2}
<palomer> you don't?
<palomer> you have to specify all fields
<emu> then i'm thinking of something else
<palomer> Some record field labels are undefined: y
<emu> well
<emu> consider
<emu> type r = {x:int};; type r' = {x:int};;
<emu> what is {x=1};;?
<emu> presuming the allowance of such definitions
<palomer> you would have to put a restriction two records must differ in atleast one field
<palomer> which seems more reasonable to me than saying that none have the same field name
<palomer> I mean, what if you have a huge project
<mrvn> emu: r' shadows r
* palomer gives mrvn a high five
<palomer> maybe you can explain it mrvn
<emu> mrvn: we're making an assumption
<palomer> why do record fields have to be unique?
<palomer> w.r.t the closure
<mrvn> type foo = { x:int; } creates a binding for x telling ocaml that its part of a foo record.
<palomer> ahhh
<palomer> but why did they do it that way? doesn't that seem way too restrictive?
<mrvn> if ocaml sees bla.x it sees x as record lable and knows bla must be a foo.
<palomer> so it infers the type of bla
<emu> i'm thinking it should be able to deduce the type of bla from other sources
<mrvn> With type a = { x:int; y:int; } and b = { x:int;} bla.y is an a but bla.x could be a or b.
<emu> but maybe not
<emu> i havent workedi to ut
<palomer> good point
<mrvn> If b wouldn't shadow a ocaml couldn't say what type bla.x has.
<palomer> but he does have a point, if two records have the same type how can we infer the type of bla
<palomer> does it really matter what type bla is?
<palomer> couldn't we say bla is of type { r union r' } ?
<mrvn> palomer: because b={b:int;} shaodows the old x. There is no more a.x record label anymore.
<mrvn> b={x:int} I mean
<palomer> yes, because of the system in which it is implemented
<emu> palomer: that opens the door for unsafe code
<mrvn> palomer: records are not classes.
<palomer> and why are record types named?
<mrvn> palomer: a={y:int; x:int} then a.x is at &a+8, b={x:int} then b.x is at &b+4
<mrvn> So you can't build a union.
<emu> yikes, keep out implementation details
<palomer> couldn't we have chosen another implementation?
<mrvn> palomer: Thats much slower and you have that with classes.
<palomer> ahh, so records are kinda like speedy classes
<mrvn> records are like structs in C. Just a bunch of data.
<palomer> last thing before I go eat
<emu> except they share a namespace
<palomer> what are polymorphic variants?
<mrvn> emu: No, they share the current namespace.
<mrvn> palomer: `X
<palomer> what are they good for?
<palomer> is it that they belong to many different union types?
<palomer> yikes, food time...
<palomer> brb
<emu> i havent the time nor motivation, but there should be an explanation for the way record types are in terms of the type system...
<mrvn> As an example take a boardgame. The board has empty squares, blocked squares and two Players X and O.
<mrvn> You can write a function that can take a player `X or `O as argument and a function that takes a board piece `X `O `Empty or `Blocked.
<mrvn> With the polymorphic variants you can easily go from a player to a board piece because a player is a subset of what a boardpiece can be.
<palomer> erm
<palomer> back
<mrvn> Did the example help?
<palomer> just had a long argument with my mom on the definition of derivative on the set of matrices
<palomer> lemme think
<palomer> how would you write the function?
<mrvn> function `X -> print_char 'x' | `O -> print_char 'o'
<mrvn> ocaml
<mrvn> ups
<palomer> so that function can take type of player or piece?
<palomer> so basically polymorphic types are what I'm arguing records should be
xtrm has quit ["leaving"]
<mrvn> # let print_player = function `X -> print_char 'x' | `O -> print_char 'o';;
<mrvn> val print_player : [< `O | `X] -> unit = <fun>
<mrvn> # let print_board = function `X -> print_char 'x' | `O -> print_char 'o' | `E -> print_char ' ' | `B -> print_char '#';;
<mrvn> val print_board : [< `B | `E | `O | `X] -> unit = <fun>
<mrvn> # let me = `X;;
<mrvn> val me : [> `X] = `X
<mrvn> # print_player me;;
<mrvn> x- : unit = ()
<mrvn> # print_board me;;
<mrvn> x- : unit = ()
<palomer> X is not defined as a variant!
<palomer> is that the major dinstinction? no need to declare it in a sum type?
<mrvn> You can but you don#t have too.
<mrvn> # type player = [`O | `X];;
<mrvn> type player = [ `O | `X]
<palomer> whats the < mean?
<mrvn> # let print_player = function (`X : player) -> print_char 'x' | `O -> print_char 'o';;
<mrvn> val print_player : player -> unit = <fun>
<palomer> why would you ever want to use non polymorphic variants?
<mrvn> palomer: [< `O | `X] means that it can be `X | `O (a player) or anything less.
<mrvn> Like [> `X]
<mrvn> polymorphic variants just have to be subsets to be valid arguments to a function.
<palomer> they're a million times more flexible than normal variants!
<palomer> what's the tradeoff?
<mrvn> polymorphic variants use hashes to match. That can be faster or slower than normal variants.
<palomer> so it's speed
<mrvn> # let print_player = function `X -> print_char 'x' | `O -> print_char 'o' | _ -> assert false;;
<mrvn> val print_player : [> `O | `X] -> unit = <fun>
<mrvn> # print_player `FOO;;
<mrvn> Exception: Assert_failure ("", 79, 91).
<mrvn> Also the type can be pretty loose.
<palomer> can you do something like let x = `X::x ;; let x = `Y::x;; ?
<palomer> so you lose some type safety along the way
<palomer> gotcha
<mrvn> # let x = [];;
<mrvn> val x : 'a list = []
<mrvn> # let x = `X::x ;;
<mrvn> val x : [> `X] list = [`X]
<mrvn> # let x = `Y::x;;
<mrvn> val x : [> `X | `Y] list = [`Y; `X]
<palomer> so the rule is only use polymorhic variants when needed
<palomer> so as to take advantage of type safety
<mrvn> palomer: You don#t loose type safety. You just have a different idea of types.
<palomer> you can insert any polymorphic type in x!
<mrvn> You can write a function that takes A | B | any other
<palomer> if it was non polymorphic, you'd be restricted to the variants in a specific sum type
<mrvn> You can also restrict the type to a certain set
<palomer> how would you write a function that takes A | B | any other?
<palomer> I thought constructors were unique!
<mrvn> The main advantage would be to include objects of a smaller set in a larger set.
<mrvn> They are.
<palomer> how do you restrict polymorphic variant functions to sets?
<palomer> or lists
<palomer> or any containers for that matter
<mrvn> type player = [`O | `X];;
<mrvn> let print_player = function (`X : player) -> print_char 'x' | `O -> print_char 'o';;
<mrvn> # print_player `E;;
<mrvn> This expression has type [> `E] but is here used with type
<mrvn> player = [ `O | `X]
<palomer> ahh, gotcha
<mrvn> Thats why you have [ ], [< ] and [> ]
docelic|away is now known as docelic
<mrvn> `E is a set that include `E and possibly more.
<mrvn> type [> `E]
<mrvn> The player type would be just the two variants.
<palomer> [> `E] may include more?
<palomer> [ `E ] would just include E?
<palomer> what would [< `E ] include?
<mrvn> It is valid for all functions that have a `E in their set.
<mrvn> palomer: `E or anything smaller.
<palomer> smaller?
<mrvn> Which doesn#t realy make sense.
<palomer> > means anything greater?
<palomer> variants are ordered?
<mrvn> # let foo = function `E -> 0 | `F -> 1;;
<mrvn> val foo : [< `E | `F] -> int = <fun>
<palomer> erm
<mrvn> foo acepts `E, `F and `E|`F types.
<palomer> ohmy, you can union them?
<mrvn> smaller meaning subset.
* palomer kills self
<palomer> con you union normal variants?
<mrvn> palomer: No, only typewise.
<palomer> typewise?
<mrvn> type player = [`O | `X];;
<palomer> what's the use of naming your types?
<mrvn> # type only_E = [ `E ] and only_F = [ `F ] and both = [ `E | `F ];;
<mrvn> type only_E = [ `E]
<mrvn> type only_F = [ `F]
<mrvn> type both = [ `E | `F]
<mrvn> just shortcuts for restricting types.
<palomer> ok, how do you use those types now?
<mrvn> # let foo (x : both) = match x with `E -> 0 | `F -> 1;;
<mrvn> val foo : both -> int = <fun>
<mrvn> just like any other type.
<mrvn> You can also cast polymorphic types:
<mrvn> # let an_E = (`E : only_E);;
<mrvn> val an_E : only_E = `E
<mrvn> # foo (an_E :> both);;
<mrvn> - : int = 0
<palomer> :O
<mrvn> That way you can grow some variant types by some more values without rewriting all the function.
<palomer> so is there a distinction between a function that takes [< `E | `F ] and one who takes [ `E | `F ]?
<palomer> would i use it any differently?
<mrvn> Yes.
<mrvn> # let foo = function `E -> 0 | `F -> 1 and bar (x : both) = match x with `E -> 0 | `F -> 1;;
<mrvn> val foo : [< `E | `F] -> int = <fun>
<mrvn> val bar : both -> int = <fun>
<mrvn> both being [ `E | `F ] from above.
<mrvn> # foo an_E;;
<mrvn> - : int = 0
<mrvn> # bar an_E;;
<mrvn> This expression has type only_E = [ `E] but is here used with type
<mrvn> both = [ `E | `F]
<mrvn> The first variant type does not allow tag(s) `F
<mrvn> [ `E ] doesn't fit a [ `E | `F ]
<mrvn> its smaller.
<mrvn> # `E;;
<mrvn> - : [> `E] = `E
<mrvn> # bar `E;;
<mrvn> - : int = 0
<mrvn> [> `E] fits [ `E | `F ] because that `E or more.
<mrvn> You can restrict your types and functions to subsets, exact matches or supersets.
<palomer> ahh, gotcha
<palomer> where is an_e defined?
<mrvn> Back to the game example. A path finding function would only need to know where the board is empty. You would type it as [> `E ] board -> path
<mrvn> # let an_E = (`E : only_E);;
<mrvn> val an_E : only_E = `E
<mrvn> The pathfinding function would work with anything that has `E on its board to declare empty fields.
<mrvn> One function and it works with just `X and `O or with `Blocks or a set of 1000 different pieces.
<palomer> why would you vere want to limit the type of a variable to a subset?
<palomer> so that it never becomes the input of a function that takes the strict set?
<mrvn> If you have multiple groups of polymorphic variants.
<palomer> ahhh, starting to understand
<mrvn> Like colors and fruits and smells.
<palomer> so a function that takes player piece info would be foo = function (x:black_or_white)
<palomer> while one that takes board pices would be (x:black_or_white_or_empty_or_blocked)
<mrvn> type colors = [ `Red; `Green`; `Yellow; `Blue; ] and traffic_light_colors = [ `Red; `Yellow; `Green; ]
<mrvn> palomer: yes.
<palomer> ahhh
<palomer> so it's a safety mechanism
<palomer> starting to understand
<mrvn> But you probably would want to allow players to be used as board pices.
<mrvn> so [< ... ] for board piece.
<mrvn> But that allways depends and what you need.
<palomer> so that's what naming sum types is good for!
<palomer> mrvn, you rock
<mrvn> The naming is just so you don't allways have to type it.
<mrvn> (x : player) is somewhat more readable than (x : [ `X | `Y ])
<palomer> so optional arguments are polymorhic, with [> `None ; `Sum ] ?
<mrvn> optional arguments?
<palomer> let foo ?x = function None -> 3 ; Some -> 4;;
<palomer> brb
<mrvn> No, they are just plain option types.
<mrvn> ?x saves you from using None | Some x
<mrvn> Thats just syntactic suggar
<palomer> back
<palomer> option types?
<mrvn> # let x = Some 1;;
<mrvn> val x : int option = Some 1
<mrvn> ?x is just a normal option.
<palomer> haven't seem option types
<mrvn> # type 'a option = None | Some of 'a;;
<mrvn> type 'a option = None | Some of 'a
<palomer> ahh
<palomer> gotcha
<mrvn> Its a buildin variant type.
<palomer> so option is a sum type
<mrvn> yes.
<palomer> this is getting interesting:o
<mrvn> But since you need it so often its predefined
<palomer> so methods are slow binding right?
<palomer> meaning I can change the method of a class
<palomer> of an object I should say
<palomer> correct?
<mrvn> And its called variant or enumerated types if all alternatives are constants
<mrvn> How would you change the method of an object?
<mrvn> do you mean virtual functions or function overloading?
<palomer> erm
<palomer> let foo = object method bar = foobar;;
<palomer> let barfoo = new foo;;
<palomer> can I change barfoo.bar?
<mrvn> nope.
<palomer> erm
<palomer> 1 sec, lemme look it up
<mrvn> first its not mutable and second I don't think methods can be.
<palomer> ahh, it was that methods used within methods are slow binding
<mrvn> # class foo = object method bar = "bar" end;;
<mrvn> # class foobar = object inherit foo method bar = "foobar" end;;
<mrvn> # let foo = new foo and foobar = new foobar;;
<palomer> let foo = object method bar x = a x ; a x -> 3;; let foobar = object inherit foo method a x -> 4;;
<mrvn> # let l = [ foo; foobar];;
<mrvn> # List.map (fun x -> x#bar) l;;
<mrvn> - : string list = ["bar"; "foobar"]
<palomer> I mean method calls within methods
<mrvn> palomer: What language is that?
<palomer> :o
<palomer> palocaml
<mrvn> Certainly nothing my ocaml compiles.
<mrvn> But I think what you try to say is that methods are dispatched through a virtual table.
<palomer> method bar x = self#a
<palomer> there we go
<palomer> yes
<palomer> doesn't that slow things down?
<mrvn> # class foo = object method foo = 0 end;;
<mrvn> Thats the same as
<mrvn> # type foo = { foo : unit -> int; };;
<mrvn> # let make_foo = { foo = fun () -> 0; };;
<mrvn> It means that you have to lookup a function pointer each time a function is called.
<mrvn> Usually its slower.
<mrvn> Thats one thing I don't quite like in ocaml.
<palomer> speed?
<palomer> ocaml is speedy quick!
<mrvn> But its cleaner.
<mrvn> palomer: amasingly speedy usually.
<palomer> yhea
<palomer> I don't know how:o
<palomer> so what don't you like
<mrvn> That all methods are dispatched through a function table.
<palomer> ahh
<palomer> like java
<palomer> unlike c++ and c#
<mrvn> more like C++
<mrvn> is what I would like
<palomer> for speed reasons?
<mrvn> In C++ you can say that method is virtual or static.
<mrvn> Speedier and sometimes you don't want other classes to mess up your interface.
<mrvn> e.g. if you have a public method that used internally. Every other class can inherit you and change the method.
<mrvn> +is
<palomer> so theres no way of not using the virtual table?
<mrvn> not for public method.
<palomer> you could define a method relative to a private value, can't you?
<mrvn> class foo = let bar () = "bar" in object method blub = bar () end
<palomer> yhea
<mrvn> bar is just like any other value.
<palomer> there you do
<palomer> I mean there you go
<mrvn> But from ouside the class you still have to use foo#blub
<palomer> ahh, and it can be overwritten
<mrvn> blub can but bar not.
<mrvn> you can also make methods private. That should keep them save.
<mrvn> not sure on that one though.
<palomer> so how about (pseudocodish) class foo = private val bar = fun x -> x+2 ; method blub = bar;;?
<palomer> where blub is public
<mrvn> palomer: val is private anyway
<mrvn> class foo = object val x = 0 end, you will never get the x out of the class.
<palomer> ahh yes
<palomer> so class foo = val bar = fun x -> x+2 ; method blub = bar;;
<palomer> pseudo
<mrvn> Actually that not true. YOu can get the x out of foo:
<mrvn> # class bar = object inherit foo method bar = x end;;
<mrvn> So val is only protected
<mrvn> But without mutable it can't be changed.
<palomer> bar isn't a method!
<palomer> what im saying is that instead of having public functions calling public functions, if you want the interface to be the same you have public methods only calling private methods
<palomer> or private values
<mrvn> more to type and still slower than static functions.
<mrvn> But its fast enough anyway.
<mrvn> My programs usually run only for seconds or for many hours. A 10% doesn#t realy matter much if it runs overnight anyway.
<palomer> hours?
<palomer> whoa
<mrvn> s/10%/10% speed increase/
<palomer> what's your favourite programming language?
<mrvn> currently ocaml
<palomer> more than haskell?
<mrvn> never used haskell much.
<mrvn> no compiler for alpha (in Debian) for example.
<palomer> yhea
<palomer> haskell won't compile in gcc3.2
<palomer> well thanks a bunch mrvw
<palomer> mrvn
<palomer> back to analysis
TachYon26 has joined #ocaml
TachYon26 has quit ["bez ki³y nie ma zaliczenia (z prawd studentek AM)"]
<vegai> palomer: ghc compiles fine here
<vegai> ok, this is not debian, but still
<vegai> doublechecks this right now
<vegai> ah, my distro uses 4.08 to bootstrap
<vegai> ahh, I guess I remembered wrong. Doesn't compile here ;-/
<palomer> :o
<palomer> another roadblock
<whee> heh, I like haskell more than ocaml D:
<palomer> what does [> a b ] mean?
<whee> polymorphic variant, containing those two types and possibly more?
<whee> just guessing :|
<palomer> they aren't polymorphic!
<palomer> that's what I don't understand
<whee> using backticks when referencing the variants?
<palomer> eh?
<palomer> backticks indicate polymorphic variants
<whee> yes
<palomer> class container_signals : [> Gtk.container] Gtk.obj -> object end
<palomer> what does that mean:o?
<whee> er, might mean something different in that context
<whee> I don't know lablgtk, so I'm not sure offhand
mrvn_ has joined #ocaml
<palomer> :/
<palomer> lablgtk is really hard to work with
<palomer> no docs!
<palomer> atleast a reference
<palomer> all I have is this
<palomer> which is a very much incomplete ocamldoc page
mrvn has quit [Read error: 60 (Operation timed out)]
<mattam> palomer: looking at the mli files is maybe the best solution
<palomer> true
<palomer> maybe I can generate my own ocamldoc for it
<palomer> how do I generate ocamldocs?
<palomer> I can't find any documentation anywhere
cm has quit ["simon says: rehashing"]
cm has joined #ocaml
systems has joined #ocaml
systems has quit ["Client Exiting"]
<mattam> palomer: there is a section in the manual
<mattam> about exactly 1hour distance between q & a :)
mrvn_ is now known as mrvn
<vegai> has the same guy designed netbsd.org and ocaml.org? =)
TachYon has joined #ocaml
TachYon has quit [Read error: 54 (Connection reset by peer)]
mattam_ has joined #ocaml
mattam has quit [Read error: 110 (Connection timed out)]
mattam_ is now known as mattam
stepcut has joined #ocaml