cjeris changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/
david_koontz has joined #ocaml
smimou has quit ["bli"]
gim has quit []
mbishop has quit ["Leaving"]
malc_ has quit ["leaving"]
<zarvok> hmm, can I mix named arguments and as patterns? I want to do something like "((ind,cen,rad) as ~sphere)" as a function's argument
<zarvok> but I am getting syntax errors
david_koontz has quit ["Leaving"]
jwt has quit ["Leaving"]
johnnowak has joined #ocaml
Z4rd0Z has joined #ocaml
<flux> when in doubt, check the documentation: file:///usr/share/doc/ocaml-doc/ocaml.html/manual015.html#parameter (the doc on web doesn't appear to have anchors)
<flux> in short: let foo ~a:(b, c) = b + c
<zarvok> flux: thanks!
<zarvok> interesting syntax, I'm surprise it doesn't cause strange conflicts with type annotation
<zarvok> *surprised
<flux> it is all clear from the page ;)
<flux> (infact I didn't know the syntax either..)
zarvok has quit ["My damn controlling terminal disappeared!"]
mbishop has joined #ocaml
Z4rd0Z has quit []
slipstream-- has joined #ocaml
slipstream has quit [Read error: 60 (Operation timed out)]
Smerdyakov has quit ["Leaving"]
klapmuet1 has joined #ocaml
klapmuetz has quit [Read error: 60 (Operation timed out)]
smimou has joined #ocaml
klapmuet1 is now known as benny
Nutssh has joined #ocaml
<jacobian> Anyone know how to get netsys in ubuntu
<jacobian> libocamlnet-dev doesn't seem to include it
love-pingoo has joined #ocaml
<flux> download and install libocamlnet-2.2?
descender has quit [Read error: 104 (Connection reset by peer)]
mnemonic has joined #ocaml
bluestorm_ has joined #ocaml
Submarine has quit [Remote closed the connection]
<mnemonic> hi
_JusSx_ has joined #ocaml
descender has joined #ocaml
Mr_Awesome has quit ["...and the Awesome level drops"]
mnemonic has quit [Read error: 104 (Connection reset by peer)]
mnemonic has joined #ocaml
dark_light has quit [Read error: 110 (Connection timed out)]
malc_ has joined #ocaml
jacobian has quit [Remote closed the connection]
bzzbzz has quit ["leaving"]
slipstream-- has quit [Read error: 60 (Operation timed out)]
johnnowak has quit []
Smerdyakov has joined #ocaml
zarvok has joined #ocaml
postalchris has joined #ocaml
descender has quit [zelazny.freenode.net irc.freenode.net]
eradman has quit [zelazny.freenode.net irc.freenode.net]
postalchris has quit [Read error: 113 (No route to host)]
pango has quit [Remote closed the connection]
vital304 has joined #ocaml
pango has joined #ocaml
descender has joined #ocaml
zarvok has quit ["BitchX-1.1-final -- just do it."]
vital304 has left #ocaml []
vital304 has joined #ocaml
eradman has joined #ocaml
eradman has quit [zelazny.freenode.net irc.freenode.net]
eradman has joined #ocaml
eradman has quit [zelazny.freenode.net irc.freenode.net]
eradman has joined #ocaml
eradman has quit [Remote closed the connection]
eradman has joined #ocaml
_JusSx__ has joined #ocaml
_JusSx_ has quit [Read error: 148 (No route to host)]
Z4rd0Z has joined #ocaml
vital304 has left #ocaml []
Riesz has quit ["Leaving.."]
mnemonic has quit ["leaving"]
Submarine has joined #ocaml
bluestorm_ has quit ["Konversation terminated!"]
flux has quit [Read error: 104 (Connection reset by peer)]
flux has joined #ocaml
jlouis has joined #ocaml
Mr_Awesome has joined #ocaml
eradman has quit [zelazny.freenode.net irc.freenode.net]
eradman has joined #ocaml
mbishop has quit ["Leaving"]
mrvn has joined #ocaml
<mrvn> hi
<mrvn> Are Bigarrays imune from being moved by the GC? i.e. can I take a pointer to the data part of a Bigarray.Array1.t in C and use that across GC calls?
<malc_> mrvn: yes
<mrvn> And custom blocks?
<malc_> things custom block point to, certainly
zarvok has joined #ocaml
<mrvn> But the block itself will move?
<malc_> it can
<malc_> and will
<mrvn> So putting a struct dlist { struct dlist *prev, next; ... } with prev pointing to itself would be bad.
<mrvn> +in there
<mrvn> thx
<malc_> if that's what you malloced on your own it'll be safe
<mrvn> malc_: More like v = caml_alloc_custom(&dlist_ops, sizeof(struct dlist), 0, 1);
<malc_> then no
<mrvn> struct dlist *p = (struct dlist *)Data_custom_val(v);
<mrvn> Is it recommended to put structs into a custom block (not a dlist obviosuly :) or should one always put a pointer to the struct in there?
<malc_> i'm in no position to specify what's recommended leave alone always
<mrvn> what would you do?
<malc_> i'd put a pointer
<mrvn> despite the extra malloc()?
<malc_> yes
<malc_> i'd also eat children on occasion, i.e. don't jump to conclusions based on this sampling
<mrvn> Ok :). Now for something completly different:
<mrvn> # class foo p = object val parent = p end;;
<mrvn> class foo : 'a -> object val parent : 'a end
<mrvn> # let rec my_foo = new foo my_foo;;
<mrvn> This kind of expression is not allowed as right-hand side of `let rec'
<mrvn> Any idea how to do something like this eficiently?
<malc_> rectypes again..
<malc_> i'd recommend reading last week worth of ocaml ml
<mrvn> ocaml -rectypes doesn#t help there.
<mrvn> The thread about 'How important are circular lists/recursive objects?'?
<malc_> 'polymorphic recursion'
<malc_> and with a class like this everyone has to have a parent, and you want the phony root be a parent of itself sorta kinda?
<mrvn> malc_: yes.
<malc_> evil
<mrvn> Saves me from having an "option".
eradman has quit [zelazny.freenode.net irc.freenode.net]
eradman has joined #ocaml
<mrvn> class ['a] foo (p : 'a foo) = object val parent = p method get_parent = parent end;;
<mrvn> let my_foo = new foo (Obj.magic 0);;
<mrvn> This works but now it is truely evil.
<mrvn> # let my_foo = new foo (Obj.magic 0);;
<mrvn> val my_foo : 'a foo = <obj>
<mrvn> # my_foo#get_parent#get_parent;;
<mrvn> zsh: segmentation fault ocaml -rectypes
<mrvn> hehe
<mrvn> Do you know if "val mutable p" takes more space than "val p"?
<malc_> no idea
<Smerdyakov> You're not guaranteed that either takes _any_ space... I would hope optimizations sometimes achieve that.
<mrvn> A mutable has type 'a ref so that would be a pointer to 'a then while without it is just 'a. Assuming it doesn't get optimized out.
johnnowak has joined #ocaml
<Smerdyakov> No, a mutable does not have type 'a ref.
<malc_> mutable member variables are not your 'a refs
<malc_> so again, i don't know
<tsuyoshi> mutables are unboxed by the compiler usually
<malc_> no they are not
<mrvn> at least the type system gives you errors like this: This expression has type 'a foo but is here used with type 'b ref
<malc_> except for floats
<tsuyoshi> malc: try it and see
<tsuyoshi> integers are unboxed too
<malc_> try what exactly
<mrvn> tsuyoshi: how would you try?
<mrvn> read the asm code?
<tsuyoshi> compile something with mutable integers and look at the assembly
<Smerdyakov> As always, I remind that, if you care about performance, you should be using SML instead of OCaml. :P
<malc_> let a = ref 0
<malc_> box$ ocamlopt -c -dcmm box.ml
<malc_> (data int 1024 global "camlBox" "camlBox": skip 4)
<malc_> (function camlBox__entry () (let a/57 (alloc 1024 1) (store "camlBox" a/57)) 1a)
bluestorm_ has joined #ocaml
<mrvn> class foo =
<mrvn> object
<mrvn> val mutable i = 0
<mrvn> method inc = i <- i + 1
<mrvn> method get = i
<mrvn> end
<mrvn> (data int 1024 "camlBar__6": addr L7 int 1276 L7: string "i" skip 6 byte 6)
<mrvn> (function camlBar__method_inc_93 (self-1/67: addr env/104: addr)
<mrvn> (store (+a (+a self-1/67 (<< (load (+a env/104 16)) 2)) -4)
<mrvn> (+ (load (+a (+a self-1/67 (<< (load (+a env/104 16)) 2)) -4)) 2))
<mrvn> 1a)
<mrvn> So is it boxed or unboxed?
<mrvn> "addr L7 int 1276" looks like a box to me.
<Smerdyakov> mrvn, what's that output code you're showing? Caml bytecode?
<mrvn> ocamlopt -c -dcmm output
<malc_> it's boxed
<mrvn> class foo = object val mutable i = 0 end
<mrvn> let _ = let foo = new foo in Gc.print_stat stdout;;
<malc_> only arrays and records of floats + strings + bigarrays are unboxed in ocaml
<mrvn> mutable has live_words: 93268, without live_words: 93295.
<mrvn> That didn't quite work out.
<mrvn> let _ = let foo = new foo in Gc.compact; Gc.print_stat stdout;;
<mrvn> That gives me 93228 vs 93220
<mrvn> Does that mean "val mutable i" uses up 8 more word (64 bytes) than "val i" in a class?
<Smerdyakov> mrvn, what are your reasons for choosing OCaml over SML if constant factor differences in space usage matter to you?
<mrvn> I like ocaml
<mrvn> And who is to say SML would do things differently?
<mrvn> Does SML even have classes?
<Smerdyakov> MLton is one of the best optimizing compilers for any language.
<Smerdyakov> No, SML doesn't have classes, but the representation issues here have more to do with records than class-specific anything.
<Smerdyakov> OCaml has no optimizing compiler.
<mrvn> I don't think you can optimize the pointer away anyway.
<mrvn> It would change the semantic.
<Smerdyakov> MLton does, because it can use whole-program analysis to determine when the program semantics will stay the same.
<Smerdyakov> ocamlopt doesn't even do _local_ program analysis.
<mrvn> Say you have a more complex case and you have a mutable list there. If anything else in the program gets a reference to that list and it gets changed in-place instead of changing the pointer then you change the other reference too.
<Smerdyakov> A concrete example, please?
vital304 has joined #ocaml
vital304 has left #ocaml []
<Smerdyakov> And you are arguing that that program can't be compiled to keep the list value inline in objects?
<mrvn> Anyone know of bindings for libaio? The Linux async I/O interface.
<mrvn> Smerdyakov: yes.
<mrvn> Smerdyakov: unless the foo#get copies the list
<mrvn> If you make val mutable l to be an abstract type then you get truely impossible.
<Smerdyakov> But 'get' would be returning the value of the list, not an address of that value.
<Smerdyakov> No matter how you represent the class.
<Smerdyakov> Where the value is probably going to be a word-sized pointer; either NULL for nil or a pointer to a two-element record for cons.
<mrvn> Smerdyakov: inlined it would be two elements that are either NULL or next+data.
<Smerdyakov> That's not how I think about list inlining.
<Smerdyakov> The case of ints is very different. There is a "base" representation of ints, and we add an extra box around it.
<Smerdyakov> Or for int32, for instance.
<jlouis> ... but not in MLton.
<Smerdyakov> I'm talking about ocamlopt, jlouis.
<jlouis> okie.
<mrvn> So inlined int would be just the taged value but a boxed int a pointer to it.
<Smerdyakov> In SML, there are no mutable fields, so these things are represented with refs.
<mrvn> But for list you have a pointer to the tupple and boxed list would be a pointer to a pointer to the tupple?
<Smerdyakov> The kind of inlining for a list that I described would occur in such an SML situation with MLton.
<Smerdyakov> I don't think lists are ever boxed.
<mrvn> What is the difference between list and list ref?
<Smerdyakov> You mean the difference between what they look like after ocamlopt gets through with them?
<mrvn> Are both just a pointer to the block?
<mrvn> Smerdyakov: yes, the bit patterns
<Smerdyakov> No, list ref is a pointer to a pointer; list is a pointer.
<mrvn> And val list and val mutable list?
<Smerdyakov> Whereas, in MLton, list ref will end up as just a pointer in most situations, thanks to whole-program analysis.
<Smerdyakov> I don't think adding the 'mutable' keyword changes anything about compilation strategy in OCaml.
<Smerdyakov> Sort of like C 'const' in that respect
<Smerdyakov> But reversed
<mrvn> So you would say there is a definite difference between val list = ref [] and val mutable list = [] then?
<mrvn> The ref having that extra indirection.
<Smerdyakov> Yes. You can pass the ref from the first case around as a first-class value. Not so about the field in the second case.
<mrvn> Thanks. That answeres my question. :)
<Smerdyakov> Why are you using classes?
<mrvn> syntactical suggar
<mrvn> Smerdyakov: Any idea to the initial question about classes:
<mrvn> # class ['a] foo p = object val parent = p end;;
<mrvn> class ['a] foo : 'b -> object val parent : 'b end
<mrvn> # let rec myfoo = new foo myfoo;;
<mrvn> This kind of expression is not allowed as right-hand side of `let rec'
<mrvn> Any idea how to implement this so that the root points to itself and all other classes to its parents?
<Smerdyakov> Ew. ;-)
<mrvn> Bets I come up with so far is: class ['a] foo p = object val parent = (p:'a option) method get_parent = match parent with None -> raise Not_found | Some p -> p end
<mrvn> Which I believe is wastefull of memory.
<mrvn> If you need an usage case then think of a filesystem. Every directory has . and ..
<mrvn> type dir = { parent : dir }
<mrvn> let rec root = { parent = root }
<mrvn> With records the whole thing is trivial.
<Smerdyakov> Sorry, I generally ignore OCaml's facilities for recursive definition of non-function values.
JeffSmac has joined #ocaml
<JeffSmac> is anyone here somewhat versed in labltk?
<mrvn> Smerdyakov: ok. other question.
<Smerdyakov> mrvn, meaning you are about to ask another, or that I've missed another you've already asked?
<mrvn> libaio has a function "int io_submit(io_context_t ctx, long nr, struct iocb *ios[]);". I wonder how I should interface that with ocaml.
<Smerdyakov> I also don't have any experience interfacing C and OCaml. It's sooo much nicer in SML. ;-)
<mrvn> I can pass an "iocb_t array", malloc the '*ios[]', copy the pointers, call io_submit, and free the ios.
<mrvn> But an iocb_t array wants to be initialized fully. I can't fill it up as I go along.
<mrvn> Or I could pass an iocb_t list. That is easy to build as one goes along.
<mrvn> But List.length isn't so cheap.
<jlouis> just store the length besides the list if that is a real concern to you. You are currently prematurely optimizing quite a heck of a lot
<Mr_Awesome> Smerdyakov: interfacing C is nicer in SML? i already thought it was nice in ocaml
<Smerdyakov> Mr_Awesome, MLton uses native C types, for instance. No marshalling.
<mrvn> jlouis: I'm too lazy to write List.length in C. :) Seed isn't the main concern (yet).
<Mr_Awesome> i really need to try out sml
<mrvn> Smerdyakov: how does the GC detect ints then?
<Smerdyakov> mrvn, the compiler outputs tables with that information.
<jlouis> mrvn, complete description of the types in tables
<mrvn> Doesn't that waste a lot of space?
<Smerdyakov> Doesn't boxing waste a lot of space?
<mrvn> The tag bit on ints waste little
<Smerdyakov> But int32 is boxed.
<mrvn> nah, I have a 64bit cpu. int is big enough. :)
<jlouis> so a 32bit integer fits in a 8-byte 64-bit pointer?
<mrvn> int is 63 bits. No need for int32.t
<jlouis> but well, it is not wasted in MLton. You only have one table per possible object type
<mrvn> I know what you mean but I just found little use for Int32.t.
<Smerdyakov> mrvn, also look at polymorphic functions that should work with all of ints, floats, and aggregate structures.
<mrvn> jlouis: does that mean all ints are allocated in one heap, all int lists in another, all float list in yet another?
<jlouis> mrvn, no. But you know *exactly* what an object looks like in the GC of MLton.
<jlouis> So you know what fields are pointers and thus you also know the type of the referred objects. A search along the pointers always knows the object type due to the table lookup
<jlouis> This compilation strategy is really only feasible in a whole-program-compiler though
<mrvn> Say you have type s = { a:int; b:int list; } let x = { a=1; b=[1;2;3];} let y = x.b
<jlouis> In OCaml, it is impossible because we do not generally know the layout of a type defined in another module
<mrvn> I get that the GC can know that x is of type s, but where does it get y from?
<Smerdyakov> mrvn, from the same type containing the type of x.
<Smerdyakov> er, from the same TABLE.
<jlouis> what Smerdyakov said ;)
<mrvn> And in memory y is a pointer to the TABLE and a pointer to x.b?
<jlouis> no
<mrvn> Then how do you know the TABLE to use?
<Smerdyakov> There is only one table.
<jlouis> There is a single table for s.
<Smerdyakov> It is indexed by program location and register/stack slot.
<mrvn> And that says what?
<Smerdyakov> Each entry tells you everything the GC needs to know about handling the value.
<mrvn> SO you have "register/stack slot -> type", say 2 words for each variable?
<Smerdyakov> Shouldn't need more than one word.
<Smerdyakov> Pointer to a type descriptor.
<mrvn> then how does it know which entry in the TABLE to use?
<Smerdyakov> Probably just a few bits, actually, representing a small enumeration like {int, float, pointer}.
<Smerdyakov> Please stop capitalizing table.
<mrvn> sorry, you started that.
<Smerdyakov> It's a common convention for indicating emphasis in text.
<Smerdyakov> I'm saying you need a few bits for the "value" part of the "key-value pairs" the table stores.
<Smerdyakov> You probably don't need any more, because there is an easy function for hashing a register/stack slot to a unique int.
<mrvn> All value addresses are word aligned so you might have enough bits left over in the key. Ok, so one word per binding.
<mrvn> Which would be exactly what ocaml has.
<Smerdyakov> All you really need is the set of pointer-typed live registers.
<Smerdyakov> Which can be much smaller than any structure proportional to all live temporaries.
<Smerdyakov> And I'm not talking about tagging; I'm talking about boxing for purposes of demonstrating the benefit.
JeffSmac has quit []
<Smerdyakov> As you get with every array of records in OCaml, for instance.
<mrvn> And then when you follow pointers in a Block you already know what type they have. Ahh, now I see how that can work.
<jlouis> is the basic layout
<mrvn> Can MLton have seperate compilation units?
<jlouis> mrvn, no
<jlouis> it is a whole-program-complier so it can't by definition
<jlouis> compiler*
<mrvn> That is a show stopper for me then.
<jlouis> actually, the basic idea of MLton is to do W-P-C. And that makes a *lot* of the compilation strategies much easier in an ML-like language
<jlouis> I suspect you will see MLton killing the competition for large project where inter-module optimizations begins to pay off big time
<mrvn> It is nice for the final product but wastes developement time.
<jlouis> how so? You can always do the initial development in, say SML/NJ, or another SML system with separate compilation
<mrvn> is it that compatible?
<jlouis> Quite close. I tend to just run mlton -stop tc and have it stop after TypeChecking and elaboration
<jlouis> This done on the MLton sources themselves (130k lines) takes about 10-15 secs on my machine. I can live with that.
<mrvn> jlouis: That url you pasted doesn't say anything about a global table.
<jlouis> indirectly it does. You only need to know where in an object the pointers are. Each object has a headerword with 19 index bits for indexing into an array (this array is the table) for satisfying the requirement
<mrvn> jlouis: which saves you from tagging pointers and non pointers. But that is still a box.
<mrvn> jlouis: I guess on 64bit cpus you have 64bit header and respectively can have bigger objects.
<jlouis> mrvn, I have not looked into Matthews 64-bit branch yet (it is not completely merged yet)
<mrvn> another show stopper.
<mrvn> An array length word is a twos-complemenet 32 bit Int.int storing the
<mrvn> array length, and hence always has a top bit of zero.
<mrvn> ^^^ So ints are tagged as well.
<mrvn> Or does it refer to the sign bit?
<jlouis> sign bit
<jlouis> negative array lengths are not that useful after all.
<mrvn> unsigned int could be.
<jlouis> not on a 32bit arch, I'd say.
<mrvn> jlouis: you can allocate 3.99GB in a 32bit process with a 64bit amd64 kernel.
<mrvn> 2-3.5GB with a 32bit kernel.
<mrvn> But it is probably less restrcitive than ocaml arrays and strings.
<mrvn> What is the limit for strings in 32bit? 16MB?
<jlouis> Strings are arrays to the GC, so I guess it is 2Gb
<jlouis> IIRC
<jlouis> (dunno about Ocaml though)
<mrvn> Big arrays are not limited in size, unlike Caml arrays (float array are limited to 2097151 elements on a 32-bit platform, other array types to 4194303 elements).
<mrvn> It is much less.
<mrvn> With 4 byte per word that is 16MB indeed.
love-pingoo has quit ["Connection reset by pear"]
<mrvn> anyone here using (or having used) ocamlfuse?
<mrvn> Another day, another problem solved.
bluestorm_ has quit [Remote closed the connection]
mbishop has joined #ocaml
malc_ has quit ["leaving"]
_JusSx__ has quit ["leaving"]
smimou has quit ["bli"]