thrasibule has quit [Quit: No Ping reply in 180 seconds.]
thrasibule has joined #ocaml
<quidnunc>
I have a source hierarchy with several subdirectories. I want to use some of the modules define therein interactively at the top-level. Can someone tell me how to do that? I have tried using the #directory directive with no luck. I am new to Ocaml and am using tuareg.
elehack has quit [Ping timeout: 265 seconds]
elehack has joined #ocaml
mbishop has quit [Quit: Lost terminal]
enthymene has quit [Quit: brb, router hop.]
elehack has quit [Quit: Goodbye...]
mbishop has joined #ocaml
mjonsson has quit [Read error: Connection reset by peer]
maskd has quit [Quit: leaving]
mrvn has quit [Ping timeout: 245 seconds]
elehack has joined #ocaml
mrvn has joined #ocaml
mjonsson has joined #ocaml
quidnunc has quit [Remote host closed the connection]
elehack has quit [Quit: Goodbye...]
caligula_ has joined #ocaml
caligula__ has quit [Ping timeout: 256 seconds]
thrasibule has quit [Ping timeout: 246 seconds]
thrasibule has joined #ocaml
thrasibule has quit [Ping timeout: 240 seconds]
thrasibule has joined #ocaml
seafood has joined #ocaml
Drk-Sd has quit [Quit: {'EXIT', Drk-Sd, "bye"}]
seafood has quit [Client Quit]
seafood has joined #ocaml
enthymene has joined #ocaml
pad has quit [Remote host closed the connection]
thrasibule has quit [Quit: No Ping reply in 180 seconds.]
thrasibule has joined #ocaml
thrasibule has quit [Quit: No Ping reply in 180 seconds.]
thrasibule has joined #ocaml
thrasibule has quit [Quit: No Ping reply in 180 seconds.]
thrasibule has joined #ocaml
thrasibule has quit [Client Quit]
thrasibule has joined #ocaml
thrasibule has quit [Quit: No Ping reply in 180 seconds.]
thrasibule has joined #ocaml
thrasibule has quit [Quit: No Ping reply in 180 seconds.]
threeve has quit [Quit: threeve]
yziquel has quit [Ping timeout: 252 seconds]
seafood has quit [Quit: seafood]
ulfdoz has joined #ocaml
seafood has joined #ocaml
yakischloba has quit [Quit: Leaving.]
Modius_ has joined #ocaml
boscop has quit [Read error: Connection reset by peer]
Modius has quit [Ping timeout: 252 seconds]
ttamttam has joined #ocaml
ulfdoz has quit [Ping timeout: 245 seconds]
enthymene has quit [Quit: *thud*]
naufraghi has joined #ocaml
ttamttam has quit [Quit: Leaving.]
Yoric has joined #ocaml
<Yoric>
hi
valross has quit [Remote host closed the connection]
ikaros has joined #ocaml
domiel has joined #ocaml
joewilliams is now known as joewilliams_away
ttamttam has joined #ocaml
<domiel>
Hi all! I haven't touch ML in a number of years and I've just started dabbling again. Whilst doing some googl'ing I've noticed a lot of talk about MLton. I've gained the impression that it has managed to oust Ocaml as the Functional/Declarative performance king. Would anyone here care to comment? (Please note this is not intended as a troll or flamebate I'm just interested in your comments)
Yoric has quit [Quit: Yoric]
<Camarade_Tux>
I don't have the time to really elaborate but while mlton may provide better performance, it takes ages to compile
<domiel>
ok... that's not so much of an issue for me... but I guess my next question is: is there any nice paper available that compares the compilation techniques?
<domiel>
I'm kind of curious as to how they've managed it
<flux>
domiel, mlton does whole-program-compiling, so it gets the permission to do more kinds of interesting optimizations. on the other hand ocaml's native code performance is mostly based of a solid code generator, it doesn't really perform interesting optimizations at all
<flux>
of a -> on a
<domiel>
flux: so to your knowledge have the MLton guys built upon what the Caml guys have done... or have they struck out in a different direction entirely
<flux>
domiel, they've gone in a different direction I'd say. btw, I don't think their code itself has anything to do with ocaml's code. also note that my mlton knowledge is extremely limited :)
<domiel>
flux: hey no problems this is a caml list afterall... I'm just assuming that since they are both ML dialects that there would be plenty of scope to borrow implementation techniques if required
Submarine has quit [Quit: Leaving]
gorgonite has left #ocaml []
_zack has joined #ocaml
_zack has quit [Client Quit]
_zack has joined #ocaml
ikaros has quit [Quit: Leave the magic to Houdini]
f[x] has quit [Ping timeout: 268 seconds]
f[x] has joined #ocaml
Yoric has joined #ocaml
_zack has quit [Quit: Leaving.]
_zack1 has joined #ocaml
dark has quit [Remote host closed the connection]
gim has quit [Ping timeout: 248 seconds]
sfuentes has quit [Ping timeout: 260 seconds]
sfuentes has joined #ocaml
Alpounet has joined #ocaml
gim has joined #ocaml
Tianon has quit [Ping timeout: 246 seconds]
jao has joined #ocaml
naufraghi has quit [Quit: naufraghi]
maskd has joined #ocaml
naufraghi has joined #ocaml
naufraghi has quit [Client Quit]
naufraghi has joined #ocaml
pimmhogeling has joined #ocaml
domiel has quit [Quit: Ex-Chat]
avsm has joined #ocaml
pimmhogeling has quit [Ping timeout: 256 seconds]
fraggle_ has quit [Ping timeout: 256 seconds]
fraggle_ has joined #ocaml
_andre has joined #ocaml
TaXules has quit [Remote host closed the connection]
robocop has joined #ocaml
avsm has quit [Read error: Connection reset by peer]
avsm has joined #ocaml
seafood has quit [Quit: seafood]
Drk-Sd has joined #ocaml
robocop has quit [Ping timeout: 265 seconds]
avsm has quit [Quit: Leaving.]
robocop has joined #ocaml
derdon has joined #ocaml
f[x] has quit [Ping timeout: 268 seconds]
f[x] has joined #ocaml
avsm has joined #ocaml
mellum has joined #ocaml
<mellum>
Hi. Any ideas how to write a function that returns true iff some predicate is true for all elements of an array, and that the ocaml compiler compiles with tail recursion?
<mellum>
I tried the obvious way let array_for_all p a = let rec loop i = i >= Array.length a || (p a.(i) && loop (i + 1)) in loop 0, but this generates terribly inefficient code
<mellum>
even though it looks to me that the compiler should be able to eliminate tail recursion
<thelema>
mellum: Array.for_all?
<mellum>
thelema: I don't have that in my version
<mrvn>
mellum: let array_for_all p a = let rec loop i = if i >= Array.length a then true else if p a.(i) then loop (i+1) else false ?
<mfp>
for i = 0 to Array.length a should be ... to Array.length a - 1
<mrvn>
yeah, saw that too
_unK has joined #ocaml
<mellum>
Hmm. If I look closely, the only place I really use it is with let is_zero = array_for_all (fun x -> x = 0);;
<mrvn>
mellum: Is p always the same or one of a few functions? maybe just write a C stub.
<mellum>
I suppose if I just code that manually, it should be faster, since inlining also diesn;'t seem to take place
<mfp>
mellum: HOFs are not inlined
<mfp>
(that is, functional params of HOFs aren't)
<mellum>
mfp: a pity, that would often be quite advantageous
<mrvn>
HOFs?
<mfp>
higher-order functions
<thelema>
mellum: that real test does convnce me.
<thelema>
inlining HOFs would require something quite close to full program optimization, as the codegen wouldn't be able to work with just local information
<mfp>
it's not very different from regular inlining I think, at least for full applications
<mrvn>
thelema: How it HOF different from using a binding?
<orbitz>
mrvn: what do you mean?
<mrvn>
Not my day. :)
<mrvn>
orbitz: thats the second bug I pasted in the last 10 minutes :)
<mellum>
heh. acually the gain is much smaller than I quantified before, there's something strange going on with my timing
<mrvn>
mellum: I would write a C stub for this. value is_zero(value ml_array) { value *p = &Field(a, 0); value *end = p + <size_of_block>; while (p < end) { if (*p != (Val_int 0)) return <false>; ++p; } return <true>; }
<mrvn>
and external is_zero : int array -> bool = "is_zero" "no_alloc"
mutew has joined #ocaml
<mellum>
well, that seems like a bit of overkill, I think the imperative ocaml version is OK for now...
<mrvn>
mellum: is it any better than the funtional one?
<thelema>
mrvn: with HOF, you don't know what function you'll be calling, so you have to wait until you have a lot more of the program in one place to build the inlined version. With regular inlining, you know what function you're inlining, and it's already defined when you are doing codegen for the later function
<mrvn>
thelema: I inlined that
<mrvn>
nm
<mrvn>
thelema: At some place the outer function is inlined. At that palce you often know the HOF that is passed as argument.
<mrvn>
thelema: as in array_for_all (fun x -> x = 0) ...
<mfp>
thelema: it's quite easy if you expand the HOF at the call site of a full application
<thelema>
which requires codegen for a function that's not being declared. Possible, but much more bookkeeping
<mfp>
it's not diff from regular inlining
<thelema>
requires 2-level inlining
<mrvn>
But a rather common case I would think.
<mfp>
the HOF body would be in the cmx
<thelema>
let val = hof f x
<mfp>
thelema: not if the functional params are known functions
<mfp>
if f is known, that poses no pb
<mrvn>
mfp: Your paste output is almost beautiful.
<thelema>
requires being able to codegen hof at this point (one level of inlining) with f inserted into its definition (second level of inlining)
<mrvn>
thelema: inlining should go by size and not by level.
<mfp>
hof's body is extracted from the cmx, and the param replaced with f
<mfp>
if f is a known function, it'll be inlined using the normal procedure
<thelema>
yes, which requires being able to do function parameter replacement from the inlining version of a function
<mfp>
if it's not, expanding the HOF was pointless
<mrvn>
mfp: saves a function call
<mrvn>
By inlining the HOF and doing parameter replacement I bet often you can reduce a polymorphic function to a specific one. That makes a huge difference.
<mfp>
thelema: you are talking as if that were hard --- it's just pattern matching over the expression tree
<thelema>
if you marshal the AST of [hof], then you can do this. If your inlining representation isn't the ast...
<mfp>
the real pb with HOF inlining is deciding when to inline and when not to
<mellum>
well, if it is "fun x -> x = 0", I'd say "do it".
<mfp>
I don't know which of the several IRs is being used in the .cmx, but keeping a high-level one would be easy
<mfp>
mellum: it depends on how often the functional param is used
<mrvn>
mfp: It is shorter than the function call.
<mfp>
expanding the HOF could kill perf even if the functional arg is as simple as ((=) 0)
<mellum>
mfp: when for example?
<mfp>
mrvn: but the whole HOF with the inlined (fun x -> x = 0) will probably be larger than the funcall with ((=) 0) as a param
<mrvn>
mfp: But that is already decided when you inline the HOF or not.
<mfp>
... which is the pb I was referring to
<mfp>
ah
<mrvn>
mfp: Oh, I was thinking of when to do parameter replacement.
<mfp>
I was not referring to whether to expand the functional param,
<mfp>
but rather about the HOF itself
<mrvn>
I don't see that being any different from normal functions being inlined.
<mrvn>
One thing I miss in ocaml is what C++ has a template specialization.
<mrvn>
Say you have the polymorphic array_for_all from above. Would be nice if you could tell the compiler to also build a specialized version for int array.
<mfp>
mellum: code explosion blowing your cache
<mfp>
ad-hoc polymorphism :-|
<thelema>
building all the possibilities explodes code size
<thelema>
building only the used possibilities require WPO
<mrvn>
thelema: telling the compiler what to build just takes brains.
<mfp>
thelema: mrvn's talking about manual specialization, though
<mrvn>
And the code should be able to differ.
<thelema>
yup, manual annotations => build it yourself
<mrvn>
Whit the special gimmick that the use is automatic.
<thelema>
but I guess the compiler can build it safer
<mrvn>
thelema: Not if the code differs.
<mrvn>
E.g. Hashtbl. Generic types need to be hashed. unit, char, bool, int can be used as is.
<mrvn>
int32/int64 can be unboxed and used.
<mrvn>
You could also define ( + ) : 'a -> 'a -> 'a [int -> int -> int, float -> float -> float]
<thelema>
yay, another new error message for me from the compiler. "Error: This function is applied to arguments in an order different from other calls. This is only allowed when the real type is known."
<thelema>
I take this as a sign I'm exploring more of the design space of ocaml programs than before
yakischloba has quit [Quit: Leaving.]
<mehdid>
mrvn: really from the C side, or is Dynlink.is_native enough for your needs?
<mrvn>
I need that in ocaml.
<mehdid>
Dynlink.is_native, Sys.word_size
<mrvn>
mehdid: type int31 = if Dynlink.is_native then if Sys.word_size = 32 then Int32.t else int else int
<mrvn>
s/32/64/ for the first one
ccasin has joined #ocaml
<mrvn>
mehdid: I want a fast 4 byte interger in a BigArray.
rwmjones has quit [Read error: Operation timed out]
rwmjones has joined #ocaml
f[x] has quit [Ping timeout: 248 seconds]
f[x] has joined #ocaml
<thelema>
mrvn: Bigarray.int32_elt?
<mrvn>
thelema: slow as it always boxes.
<mrvn>
Binary code on 32bit cpu can use int instead. On 64bit it must use int32_elt, have Bigarray allocate one and use Int32.to_int on it.
<thelema>
hmm, I wonder if one could make a new bigarray kind...
<mrvn>
thelema: patch is in the ocaml BTS.
<mrvn>
thelema: The patch even makes it use inlined asm to access int31_elt.
<thelema>
bug 4909.. hmmm
<thelema>
at least they've acknowledged it
<mrvn>
I'm using OCamlMakefile to build something that uses libaio-ocaml and I'm getting "Error: Unbound type constructor Aio.Buffer.t". What do I need to add so it adds the right -I ... entry?
<thelema>
sorry, I don't know OCamlMakefile
<mrvn>
Anything better that is simple to use?
ulfdoz has joined #ocaml
* thelema
uses ocamlbuild when he can
<mrvn>
INCDIRS := $(shell ocamlc -where)/aio
f[x] has quit [Ping timeout: 268 seconds]
<mrvn>
works. But that doesn't look right.
<_andre>
mrvn: did you try "PACKS = aio"?
f[x] has joined #ocaml
<mrvn>
Error: Cannot find file aio.cma
<mrvn>
But that can be a packaging error on my side.
<mrvn>
_andre: thx.
<_andre>
is "aio" the pkg name reported by ocamlfind list?
ikaros_ has quit [Quit: Leave the magic to Houdini]
pimmhogeling has quit [Ping timeout: 240 seconds]
<mrvn>
yes
ikaros has joined #ocaml
<mrvn>
I have /usr/lib/ocaml/aio/aio.cma. Why isn't it finding that now?
<_andre>
what's the search path reported by "ocamlfind printconf"?
<mrvn>
/usr/lib/ocaml
<_andre>
maybe something's wrong in findlib.conf or ocaml/ld.conf?
<mfp>
mrvn: INCDIRS := $(shell ocamlfind query -i-format aio) should be quite safe...
rwmjones has quit [Read error: Network is unreachable]
<mfp>
oh you don't want -I
<mrvn>
mfp: I want it to work as simple as possible.
<mfp>
then ocamlfind query -format %d aio
<mrvn>
/usr/lib/ocaml/aio
<mfp>
if you were using omake, it'd be OCAMLPACKS[] += aio
<mfp>
does /usr/lib/ocaml/aio/aio.cmi exist?
<mrvn>
Ahh, PACKS collides with LIBS.
<mrvn>
If I remove "LIBS := aio" and only keep "PACKS = aio" then it works.
Submarine has joined #ocaml
<mrvn>
Thanks for all your help.
tmaedaZ is now known as tmaeda
yakischloba has joined #ocaml
<thelema>
:( Batteries' (//) doesn't have the right priority to use it to replace [ |> Enum.filter ] in a processing chain.
f[x] has quit [Ping timeout: 260 seconds]
f[x] has joined #ocaml
f[x] has quit [Ping timeout: 240 seconds]
f[x] has joined #ocaml
mutew has joined #ocaml
enthymene has joined #ocaml
bzzbzz has joined #ocaml
naufraghi has quit [Quit: naufraghi]
tmaeda is now known as tmaedaZ
ttamttam has joined #ocaml
mutew has quit [Ping timeout: 265 seconds]
Submarine has quit [Remote host closed the connection]
rwmjones has joined #ocaml
<mrvn>
I'm building libfuse bindings. I'm thinking of having multiple interfaces. One with simple strings and one with Aio.Buffer.t that doesn't copy data into strings and back. If I create a Fuse.String and Fuse.Aio submodule and the user uses Fuse.String would he still need to link against Aio?
Submarine has joined #ocaml
<flux>
afaik yes
<flux>
if you arranged it to be Fuse_String and Fuse_Aio, the user would not need to do that
* thelema
concurrs with flux
<flux>
of course, findlib removes the need to manually add the lib
<mrvn>
Sure, but I want the binary not to be linked with it needlessly.
<thelema>
then you're stuck not using submodules
<mrvn>
I want namespaces
<flux>
you have the source :)
<thelema>
what's the difference between Fuse.String and Fuse_string?
<flux>
I guess batteries would be happy with namespaces as well
<flux>
actually, the problem might resolve itself
<flux>
hasn't there been some talk about making packing not link unneeded code?
<mrvn>
thelema: Fuse_string would be a toplevel modules that is completly independent from Fuse_aio
<thelema>
mrvn: which is what you need to avoid Fuse_aio's dependencies polluting Fuse_string.
<thelema>
flux: packing? I thought it was just a linking optimization...
<mrvn>
thelema: The idea would be to pack Fuse.String and Fuse.Aio together and during linking it then sees that Aio isn't used and drops it.
pimmhogeling has joined #ocaml
ttamttam has quit [Quit: Leaving.]
<flux>
mrvn, well, that doesn't happen at the moment, so for the time being you better go with the fullly separate module-approach :)
<thelema>
aio might have side-effects that are needed for correct execution - thus it's always included.
<mrvn>
thelema: That would be truely evil for a module.
<thelema>
mrvn: not at all. lablgtk2 has GtkInit that takes care of various initialization just by linking it in
<mrvn>
at least for a public one.
<mrvn>
thelema: But if youdon't use Gtk then then libgtk wouldn't be linked in either. No init needed.
<thelema>
batteries auto-flushes and closes all opened channels, which requires at_exit hooks to get created automatically
<mrvn>
thelema: I think that is a bug of Unix.file_descr.
<mrvn>
and channels
<flux>
what is?
<thelema>
You might want to control exactly when the GTK initialization happens, so it's also important for this to not be automatic.
<mrvn>
That they don't have a finalizer
<flux>
finalizers aren't even guaranteed to be run
<flux>
nor is it known when they are run
<thelema>
finalizers aren't guaranteed to be run on program exit.
<mrvn>
Which is a bug in the GC I believe. At exit all finalizers should be run where possible.
<flux>
gc isn't really suitable for generic resource management
<thelema>
but batteries channels *do* have finalizers that flush and close.
<flux>
gc is for managing memory
<mrvn>
As to when that is not really a problem. If you want to know when a file is closed call Unix.close. If you forget the finalizer should close it.
<flux>
for a = 0 to 2000 do function_that_opens_a_file_handle_and_registers_a_finalizer_do_it (); done -> dies because you run out of fds
<mrvn>
In Aio I have a finalizer that writes a warning to stderr if a resource wasn't freeed properly and then frees it.
<flux>
that's a good way of using finalizer
<mrvn>
With Unix.file_descr you open a file, write to it and return. Voila, you are leaking FDs.
<flux>
yes. it's a bug in your code :)
<mrvn>
detectable by the GC
<flux>
it would be nice indeed. but adding it would possibly break some code that uses C-extensions with Unix.file_descr.
<mrvn>
flux: Currently it is an int. It would need to be a custom block then.
<mrvn>
Every C code using Unix.file_descr would break.
<flux>
if such a change would be introduced, it would happen in two steps: first provide a macro or function for properly accessing the value, then introduce the change
<mrvn>
/usr/include/caml/unixsupport.h does not have any macro to access Unix.file_descr. Strictly speaking every C stub using one is using internal types of the Unix modul.
<mrvn>
I wish the C interface of ocaml where more complete.
<flux>
definitely
<mrvn>
flux: One problem with the change though is that now something opening a file can be "noalloc". With a custom block it can't.
<flux>
who would open a file in a noalloc function?
<flux>
it's going to take probably hundreds of cycles anyway
<mrvn>
People do crazy things
<flux>
I like to believe that in o'caml they don't that a lot :)
<flux>
s/that/do &/
<mrvn>
less than in other languages. :)
<flux>
in anycase, "noalloc" is a performance hack and I think it's not even documented..
<mrvn>
flux: another one of those missing things in the docs.
<mrvn>
Makes a huge difference though if you just access a member of a C struct or C++ class.
<flux>
less of a difference when you actually do something in the function..
<mrvn>
sure. I was talking about C one liners.
<mrvn>
Should I have Fuse_common, Fuse_string and Fuse_aio?
_unK is now known as drunK
<mrvn>
Or maybe I just make Fuse_aio depend on Fuse_string and override the few things that differ.
rwmjones has quit [Ping timeout: 240 seconds]
drunK is now known as _unK
f[x] has quit [Ping timeout: 248 seconds]
f[x] has joined #ocaml
pimmhogeling has quit [Ping timeout: 240 seconds]
rwmjones has joined #ocaml
pimmhogeling has joined #ocaml
<derdon>
which is the usual method of analysing *.ml files?
<derdon>
I want to get the AST of a given *.ml file to find all functions, comments, etc.
<thelema>
there's a -dlambda argument to the compiler that'll give you one intermediate representation