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);
<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>
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>
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]