Alpounet changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | 3.11.1 out now! Get yours from http://caml.inria.fr/ocaml/release.html
ikaros has joined #ocaml
thrasibule has quit [Remote closed the connection]
thrasibule has joined #ocaml
marteo has quit ["Debian GNU/Hurd is Good."]
dark has quit [Remote closed the connection]
thrasibule has quit [Read error: 113 (No route to host)]
wormphlegm has quit []
ikaros_ has joined #ocaml
ikaros has quit [Read error: 60 (Operation timed out)]
tmaedaZ is now known as tmaeda
tmaeda is now known as tmaedaZ
joewilliams has quit [Remote closed the connection]
cloudhead has quit [Read error: 110 (Connection timed out)]
ikaros_ has quit ["Leave the magic to Houdini"]
EliasAmaral has joined #ocaml
EliasAmaral is now known as dark
Pimm has quit [Remote closed the connection]
<WuJiang> anyone know any available projects on OCaml
<WuJiang> thanks
johnnowak has joined #ocaml
<thelema> WuJiang: There's a big todo list for the batteries project: http://github.com/thelema/AAA-batteries/issues
johnnowak has left #ocaml []
_unK has quit [Remote closed the connection]
ski_ has joined #ocaml
Alp_ has quit [Read error: 110 (Connection timed out)]
ski_ has quit ["Lost terminal"]
ski_ has joined #ocaml
Alp has joined #ocaml
Alp has quit [Read error: 54 (Connection reset by peer)]
Alp has joined #ocaml
<derenrich> does the "<|" op have a name?
wormphlegm has joined #ocaml
dark has quit [Read error: 101 (Network is unreachable)]
tmaedaZ is now known as tmaeda
wormphlegm has quit []
thrasibule has joined #ocaml
ygrek has joined #ocaml
derenrich has quit [Read error: 60 (Operation timed out)]
thrasibule has quit [Read error: 60 (Operation timed out)]
marteo has joined #ocaml
svenl has quit []
svenl has joined #ocaml
ttamttam has joined #ocaml
AndChat- has joined #ocaml
AndChat- has quit [Client Quit]
AndChat- has joined #ocaml
ski_ has quit ["Lost terminal"]
Pepe_ has quit [Read error: 60 (Operation timed out)]
Pepe_ has joined #ocaml
cloudhead has joined #ocaml
AndChat- has quit [Remote closed the connection]
AndChat- has joined #ocaml
AndChat- has quit [Remote closed the connection]
ttamttam has quit ["Leaving."]
arquebus has joined #ocaml
ulfdoz has joined #ocaml
ikaros has joined #ocaml
CcSsNET has joined #ocaml
CcSsNET has quit [Remote closed the connection]
ksson has joined #ocaml
eldragon has joined #ocaml
BiDOrD has quit [Read error: 60 (Operation timed out)]
ski_ has joined #ocaml
derenrich has joined #ocaml
BiDOrD has joined #ocaml
arquebus has quit [Remote closed the connection]
derenrich has quit [Connection timed out]
demitar has joined #ocaml
_unK has joined #ocaml
M|_ has quit [Read error: 60 (Operation timed out)]
M| has joined #ocaml
joewilliams has joined #ocaml
demitar has quit [Read error: 110 (Connection timed out)]
tmaeda is now known as tmaedaZ
demitar has joined #ocaml
tmaedaZ is now known as tmaeda
Yoric has joined #ocaml
demitar has quit [Read error: 110 (Connection timed out)]
bogen has joined #ocaml
derenrich has joined #ocaml
Amorphous has quit [Read error: 110 (Connection timed out)]
Amorphous has joined #ocaml
Tomsik has joined #ocaml
<Tomsik> Hi, I have a problem compiling ocaml code, files and errors are here: http://pastebin.ca/1734320
<Tomsik> It's basically that I want to use .mli as header, but I can't access functions in .ml file before I declare them there
<ksson> Tomsik: the .mli file is an interface for the *outside* world
ygrek has quit [Remote closed the connection]
<ksson> for all the other modules of your program
<ksson> it can not be used inside vector.ml (in your case)
<ksson> you should order your functions in vector.ml so that every function is defined before its use
<Tomsik> Oh, so what should I do? Copy-paste it? It would be stupid.
<mrvn> just more normalize after len
<Tomsik> That's kinda lame
<mrvn> move
<ksson> Tomsik: you also could define your functions using let rec
<ksson> let rec f = ... and g = ...
<mrvn> That is best avoided unless needed
<ksson> but this is considered bad style i guess
<ksson> (but i have seen people use it)
<mrvn> Tomsik: you also can't divide a float by a function. :)
<mrvn> v.x/.len should be v.x /. l
<Tomsik> Well, they're not recurrsive, but I'd rather have it clean and neat and in the same order
<Tomsik> Oh, yeah, thanks :)
<mrvn> Tomsik: why should normalize be before len?
<Tomsik> Because it's how it is in .mli, it'd be cleaner
Blueblaze has joined #ocaml
Blueblaze has left #ocaml []
<mrvn> The only job of the .mli file is to enable you to hide things from the .ml file.
<Tomsik> You can do that in C++ :p
<mrvn> yeah, but c++ has header files. :)
<mrvn> In ocaml you can write let foo = 1 let bar = foo let foo = 2
<mrvn> If the .mli file where a header file then bar would be 2 instead of 1 or something.
<mrvn> Tomsik: another hint: Use (** *) in the mli file so the automatic doc generation can pick up your comments
<Tomsik> Righto
<mrvn> and maybe let rotate_2d = rotate_z
<Tomsik> I'll probably remove it at all, I'm just refactoring code written by somebody else for our project for uni
<Tomsik> right now I just want it to work :p
<mrvn> any more errors?
<Tomsik> yeah, but things I can handle
<Tomsik> like forgetting the dot after a *
<mrvn> hehe. always have a few of those
marteo has quit ["Debian GNU/Hurd is Good."]
<Tomsik> well, there's one another thing, in another file I've got
<Tomsik> let sphere center radius_sqr v =
<Tomsik> let x = v.x-.center.x and y = v.y-.center.y and z = v.z-.center.z in
<Tomsik> x*.x +. y*.y +. z*.z <= radius_sqr;;
<Tomsik> and the error is: tomek@nibylandia:~/uczelnia/ocaml/projekt$ ocamlc -c objects.ml
<Tomsik> File "objects.ml", line 2, characters 14-17:
<Tomsik> Error: Unbound record field label x
<Camarade_Tux> if otherModule.ml is the file where this record is defined, you have to use "open OtherModule" or write v.OtherModule.x
<Tomsik> if it's Vector.t then I need to write v.Vector.x? That's kind of messy
<ksson> Tomsik: or you put "open Vector" at the top of your file
<Tomsik> And opening it would cause more mess
<Tomsik> No?
<palomer> some people are against open
<ksson> another idiom would be:
<ksson> module V = Vector
<ksson> v.V.x
<palomer> you could even cast the module, no?
<ksson> palomer: what is casting?
<palomer> something like module V : Somesig = Vector
<palomer> where Somesig only contains the stuff that interests you
<ksson> palomer: ah, yes that's possible
<palomer> so many options!
<ksson> hey i've another one
<ksson> if it's just for the record fields
<ksson> you could redeclare the type
<palomer> nope
<ksson> type t = Vector.t = { ... }
<palomer> ah yes
<palomer> forgot about that
<ksson> :)
<palomer> can you do that for any type?
<ksson> yes, for record types and algebraic data types
<ksson> other type definitions are only abbreviations anyway
<palomer> cool!
<palomer> does it check type equality nominally?
<palomer> or does it do it structurally?
<palomer> type t = Vector.t = {foo : t} is the same as type t = Vector.t = {foo:Vector.t} ?
<ksson> hmm
<ksson> palomer: i guess it checks that your redeclaration is equal to the original one
<ksson> but i don't know the exact sense of "equal" :)
<palomer> lemme test it out
<palomer> yep, both work
<ksson> ok
<palomer> ditto for polymorphic types
itewsh has joined #ocaml
Tomsik has quit ["Thus spoke Tomsik"]
cloudhead has quit [Read error: 60 (Operation timed out)]
emias has joined #ocaml
cloudhead has joined #ocaml
smimou has quit [Read error: 104 (Connection reset by peer)]
<mrvn> if you write type t = Vector.t can you then use v.x or do you need the extra = { x:float; ...}?
<palomer> good question
<palomer> you need the extra stuff
AndChat- has joined #ocaml
<palomer> according to my test case:
<mrvn> didn't know you could write type t = Foo.t = ....
<palomer> yeah, it was news to me too
<palomer> though I've seen it before
smimou has joined #ocaml
<mrvn> I would have added a Vector.T that just defines the vector record and opened that in Vector and modules using the Vector.
<palomer> you would have added something to the vector module?
<mrvn> yep. so you can open just the record without the rest
<palomer> I don't know if tomsik could have edited the Vector module
AndChat- has quit [Read error: 104 (Connection reset by peer)]
AndChat- has joined #ocaml
Pimm has joined #ocaml
johnnowak has joined #ocaml
johnnowak has quit [Client Quit]
ksson has quit [Read error: 60 (Operation timed out)]
Yoric has quit []
ski_ has quit ["Lost terminal"]
* palomer would KILL to be able to turn off the value restriction
Narrenschiff has joined #ocaml
ski_ has joined #ocaml
<palomer> how would you guys mash the following idiom into a single declaration:
<palomer> let temp = (counter := !counter + 1; !counter)
<palomer> let foo = fun x -> {something that uses temp}
<palomer> let foo = let temp = (counter := !counter + 1;!counter) in fun x -> {...} <--runs into the value restriction
<palomer> im using camlp4 so having extra declarations is kind of a bummer
<palomer> encapsulating it in a lazy clause doesn't get rid of the value restriction, surprisingly
cloudhead has quit [Connection timed out]
<palomer> oh, I guess it wouldn't, since let foo = lazy (ref []) in !(Lazy.force foo) :: 4; !(Lazy.force foo) :: "bee" is still unsafe
ksson has joined #ocaml
AndChat- has quit [Read error: 104 (Connection reset by peer)]
ksson has quit [Read error: 113 (No route to host)]
Wooh has joined #ocaml
<palomer> props to whoever can get the following to be polymorphic: let foo = let temp = (counter := !counter + 1;!counter) in fun x -> temp
<palomer> actually, wait, the value restriction doesn't hold in that case (since the polymorphic variable is in a generalizable position)
<mrvn> let next_count = let count = ref 0 in function () -> incr count; !count
<mrvn> and then use (next_count ()) each time you need one
<palomer> but I can't use (next_count ()) inside {...} in fun x -> {...}
<mrvn> # let foo = fun x -> next_count ();;
<mrvn> val foo : 'a -> int = <fun>
<palomer> let foo = let uid = next_count in fun x -> { stuff containing uid }
<palomer> is not the same as
<palomer> let foo x = {stuff containing (next count ()) }
<mrvn> # let foo = let uid = next_count () in fun x -> { id = uid; };;
<mrvn> val foo : '_a -> t = <fun>
<mrvn> # foo ();;
<mrvn> - : t = {id = 1}
<mrvn> # foo ();;
<mrvn> - : t = {id = 1}
<mrvn> works fine
<palomer> right, but I want '_a to be generalized
<palomer> that's my problem in a nutshell
<mrvn> ahh.
<mrvn> Why is that an '_a anyway?
<palomer> well, because you can't generalize a let
<palomer> though ocaml has a relaxed version of this restriction
<mrvn> # let f g h x = g (h x);;
<mrvn> val f : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
<mrvn> perfectly generalized
<palomer> that's not a let
<palomer> that's a fun
Yoric has joined #ocaml
<mrvn> # let f = fun g h x -> g (h x);;
<mrvn> val f : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
<palomer> hey yoric
<mrvn> Why is that different from foo?
<palomer> let foo = let... versus let foo = fun ...
<palomer> in the first case it's a let, in the second case it's a foo
<palomer> more generally:
<mrvn> # let f = let x = 1 in fun g h x -> g (h x);;
<palomer> right, that shouldn't generalize
<mrvn> val f : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
<Yoric> palomer: hi
<palomer> or the let x = 1 is ignored
bogen has quit ["Leaving."]
<mrvn> # let f = let uid = next_count () in fun g h x -> g (h x);;
<mrvn> val f : ('_a -> '_b) -> ('_c -> '_a) -> '_c -> '_b = <fun>
<palomer> ahh, good point
<mrvn> Is the difference that the let contains a function call?
Wooh has quit ["Quitte"]
<palomer> im trying to find the definition of "value" in ocaml
<mrvn> # let f () = let uid = next_count () in fun g h x -> g (h x);;
<mrvn> val f : unit -> ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
<mrvn> # let f = f ();;
<mrvn> val f : ('_a -> '_b) -> ('_c -> '_a) -> '_c -> '_b = <fun>
<palomer> right, the first one is a fun
<mrvn> verry odd behaviour
<palomer> the second one is an application
<palomer> I can understand that
<mrvn> How does applying the first argument to a generalized function make the rest not generalized?
<palomer> let g = f () ;; <--g is an application, though suffers from the value restriction
<palomer> s/though/so
<palomer> the definition of value is strangely missing from the ocaml manual
<palomer> let id = fun x -> x
<palomer> let foo = id id
<palomer> right, but the definition of value in that faq doesn't seem to apply here
<palomer> since you were able to generalize a let
<palomer> let x = 1 in fun g h x -> g (h x) <--not a value by the definition in that faq
<mrvn> why? 1 is a constant, x is a variable. Both are values. But next_count () is not causing the value restriction
Pimm has quit [Read error: 110 (Connection timed out)]
<palomer> let .. in ... is never a value by the definition in the faq
<palomer> im gonna ask the mailing list about this
<palomer> mind I use your example?
<mrvn> go ahead
<mrvn> It would be nice to see an example why we need a value restriction at all.
<mrvn> but you can rewrite your code: # let uid = next_count () let foo x = { id = uid };;
<mrvn> val uid : int = 7
<mrvn> val foo : 'a -> t = <fun>
<palomer> right, use 2 declarations
<palomer> but I'm generating this code with camlp4
<palomer> and I don't want there to be errand declarations
<mrvn> you need to do eta expansion and that means using 2 toplevel declarations
<palomer> value restriction: let _ = let foo = ref [] in foo := [4] ; foo := "bee" :: (!foo)
<mrvn> how does that relate to foo where the x is never used?
<palomer> mrvn, what do you mean?
<mrvn> By assigning [4] to the 'a list ref you bind the 'a to int. That doesn't happen in the previous example.
<palomer> ah, right, so to avoid my little example they impose a very draconian rule
<mrvn> I don't see how the two relate at all
<palomer> ref [] is not a value, so foo isn't generalized
<mrvn> # let _ = let foo = [] in 4::"bee"::foo;;
<mrvn> same thing. simple type inference.
<palomer> that type checks?
<mrvn> and't don't tell me [] isn't a value
<palomer> [] is a value
<mrvn> palomer: obviously not, like your last example.
<palomer> in my example, foo has type 'a list ref, yes?
<mrvn> palomer: only until you use it.
<palomer> because of the value restriction!
<palomer> let _ = let foo = [] in 4::"bee"::foo;; <--foo will always have type 'a list, no matter how many times you use it
<palomer> (which is the whole point of let-polymorphism)
<mrvn> let foo = ref [];;
<palomer> has type '_a list ref
<mrvn> '_a list ref, it never is generalized
<mrvn> nothing to do with it being inside another let
<palomer> right, because of the value restriction
<palomer> in this case it's not generalized because it's an application
<palomer> applications aren't generalized and lets aren't generalized
<mrvn> I'm afraid I don't understand the value restriction at all
<mrvn> (which might be a result of the time too)
<palomer> consider: let x = y in t
<palomer> the type of x will be generalized iff y is a value
<mrvn> the type of x will be the type of y
<palomer> with some variables generalized, yes?
<mrvn> or not. whatever y has
<palomer> is let x = y in t the same as (fun x -> t) y ?
<palomer> (hint: no!)
<mrvn> why not?
<mrvn> in both case any occurance of x in t is replaced by y
<palomer> consider let x = (fun y -> y) in x 5; x "bee"
<palomer> they are semantically the same, but not the same according to the type system
<mrvn> I still don't see why they can't be
<palomer> that's a little tougher to answer
<mrvn> I do understand why ref [] must be a '_a list ref. I probably just don't get how that is generalized into the value restriction.
<palomer> we agree that (fun x -> x "bee"; x 5) <--x must have a polymorphic type, yes?
<mrvn> yes
<palomer> however, trying to figure out which terms have a polymorphic type without annotations is undecidable
<palomer> so we only do it at a let
<palomer> so far so good?
<mrvn> yes
<palomer> so in let x = y in t <--the type of x will be the type of y with some variables generalized, yes?
<mrvn> so y might be '_a -> '_b but then you decide that x can still be 'a -> 'b
<palomer> right!
<palomer> if y is a value and both '_a and '_b are not in the context, this is what happens
<mrvn> And the value restriction says when it is save to change '_a to 'a.
<palomer> right
<mrvn> that I get now :)
<palomer> value restriction + context restriction
<mrvn> I thought you would infer that y is 'a -> 'b already and only drop down to '_a when it is not save.
<mrvn> But that is probably too hard to infer or gives really bad errors.
<palomer> generalizing is the last step
<palomer> ocaml has a relaxed value restriction and (so it seems) a relaxed definition of value
<mrvn> and you can't annotate generalization like: (fun (x:'a) -> x "bee"; x 5);;
<palomer> the 'a annotation is really a '_a
<palomer> and even if you could, it wouldn't cut it
<mrvn> which really sucks for the cases when you do mean 'a
<mrvn> You can only do that with records.
<palomer> let foo : 'a ref list = ref []
<palomer> err 'a list ref
<palomer> and objects
johnnowak has joined #ocaml
<mrvn> same thing :)
<mrvn> { f = ... }; and method foo = ... is pretty much the same as let.
<palomer> you can use self in the method, and super#foo
<palomer> (I think it's called super)
<mrvn> didn't you have to give it a name when you inherit it?
<palomer> ah, no, you can do inherit bar, and then use bar#foo
<palomer> right, I forget the syntax
Yoric has quit []
<mrvn> I think I haven't used classes in about a year. rusty.
<palomer> I still have my problem:o
<mrvn> I think there is no way around lifting the uid to the toplevel and doing eta expansion.
<palomer> all this work just to give type declarations unique identifiers
<palomer> bummer:/
<mrvn> There should be a compiler macro hash_of_type(t)
<palomer> it would have to come from camlp4
<mrvn> ocaml should already have it
<palomer> mrvn, what do you mean?
<mrvn> The compiler should generate that at compile time.
<palomer> so it would be a compiler pragma?
<mrvn> First use would be to make marshaling type save
<palomer> that's useful!
<mrvn> palomer: yes
<palomer> oh, this is conjecture, but doesn't exist
<mrvn> and it wouldn't work on polymorphic types.
<palomer> thelema is our resident ocaml compiler expert
<palomer> mrvn, the type constructor would have a hash
<palomer> or it could be a function
<palomer> 'a -> 'b -> 'c -> int
<palomer> err
<palomer> int -> int -> in
<palomer> you get the point
<mrvn> let t = Foo.make 17; hash_of_type(t) would work. but not let hash x = hash_of_type(x)
<mrvn> or rather the compiler would have to do some nifty magic to make the second one work.
<palomer> hash_of_type(x) would return an int
<mrvn> could.
<palomer> well, looks like I'm going to have to byte the bullet
itewsh has quit ["There are only 10 kinds of people: those who understand binary and those who don't"]
<palomer> the other option was to have camlp4 generate the unique identifiers
<mrvn> does ocaml have something like in C where _xyz is reserved?
<palomer> mrvn, that's an informal rule, no?
<mrvn> palomer: are you writing an universal type?
<palomer> you mean 'a. 'a -> 'a ?
<mrvn> it is in the standard
<mrvn> palomer: no, an universal container. Something you can put different types in and fetch them by id.
<palomer> im writing a type_of function of type Foo.t -> type_description
<palomer> so I can do stuff like let x y = if type_of(x) = type_of(y) then "they are the same type" else "different types"
<palomer> err, let compare x y = ...
<mrvn> Then you need a lot of magic in your camlp4.
EliasAmaral has joined #ocaml
johnnowak has quit []
EliasAmaral is now known as dark
<palomer> it works fine, I just call next_counter ()
<mrvn> You need to rewrite all the code to carry runtime type information like { id : int; val : 'a }
<palomer> mrvn, yeah, that's what I did
<palomer> but then you have polymorphic types
<mrvn> hmm, 'a list has e.g. id = 5. But int list and float list need to show up different.
<palomer> let mylist = let uid = next_counter () in fun x -> { id = [[uid];x.id ; val = ...}
<mrvn> yep. ugly ugly ugly
<palomer> this is precisely where im running into the value restriction
<palomer> one way around it is to use obj.magic
<mrvn> You could transform every type into a class with a #id medthod.
<palomer> I still need to have polymorphic types map to functions
<palomer> like in my example
<mrvn> class ['a] list = let id = next_count () in object method id = next_count :: head#id end kind of
<mrvn> don't know how to do [] though.
<palomer> that's polymorphic?
<mrvn> palomer: head would be <id : int; ..>
<mrvn> So a list just combines its own id with the id of head.
<palomer> where did you define head?
<mrvn> I didn't
<palomer> so what is it?
<mrvn> palomer: You would specify head and tail as arguments in the constructor.
<palomer> I still run into the value restriction
<palomer> class ['a] list : object method foo : '_b -> '_b end
<palomer> because of the let
<mrvn> what if you specify that as 'b. 'b -> 'b?
<mrvn> But I guess you need to lift the id out of the object
<palomer> hrmph, this might work
<palomer> actually, won't
<palomer> class ['a] list y = let id = ..... <--this acts like a fun
<mrvn> How do you want the code to look? type t = { x : int; y : Foo.t; } let internal_t_id = next_id () let t_id = Record (internal_t_id; [ int_id; Foo.t_id])?
<palomer> currently every type t has an associated value foo_of_t
<mrvn> which is what?
<palomer> it has two records:
<palomer> create_t
<palomer> and type_of_t
<palomer> if t is polymorphic, then foo_of_t has type 'a foo -> 'b foo -> ... -> myrecordtype