Banana changed the topic of #ocaml to: OCaml 3.08.1 available! | Archive of Caml Weekly News: http://sardes.inrialpes.fr/~aschmitt/cwn/ | A tutorial: http://merjis.com/richj/computers/ocaml/tutorial/ | A free book: http://cristal.inria.fr/~remy/cours/appsem/ | Mailing List: http://caml.inria.fr/bin/wilma/caml-list/ | Cookbook: http://pleac.sourceforge.net/
monochrom has quit ["Don't talk to those who talk to themselves."]
mrsolo_ has joined #ocaml
mattam has quit [Remote closed the connection]
mattam has joined #ocaml
m3ga has joined #ocaml
skylan has joined #ocaml
cjohnson has quit [Read error: 104 (Connection reset by peer)]
cjohnson has joined #ocaml
<cjohnson> Hey, I have an error message I don't really understand. I made this function to create a multidimensional array:
<cjohnson> let rec array_builder dimensions elements default =
<cjohnson> if dimensions = 1 then
<cjohnson> Array.create elements default
<cjohnson> else
<cjohnson> Array.create elements (array_builder (dimensions - 1) elements default);;
<cjohnson> But get this error message:
<cjohnson> This expression has type 'a array but is here used with type 'a
<m3ga> it means that where the compiler is expecting an array of type a' you are giving it a single element of type a'.
<Smerdyakov> Your desired function has no valid OCaml type.
<m3ga> i think its in the second Array.create
<Smerdyakov> Which means that you can't implement this in OCaml. Sorry.
<kinners> the 3rd line returns 'a array, the 5th line takes type 'a but your giving it 'a array
<cjohnson> kinners: So? I can do like Array.create(foo Array.create(foo (Array.create foo 5))) for a 3 x foo array of 5's
ez4 has joined #ocaml
<kinners> cjohnson: So? That has a definite type, the function doesn't
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
<cjohnson> I'm not sure if I understand why this doesn't have a definite type
<cjohnson> (Please excuse my newbness)
<Smerdyakov> What type would you give your function?
<cjohnson> 'a array
<Smerdyakov> That's not a function type.
<cjohnson> err
<cjohnson> int -> int -> 'a -> 'a array
<cjohnson> Is that what you mean?
<Smerdyakov> That is a function type, yes.
<Smerdyakov> The function you gave can't have that type, though.
<cjohnson> Why?
<Smerdyakov> It's your job to say "why so." How would the typing rules of OCaml allow it?
<Smerdyakov> For instance, consider (array_builder 2 1 0).
<Smerdyakov> Does that return an int array?
<Smerdyakov> (You don't even need to look at your code here. I'm asking about your ideal function.)
<cjohnson> I would expect [| [| 0 |]; [| 0 |] |], I think
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
<cjohnson> Ah, ok
<Smerdyakov> I'm asking for a type.
<Smerdyakov> Not a value.
<Smerdyakov> Does that value you gave have the type int array?
<cjohnson> that's an int array array
<Smerdyakov> OK. Then you have just given a counterexample to the claim that this function would have the type you gave.
<cjohnson> I see that, now. Hmm...
<cjohnson> Hmm, or do...
<cjohnson> Could you have a function of type
<Smerdyakov> And, as I've said, it wouldn't be worth your time to try to change the type or change the implementation.
<cjohnson> int -> int -> 'a -> 'b array
<Smerdyakov> This function can never be implemented in OCaml.
<cjohnson> Where the 'b is an 'c array that's a 'd array that's a ...
<Smerdyakov> Nope. Any function with that type must loop forever or throw an exception.
<cjohnson> Now, when you say "this function", do you mean in general a function for a multidimensional array of an arbitrary number of dimensions, or for this particular idea for creating such a function?
mrsolo_ has quit [Read error: 104 (Connection reset by peer)]
<Smerdyakov> A function whose return type depends on the values of its arguments
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
pango has quit [Nick collision from services.]
pango has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
kinners has quit ["leaving"]
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
cjohnson has quit ["The main attraction: distraction"]
ne1 has joined #ocaml
cjohnson has joined #ocaml
cjohnson has quit ["The main attraction: distraction"]
mrsolo has joined #ocaml
m3ga has quit ["Client exiting"]
GreyLensman has joined #ocaml
GreyLensman has quit ["Leaving"]
mrsolo has quit [Read error: 104 (Connection reset by peer)]
mrsolo has joined #ocaml
<mflux> hmm.. can gcaml do that 'return any-dimensional array'-thing?
Gliptic has joined #ocaml
vezenchio has joined #ocaml
ez4 has quit [Remote closed the connection]
ne1 has quit ["To understand recursion, you must first understand recursion."]
<pango> type 'a narray =
<pango> Array1 of 'a array
<pango> | ArrayN of 'a narray array ;;
<pango> let rec array_builder dimensions elements default =
<pango> if dimensions = 1 then
<pango> Array1 (Array.init elements (fun _ -> default))
<pango> else
<pango> ArrayN (Array.init elements (fun _ -> array_builder (dimensions-1) elements default)) ;;
pango has quit ["Client exiting"]
mlh has quit [Client Quit]
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
pango has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
oracle1 has joined #ocaml
<oracle1> i have a hashtbl with type (string * string, int) Hashtbl.t
<oracle1> now I want iter over it with
<oracle1> Hashtbl.iter (fun (a,b) c -> Printf.printf "Variable %s in %s with %d\n" a b c) htbl
<oracle1> but they compiler says:
<oracle1> This expression has type (string * string ref, int) Hashtbl.t
<oracle1> but is here used with type (string * string, int) Hashtbl.t
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
<oracle1> what am I missing here?
<Nutssh> When you store into the hash table, you're storing (string * string) ref's as keys, not (string * string)'s
<Nutssh> Aka, read what the error message is saying, *very* carefully.
<Nutssh> Type inference is inferring the wrong type. It may help to put in an explicit type declaration in if you can't find the problem.
<oracle1> well it says (string * string ref) not (string * string) refs
<Nutssh> Oops. :)
<oracle1> with this iter its working:
<oracle1> Hashtbl.iter (fun a c ->
<oracle1> Printf.printf "Variable %s with %d\n" (fst a) c) htbl
<oracle1> though it's not accepting the (snd a)
<Nutssh> I know. Read the error message carefully and try to translate it into words for me.
ez4 has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
<oracle1> the real type of the expressiong is (string * string ref, int). though I wrote a type of (string * string, int)
<oracle1> I don't understand why it's inferred as string ref.
<oracle1> Hashtbl.iter (fun a c ->
<oracle1> Printf.printf "Variable %s in %s with %d\n" (fst a) !(snd a) c) htbl
srv_ has quit ["leaving"]
<Nutssh> Wait a sec.. What do you mean 'real type'.. You mean that you *expected* the type to be that. Obviously its not.
<Nutssh> You expected htbl to have type (string * string, int) Hashtbl.t
<oracle1> yes I expected to be string * string, cause added it with Hashtbl.add like this
<Nutssh> Err, Scratch the last two lines. I misread. Its late.
<oracle1> Hashtbl.add htbl ("a","b") 1
<oracle1> when I do it in toplevel it's working, and correctly inferred to a (string * string, int) hashtbl.t
<Nutssh> Its being inferred because wherever htbl is coming from (or some other place where its being used) it is getting the unexpected type.
<Nutssh> Here's an idea, take wherever you bind 'htbl' and explicity declare the type to be what it should be. That should point out the type error more clearly.
srv has joined #ocaml
<Nutssh> The code you wrote is OK for the type you expected it to have ((string * string), int) Hashtbl.t Find out why it doesn't have that type.
<oracle1> Yes, it's an idea. When I copy the whole code into the toplevel it's working
<oracle1> when I compile it, it's not
<Nutssh> There is another use of htbl which type inference is using to get the 'wrong' type.
<Nutssh> Type inference is a global operation. If there is a type error, all bets are off and unless you tell it explicitly what type things should have, it infers as much as it can before it gets stuck with an error. Sometimes in an unexpected place.
<oracle1> exactly
<oracle1> I found it
<oracle1> I added a string ref. Forgot the !
<oracle1> Thanks. Can I explicitely define the type of an lval ?
<oracle1> the answer is yes..I just don't know the syntax for it ..heh
<Nutssh> Do a 'type foo = (...) Hashtbl.t' for an abbreviation.
<oracle1> oh right
<oracle1> is it not working directly?
<oracle1> let x:(string * string, int) = Hashtbl.create 10;;
<Nutssh> '(string * string, int)' isn't a type. '(string * string, int) Hashtbl.t' is.
<oracle1> you are right. thank you
<oracle1> :)
<Nutssh> Welcome.. Now stick around to help someone else. :)
<oracle1> heh what do you think? I'm in a classroom or what?
<oracle1> ah no :)..I'm not that potent in english.
<Nutssh> Well, still, spread the knowledge and help somoeone else.
* Nutssh has b5 to watch.
<oracle1> I'm on the way to do so
<Nutssh> Good luck.
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
mlh has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
Tristram is now known as TristramEnLernej
ez4 has quit [Remote closed the connection]
pango has quit [zelazny.freenode.net irc.freenode.net]
pango has joined #ocaml
Herrchen has joined #ocaml
cjohnson has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
haelix has quit [Read error: 113 (No route to host)]
haelix has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
TristramEnLernej is now known as Tristram
mlh has quit [Client Quit]
Tristram has quit [Remote closed the connection]
Tristram has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
buggs has joined #ocaml
skylan has quit [Remote closed the connection]
skylan has joined #ocaml
arty has joined #ocaml
<arty> may i ask a question about polymorphic variants?
<Tristram> arty, of course ;)
<docelic> certainly, althought you are forbidden to ask to ask :)
<arty> well i'm going to update my swig module to support mixing values from different modules
<arty> which will be very neat
<arty> I implement C enums as a big polymorphic variant, but I'm stuck trying to get functions to type right
<arty> Can i do something like this (or am i thinking the wrong way):
<arty> val f : [>enum] c_obj_t -> [>enum] c_obj_t
<arty> and have the enum labels from both imported modules be accepted by the [>enum] type?
<arty> (b.t.w the enum type comes from a module that's shared by both the imported module that would add enum labels)
skylan has quit [Read error: 101 (Network is unreachable)]
<arty> hmm i think i didn't explain it very well
<arty> basically i have a module that has some type enum = [ `Int of int ]
<arty> and i have two other modules (A, B) that will have some other variant labels like `A and `B, and will also define some functions that take [>enum] arguments
<arty> specifically, there will be a function that will take a value of [>enum] and call a chain of functions to try to convert it to an int value for some underlying C code
<arty> the problem I have is convincing ocaml that the type of the function converting to int is [>enum] -> int and not enum -> int
<Smerdyakov> Polymorphic variants are trash.
<arty> well perhaps you'll help me consider another solution to this problem, then?
<arty> if you aren't familiar with it, SWIG is a wrapper generator for C++ code
<Smerdyakov> Can you restate the problem in a more fundamental way?
<arty> given some C++ code like this "enum pure { V1, V2, V3 }; enum bits { BitA = 4, BitB = 8 }; enum constant_value { CONSTANT = 1000 };"
<arty> and some functions like "pure f(); void g( int bits /* bits enum */ ); void g( pure p /* enum value from pure */ );"
<arty> my goals are these:
<arty> be able to do something like match f'() with V1 -> "v1" | V2 -> "v2" ...
<arty> (of course, the ocaml f is the result of some wrapper code)
<arty> and do something like this: let _ = g '( (enum_to_int `BitA) lor (enum_to_int `BitB) )
<Smerdyakov> Why do you want to use polymorphic variants for this, as opposed to regular variants?
<arty> and even let _ = g '( `V1 ) (* calls the alternate overloaded g *)
<arty> Because the regular variant space can't expand ... I'd have to know all enum labels beforehand
<arty> I do for a single module, but not for all modules
<arty> In addition, I'd rather do as little lexical transformation as possible
<arty> so polymorphic variants are desirable because they don't require capital letters (like C enums don't)
<Smerdyakov> But the space of enums is fixed in any given program.
<Smerdyakov> It would make more sense to implement coercion functions to and from int.
<Smerdyakov> You could use int as the cross-module interchange format.
<arty> Swig generates one module at a time, and the user could import more modules
<arty> I considered that but then you can't use them in patterns as easily
<Smerdyakov> I don't follow you. Why would you use something of uncertain type in a pattern?
<Smerdyakov> If you are mixing enum spaces, you could have name overlap.
<Smerdyakov> So pattern matching would be impossible.
<arty> you can have name overlaps, and they are ambiguous in the same way they would be in C++
<Smerdyakov> OCaml will never allow you to implement that.
<arty> overload resolution fails in those cases
<Smerdyakov> I think it is far better to resolve overlaps yourself when necessary.
<arty> Yes what you say is consistent with the ocaml philosophy
<arty> The people who use this module like the ability to use the labels in match expressions, however, choosing to throw an exception on a mismatch
<Smerdyakov> And they will _still_ be able to use labels in match expressions.
<arty> yes i see
<Smerdyakov> Show me a concrete case, from real code, where you think my suggestion is problematic, if you can.
<arty> I can't think of anything that would be a problem
<arty> Since I provide a camlp4 module, I can patch things up nicely using it
<arty> (i.e. to make using enum labels by short names work when it should, etc)
<arty> thanks I'll try that
<Smerdyakov> To me, most people use polymorphic variants the same way that most students in functional programming classes would write imperative code if they were allowed.
<Smerdyakov> It seems to make things "easier," until you start caring about correctness assurances and reducing development time.
<arty> it's probably true... admittedly I started using them on the advice of another person who tried to write a swig module for ocaml, because they seemed to fit the C++ enum space fairly well
<arty> and also because I had read some stuff by Jacques Garrigue
<Smerdyakov> I recon if someone wanted that kind of kludgey language mechanism, he would be using C++ for everything instead of interfacing with OCaml.
<arty> it's precisely because i want to use ocaml for almost everything that I wrote the SWIG module.
<arty> but making the interface as painless as possible is also important because C++ code can be very eccentric
<Smerdyakov> That wouldn't bother me, since not much of interest is implemented in C++.
<arty> it really depends on what your goal is, really
<arty> do you want to be credited in the changelog (by your real name)?
<Smerdyakov> It doesn't matter to me.
Herrchen has quit ["bye"]
menace has joined #ocaml
pango has quit ["Leaving"]
mrsolo has quit [Read error: 232 (Connection reset by peer)]
mrsolo_ has joined #ocaml
mrsolo_ has quit [Read error: 104 (Connection reset by peer)]
mrsolo_ has joined #ocaml
pango has joined #ocaml
kinners has joined #ocaml
CosmicRay has joined #ocaml
mrsolo_ has quit [Read error: 104 (Connection reset by peer)]
mrsolo_ has joined #ocaml
mrsolo_ has quit [Read error: 104 (Connection reset by peer)]
mrsolo_ has joined #ocaml
mrsolo_ has quit [Read error: 60 (Operation timed out)]
cjohnson has quit ["The main attraction: distraction"]
ericc has quit [Read error: 110 (Connection timed out)]
johgro has joined #ocaml
cjohnson has joined #ocaml
vezenchio has quit [""None of you understand. I'm not locked up in here with you. YOU are locked up in here with ME!""]
arty has left #ocaml []
cjohnson has quit ["The main attraction: distraction"]
menace has quit [" HydraIRC -> http://www.hydrairc.com <- Get hot chicks here!"]
monochrom has joined #ocaml
karryall has quit ["tcho"]
vincenz has quit ["Lost terminal"]
vincenz has joined #ocaml
binary42 has joined #ocaml
johgro has quit ["Leaving"]
zigong__ has joined #ocaml
CosmicRay has quit ["Client exiting"]
mrsolo_ has joined #ocaml
avlondono has quit ["leaving"]
mrsolo_ has quit [Read error: 110 (Connection timed out)]
kinners has quit [Read error: 110 (Connection timed out)]
judge has joined #ocaml
<judge> hi i'm a little confused
<judge> i cant figure out how to use the Str module
<judge> i get Error while linking /tmp/str.cmo: Reference to undefined global `Str'
<judge> when i try to compile it
<judge> s/it/my little test code/
<judge> i'm using ocaml 3.08
<Smerdyakov> You have to link it.
<Smerdyakov> (The Str library, that is)
<judge> how do i specify that?
<judge> i saw something about load "str.cmi";;
<Smerdyakov> Libraries are .cma or cmxa (for native code).
<Smerdyakov> This is even mentioned in the first manual page on the str library.
<judge> Smerdyakov: is #load "str.cma";; the proper way to load it from the code/
<judge> or is that only for interactive use?
<Smerdyakov> You should never use #anything with ocamlc or ocamlopt.
<judge> ok
<Smerdyakov> You specify libraries on the command line for those.
<judge> ocamlc /tmp/test.ml str.cma -o test
<judge> Error while linking /tmp/test.cmo: Reference to undefined global `Str'
<judge> nm
<judge> thanks for the tips