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/
Gerkin has joined #ocaml
kinners has quit [Remote closed the connection]
Gerkin has quit [Remote closed the connection]
kinners has joined #ocaml
Gerkin has joined #ocaml
Gerkin has quit [Remote closed the connection]
<mrvn> kinners: no, never heard of it
<Nutssh> Nothing wrong with seperate files.
<kinners> mrvn: it's 'apt-cache search' on steroids
CosmicRay has quit [Read error: 113 (No route to host)]
hilbert has joined #ocaml
mrsolo has joined #ocaml
mrsolo has quit [Read error: 104 (Connection reset by peer)]
mrsolo_ has joined #ocaml
ianxek has quit [Remote closed the connection]
vezenchio has quit ["None of you understand. I'm not locked up in here with you. YOU are locked up in here with ME!"]
segphault has joined #ocaml
hilbert has quit ["hello"]
kinners has quit ["leaving"]
segphault has left #ocaml []
mrsolo_ has quit [Read error: 113 (No route to host)]
mrsolo_ has joined #ocaml
segphault has joined #ocaml
budjet has joined #ocaml
Submarine has joined #ocaml
gpciceri has joined #ocaml
rossberg has quit [Read error: 110 (Connection timed out)]
budjet has quit [Read error: 238 (Connection timed out)]
Demitar has quit ["Bubbles..."]
segphault has left #ocaml []
grirgz has joined #ocaml
<grirgz> hi
gpciceri has quit ["Ciao, sono un virus dei messaggi di quit. Sostituisci la tua vecchia linea di quit con questa cosi potro continuare a moltipl]
Submarine has quit [niven.freenode.net irc.freenode.net]
Lemmih has quit [niven.freenode.net irc.freenode.net]
Hipo has quit [niven.freenode.net irc.freenode.net]
tewk has quit [niven.freenode.net irc.freenode.net]
shammah has quit [niven.freenode.net irc.freenode.net]
creichen has quit [niven.freenode.net irc.freenode.net]
Hipo has joined #ocaml
tewk has joined #ocaml
creichen has joined #ocaml
<grirgz> where can i find some documentation about compiling ? this is not very easy to find what option to put when using somes libraries..
<Nutssh> The documentation for ocamlc/ocamlopt is very readible.
rossberg has joined #ocaml
<grirgz> in fact i would something a litle automated..
<grirgz> i tryed ocamlmakefile, ocamlfind, ocamake, but none work (or i dont know how to make it work)
* Nutssh just uses normal make 'ocamlc blah.ml blah.ml blah.ml' Its fast enough complicated build systems aren't needed.
Submarine has joined #ocaml
Lemmih has joined #ocaml
shammah has joined #ocaml
<grirgz> i am using libpxp, and this lib need a lot a file, cma, cmo, etc, i dont know what are theses files or how to find their names, it's not well documented
<Nutssh> Usually to use a library, just add the foo.cma/foo.cmxa. I've not done much with libraries.
<grirgz> just a part of a command line : usr/lib/ocaml/3.08/netstring/netaccel.cma /usr/lib/ocaml/3.08/netstring/netaccel_link.cmo /usr/lib/ocaml/3.08/netstring/compatcgi.cma /usr/lib/ocaml/3.08/pxp-engine/pxp_engine.cma /usr/lib/ocaml/3.08/pxp-lex-iso88591/pxp_lex_iso88591.cma /usr/lib/ocaml/3.08/pxp-lex-iso88591/pxp_lex_link_iso88591.cmo /usr/lib/ocaml/3.08/wlexing/wlexing.cma
<grirgz> this is ocamlfind who have generated this
<Nutssh> I don't know ocamlfind.
<grirgz> but this work sometime, sometime not
<grirgz> you see this lib need a lot a file.. in fact i am totally lost :,(
<Nutssh> Dunno.
mrsolo_ has quit [Read error: 113 (No route to host)]
mrsolo_ has joined #ocaml
Nutssh has left #ocaml []
mrvn_ has joined #ocaml
Kevin has joined #ocaml
ianxek has joined #ocaml
velco has joined #ocaml
mrvn has quit [Read error: 110 (Connection timed out)]
rossberg has quit [niven.freenode.net irc.freenode.net]
pango_ has quit [niven.freenode.net irc.freenode.net]
rossberg has joined #ocaml
pango_ has joined #ocaml
Submarine has quit [Remote closed the connection]
Kevin has quit [Nick collision from services.]
Kevin_ has joined #ocaml
Herrchen has joined #ocaml
Kevin_ has quit ["Quit"]
Submarine has joined #ocaml
hilbert has joined #ocaml
hilbert is now known as monochrom
<vincenz> one sad thing about make is that it remakes everything
<Smerdyakov> No..
<Submarine> .cmx files, due to inlining, have dependencies between them
<Submarine> this makes Make naturally recompile more stuff than would be the case for C programs
Herrchen has quit ["bye"]
Godeke has joined #ocaml
<grirgz> does someone use libpxp ?
<mrvn_> Submarine: cmx file have inlined code from other ml files?
<Submarine> mrvn_, ocamlopt can load .cmx files from other modules to inline code from them, afaik
<mrvn_> Doesn't that break with circular depends?
<Submarine> ah ah ah
<mrvn_> Submarine: Does the automatic depends finder list the depends between *.cmx due to inlining?
<Submarine> indeed
<mrvn_> Are you sure it adds a depend on the cmx and not the cmi?
<Submarine> it seems to use both
<mrvn_> That should create circular depends in the makefile all over the place and relay confuse and break make.
velco has quit ["Client exiting"]
<vincenz> For profiling does one have to compile all the .cmx with OCAMLOPT -p
<vincenz> or just during linking?
<Submarine> yes you have and it incurs a performance penalty
<vincenz> logically :)
<Submarine> I recommend you instead use oprofile
<vincenz> ?
<vincenz> that being?
<Submarine> ocamlopt -p + gprof incurs performance penalties (though it might be possible to use gprof without -p)
<Submarine> oprofile.sourceforge.net
<vincenz> too much hassle
<Submarine> talking about this I'm tempted to optimize wrt cache size
<vincenz> you wrot eit?
<vincenz> e/e
<vincenz> s/ e/e /
<Smerdyakov> ee ee eee e eee ee
<Submarine> vincenz, I'm tempted to plot performance with respect to minor heap size on various archs, on a benchmark, and thus to deduce optimal settings with respect to L2 cache size.
<Submarine> we spend maybe 25% of our time in the GC
<vincenz> Submarine: I'd go for L1-cache
<Submarine> on 11 hours of computation it makes a lot
<vincenz> L2-caches are huge
<Submarine> vincenz, L1 cache tends to be around 8k, that's far too small
<vincenz> Submarine: and L2-caches tend to be 1-2MB
<Submarine> 2mbytes? what kind of luxury box do you have?
<vincenz> besides, L1-cache is definitely more than 8k
<vincenz> Submarine: P4 has 1MB, P4m 2Mb
<Submarine> on an Athlon, L2 cache is typically 256 Mbytes
<vincenz> Mbytes?
* vincenz coughs
<Submarine> kbytes sorry
<Submarine> on an Opteron, typically 1 M
<vincenz> 8k for l1 cache seems very slim
<vincenz> Submarine: well P4 has 1Mb, P4m 2Mb
<Submarine> is there a way to get Linux to show L1 cache size?
<vincenz> no idea
<vincenz> cpuinfo
<vincenz> only shows L2 tho
* vincenz read too late you wanted l1
<Submarine> Pentium4 CPUs have 8K L1 and 512K L2. Newer versions have 1MB L2.
<vincenz> Submarine: but to give you an idea, typical embedded systems already have 8k, or more
<Submarine> AMD Athlon CPUs have 128K L1 and 512K L2. Newer 64bit version have 1MB L2.
<Submarine> There are also some CPUs that have L3 cache, like Pentium 4 Extreme Edition with 2MB L3 cache. L3 cache is slower than L2 cache.
<vincenz> 8k L! is TINY
<Submarine> Also, the Athlon has an "additive" cache - basically, anything in the L1 cache is NOT kept in the L2 cache
<vincenz> most embedded systems have 8-32k
<vincenz> (newer)
<Submarine> vincenz, it's big enough to keep your current procedure running
<vincenz> Submarine: seems innefficient
<Submarine> and the top of the stack
<vincenz> Submarine: yes but we have some techniques for cache...
<Submarine> most embedded systems don't run at the same speeds as a P4
<vincenz> true
<vincenz> so you'd expect p4 to have more l1
<vincenz> cause it can blow as much power as it wants
<Submarine> no, because memory at that kind of speed is expensive
<vincenz> meh, 8k is really a bottleneck imho
<vincenz> besides...
<vincenz> I think it's 2*8k
<vincenz> they have in and data separate iirc
<vincenz> inst
<Submarine> yeah, it's dual I/D caching
<vincenz> too bad they don't have scratchpads
<vincenz> that'd be neat
<Submarine> so, see, I was not mistaken: on some common architectures, L1 cache is tiny
<Submarine> so I have to plan heap sizes for L2 cache
* vincenz nods
<vincenz> yes but try to map often-reused variables to L1
<vincenz> though that's most likely automatic
<vincenz> also try laying out your data so that amiss will get you a lot of usable data
<vincenz> does the P4 system use write-through or dirty-cache-marking?
<Submarine> it's written in OCaml
<Submarine> I can't choose where data is laid out.
<vincenz> I thought you were talki ng about modding the gc
<Submarine> no, just setting GC parameters
<vincenz> ah
<vincenz> k
<Submarine> modding the GC is scarier
<Submarine> maybe it could be possible to add prefetching instructions, but...
* vincenz nods
<Submarine> I think Xavier already did so for the powerpc
<Submarine> something like flushing the cache or so
<vincenz> hmm
<vincenz> do you know what hyper-threading is?
<Submarine> I think it's something like: when the minor heap is collected, just flush the cache or something like that, because you no longer care about the data that was there
<Submarine> vincenz, yes, a bit
<vincenz> could you explain it?
<vincenz> I haven't been uptodate with latest chip-techniques
<Submarine> well, as far as I understand, it's SMP inside a chip
<Submarine> but you share resources between the two parallel threads
<Submarine> under Linux, you definitely want a 2.6 kernel
<vincenz> hmm
<vincenz> seems like a lot of hoohah that will nto be used effectively
<vincenz> so you s hare resources you need apps that are built for such things, no?
<Submarine> no
monochrom has quit ["hello"]
<Submarine> but you incur performances penalties
<Submarine> you can run any two programs in parallel afaik
<vincenz> yes but what's the use of sharing resources then?
<Submarine> well, you share the same cache, etc...
<vincenz> it's like P4's pipeline, 40some stages and it says very highperformance but for typical apps you only use like 10-20%
<vincenz> Submarine: so basically one app can screw your other app's cache
<Submarine> I think so.
<Submarine> that's why it's better for *threads*
<vincenz> I know
<vincenz> but that requires apps to use threads
<Submarine> but Caml sucks at threads
<vincenz> well you've got the GC :)
<vincenz> how does caml suck at threads?
<Submarine> the memory manager has a big mutex on the heap
<vincenz> oh, ouch
<Submarine> in short, your Caml code only runs on one simultaneous processor
<Submarine> you *can* get multiprocessor if you're inside C functions
<vincenz> euhm
<vincenz> the mutex is for allocating/deleting no?
<Submarine> I think so.
<Submarine> look, knowing that, I never seriously wondered about making multithreaded OCaml code
<Submarine> I just use fork()
<vincenz> meh
<Submarine> meh?
<vincenz> doesn't that still use the same heap?
<Submarine> fork() does a lazy cloning of memory
<Submarine> both processes live in separate memory spaces
<vincenz> yick
<vincenz> why not just use threads and hope taht they'll fix the memorymanager
<Submarine> hopefully Smerdyakov is not listening about all those horrors
<Submarine> vincenz, because we want performance right now
<vincenz> though, memorymanager is always an issue, hence my research, I know someone who's going to do research in memory-managers for mp
<Submarine> vincenz, Damien Doligez did some
<vincenz> we have a whole library to design optimized memory-managers, though right now concurrency is not taken care of yet,
<Submarine> who do you work for, if it's not indiscreet.
<vincenz> www.imec.be
<vincenz> it wasn't my researhc tho, i'm gonna work on something different
<vincenz> we do target multimedia/network apps for embedded systems
<Submarine> aaah I think I once saw a paper submitted from IMEC
<vincenz> what conference?
<Submarine> VMCAI?
<vincenz> our latest paper was at SIPS2004
<vincenz> not sure, I wasn't aruond before that
<vincenz> like I said, I started in april and helpded with DMM but am gonna work on sometihng different
<vincenz> let me check
<Submarine> I do too work with embedded system, but it's avionics... Fly by wire, that sort of stuff.
<vincenz> nope sorry
pango has joined #ocaml
<vincenz> Nope, don't think they were at VMCAI
<Submarine> it's just that a workmate of mine talked about some Belgian center he did not know about, then told me it was apparently some kind of inter-university center for embedded apps
<vincenz> yup
<vincenz> well inter-universitary center for electronics
<vincenz> biggest in europe
<vincenz> they just gota 45nm fabline
* Submarine really knows little about hardware
<Submarine> would you happen to know Christian Eisenbeis or Marc Duranton?
<vincenz> well we also do methodology research, that's where I'm at
<vincenz> I'm afraid not, but imec has 1500 people
<Submarine> i'm talking of French people working in compilation for embedded videoprocessors :-)
<vincenz> oh
<vincenz> no I'm afraid nto
<Smerdyakov> I'm going to compile myself some Frenchmen!
<vincenz> :)
* vincenz waits for his profiling run to finish so he can optimize his analyser
<Submarine> what kind of analyzers do you build?
<vincenz> well this is to be used in combination with the library
<vincenz> we track memory-usage and allocator-usage
<vincenz> basically profile using our own profiler and then get a lot of results out
<vincenz> wihch allow us to decide the optimal shape of the dmm
<vincenz> I'm planning to use the same profile-info and tool to give me more information that will help me for my own research
<vincenz> the advantage over things like valgrind is that I only track stuff I need to track
mfurr has joined #ocaml
<Submarine> vincenz, do you know the kind of tools that Absint Gmbh makes?
<vincenz> have a link?
<vincenz> what about it?
<Submarine> www.absint.de
<Submarine> they for instance give you worst case execution times taking the cache into account
<vincenz> ah but I don't want that
pango_ has quit [Read error: 104 (Connection reset by peer)]
<vincenz> the dmm is part of a metaflow
<vincenz> (imec's metaflow)
<vincenz> and we don't want to decided platform-specific stuff at that level
<vincenz> though that step on it's own does add performance increases
<Submarine> vincenz, yes, but it may interest other people at your institute
<vincenz> true
<vincenz> I shall certainly point them to it
<vincenz> though I'm sure that the people have already looked at it
<vincenz> but thnx
velco has joined #ocaml
velco has left #ocaml []
Demitar has joined #ocaml
det has quit [Read error: 110 (Connection timed out)]
<vincenz> Woo
<vincenz> profile:
<vincenz> #calls for compare_val: 3.5 Billion
<vincenz> caml_c_call: 4.1Billion
<vincenz> caml_compare: 3.5 Billion
<vincenz> what is caml_c_call?!?
<mfurr> its used when the runtime system calls a C function
vezenchio has joined #ocaml
<vincenz> oh, thank you
<vincenz> do you know what function it is that finds a method?
<mfurr> from C?
<vincenz> basically I profiled my app
<vincenz> using ocamlopt -p
<vincenz> [1] 59.6 7089.02 22702.30 3585294595 caml_compare [1]
<vincenz> but I want to see if the object-system incurs a lot of overhead (I use some oo)
<mfurr> Hmm... I'm not sure. I've never seen any dynamic dispatch like functions show up in profiles I've done, so it might be inlined by the compiler
<vincenz> alright, thank you
<vincenz> the values don't make a lot of sense though
<vincenz> it shows cumultime of 18... seconds though it only took 30 minutes
<vincenz> actually 50000 seconds
<mfurr> do you do a lot of I/O?
<vincenz> yes/no
<vincenz> I read 1-2 GB 1 byte at a time
<vincenz> but that's not my main bottleneck
<mfurr> I have a hunch that it doesn't count time when the process is blocked in its cumulative numbers
<vincenz> either way... it's way too much
<mflux> vincenz, 30 minutes cpu time?
<vincenz> no
<vincenz> 30 minutes real time
<Submarine> CPU time or wall clock time?
<mflux> vincenz, how much cpu time?
<vincenz> wallclock
<Submarine> have you used the "time" command?
<vincenz> don't know
<vincenz> no
<vincenz> :/
<vincenz> either way, 18k is 5 hours
<mflux> perhaps you should first try time'ing it
<vincenz> I ahve before
<mflux> but I guess you've seen the process eating all the cpu in top
<vincenz> but when ti was compiled without profiling options
<vincenz> yes
<vincenz> but...time or no tie
<vincenz> it claims MORE seconds than were passed
<vincenz> aka 18k and somewhere else it says 50k
<vincenz> but only 30 minutes or so took place
<vincenz> so it counted 10x too many seconds approx
<vincenz> [1] 59.6 7089.02 22702.30 3585294595 caml_compare [1]
<Submarine> arf
<vincenz> :P
<Submarine> use oprofile
<vincenz> 3.58 Gcomps
<Submarine> caml_compare is the polymorphic compare function
<vincenz> Submarine: I don't have kernel 2.6
<Submarine> it"s quite expensive
<Submarine> vincenz, you don"t need kernel 2.6
<vincenz> too much hassle
<vincenz> how od I bypass the polymorhpic compare?
<vincenz> aka, if I know it's ints
<Submarine> well, you can write < > = explicitly
<vincenz> euhm..
<mfurr> use == instead of =
<vincenz> Map.Make requires a comp function
<Submarine> write one yourself
<vincenz> and afaik, >/< use compare
<Submarine> no
<Submarine> depends on your data types
<Submarine> if you have ints, < > = will be instanciated to ints
<vincenz> sure?
<vincenz> so module Id.t
<vincenz> I mean module Id
<vincenz> where inside t= int
<vincenz> I shouldn't use Pervasives.compare
<Submarine> vincenz, just check it using ocamlopt -S
<vincenz> Submarine what's it do?
<Submarine> output assembler
<vincenz> hmm
<vincenz> so what's an efficient replacement
<vincenz> ?
<vincenz> if a < b then -1 else if a > b then 1 else 0?
<Submarine> let compare = ( - ) ?
<Submarine> let compare x y = x - y
<vincenz> nuhuh
<vincenz> compare must return -1/0/1
<mfurr> let comare (x:int) (y:int) = if a < b then -1 else if a > b then 1 else 0
<Submarine> are you sure, vincenz ?
<vincenz> pretty sure
<mfurr> err, match x's with a's
<vincenz> mflux: but.... if I have an .mli
<mflux> I'm pretty sure negative/positive/0 are enough ;)
<vincenz> do I still need to bind the types in the .ml?
<mfurr> if you give the compiler an exact type, it will specialize the comparison function
<pango> also '-' could overflow
<mflux> I mean.. what sense would it make otherwise
<Submarine> A total ordering function over the set elements. This is a two-argument function f such that f e1 e2 is zero if the elements e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2.
<Submarine> RTFM
<Submarine> pango, true
<vincenz> sorry
<vincenz> but if I say in the mli
<vincenz> cmopare: t -> t-> int
<vincenz> and in the ml t= int..
<Submarine> but let compare (x : int) (y : int) = if x < y then -1 else if x > y then 1 else 0
<Submarine> will be definitely faster than using polymorphic compare
* vincenz nods
<vincenz> but the .mli doesn't do that for you
<Submarine> no
<Submarine> the .mli filters after code generation
<Submarine> consider .mli and .ml like a module Foo = (struct ... end : sig ... end)
<vincenz> ok
<Submarine> vincenz, in Astree we had lots of time spent in poly compare
<Submarine> we replaced all calls to poly compare by mono compares afaik
* vincenz nods
<vincenz> most if not all for me is incompare
<vincenz> lots of maps tat collect statistics
<mflux> maybe a hash could be suitable data structure too
<mflux> tried thta?
<mflux> that even
<vincenz> not yet
<vincenz> most of my keys are either ints/int64 or tuples of those
<Submarine> is the order important?
<Submarine> how are keys generated?
allemann454 has joined #ocaml
<mflux> creating hashes from such data should be simple and could turn out to be very fast, especially if you have lots of data and big hash
<mflux> (big sparse hash versus lots of data in map)
<Submarine> in some circumstance, you can hash keys once and for all
<vincenz> Submarine: order is important for outputting
<mflux> but not processing?
* vincenz blinks
<mflux> you could just sort it for output
<vincenz> how could order be important for processing?
<mflux> it just could
<Submarine> vincenz, it's YOUR code :-)
<mflux> although I think ocaml's map doesn't have 'find greater' or 'find smaller'-functions
<vincenz> nope
<Submarine> which I would need, btw
<mflux> yes
<vincenz> ok I updated the compare func
<Submarine> we have a Map2 module that has lotsa extra functions
<vincenz> it could easily be done
* Submarine recoded Map in Coq
<vincenz> with a iter
<vincenz> and an exception
<Submarine> vincenz, you're converting a log n problem into a n problem, right?
<vincenz> true
<vincenz> actually
allemann454 has left #ocaml []
<vincenz> nm
* vincenz goes to cook as he lets it run again
<vincenz> Int64.compare is non-polymorphic, correct?
avatar8888 has joined #ocaml
<Submarine> indeed
<pango> but int64 are boxed
<mfurr> Submarine: is your Map2 part of coq?
<Submarine> no
<Submarine> it's part of astree
<vincenz> public domain?
<mfurr> In your extra functions do you have something like max_key?
<Submarine> not at all
<Submarine> Map2 may be extracted
<mflux> I wrote an implementation of map that uses a function to extract the key from the data, often useful
<Submarine> we rather focussed on stuff like Map.map2
<Submarine> i.e. you apply a *binary* function to the keys
<vincenz> Submarine: how do I access Map2?
<vincenz> and do you have any plans of submitting it to inria?
<Submarine> vincenz, it's unpublished so far but we may publish it
<Submarine> part of the reason why I did it was to get rid of the INRIA copyright
<vincenz> hmm
<mflux> btw, does ocaml have a function like let identity i = i predefined?
<Submarine> external identity : 'a -> 'a = "%identity"
Nutssh has joined #ocaml
avatar8888 has left #ocaml []
<vincenz> wow, I think it's going a lot faster :)
<vincenz> and I mean A LOT
<Nutssh> What are ya doing?
<vincenz> made compare nonpolymorphic
<Nutssh> Ah... ocamlprof is very nice.
<Nutssh> If you want to sort int or float arrays, specialcasing the sort function to be non-polymorphic (copy&paste) is a factor of three win.
<vincenz> I'm not using ocamlprof
<vincenz> I use gprof
<vincenz> running the bytecode takes too l ong
<vincenz> plus I want to get numbers
<vincenz> not just #calls
<vincenz> ocamlopt -p
<Nutssh> Duh, yeah.
<Nutssh> Also, if you run linux, oprofile is much less invasive.
<vincenz> don't feel like recompiling my kerne
* Nutssh leaves it compiled in permanently.
<vincenz> it still requires me rebuilding my kernel
<Nutssh> If you have it, you'll probably use it often enough that you might as well compile it in.
<vincenz> I never compiled my kernel
* vincenz uses mandrake, with rpm..
<Submarine> and Mandrake does not ship oprofile as RPM?
<vincenz> not afaik
<vincenz> let me check
<Submarine> even Fedora does
<vincenz> nope
<Nutssh> I usually leave oprofile running all the time, then review the results.
<vincenz> is it a module? a prog?
<Nutssh> Its a kernel module with some user-space utilities.
<Nutssh> Its standard in a 2.6 kernel, so if you're based around that, all you probably need are the userspace utilities.
* vincenz is still using 2.4
monochrom has joined #ocaml
Submarine has quit ["ChatZilla 0.8.31 [Mozilla rv:1.4.1/20031114]"]
kuribas has joined #ocaml
<vincenz> odd
<vincenz> Int64.compare uses compare_val
<pango> maybe because they're boxed ?
<mfurr> yes. that just calls the custom blocks comparison
<mfurr> function
<vincenz> darnit
<mfurr> it should only add ~2-3 pointer lookups to the cost of the compare
<vincenz> 15.77 2318.76 2318.76 1596256178 0.00 0.00 compare_val
<vincenz> from gprof
<vincenz> I think my trie-structure is inherently flawed
<mfurr> have you looked at hash-consing?
<vincenz> 'cons'?
<vincenz> it won't matter much imho
<mfurr> If it applies, you could use physical equality instead of structural which could eliminate some of the overhead
<vincenz> not quite, my keys are just ints and such
<vincenz> what's caml_apply2?
<mfurr> closure application
<mfurr> well, if the keys are int64's, then it might help...
<vincenz> problem is that hashs are non-functionaly
<Nutssh> vincenz, is your program fast enough 'as is'?
<vincenz> not quite
<vincenz> though I think my trie is really killing me
* vincenz made a custom trie
<vincenz> module TrieMap = Map.Make(Ord)
<vincenz> type 'a t = Empty | Trie of ('a option * 'a t) TrieMap.t
<vincenz> too bad it's impossible to see how much dispatching costs
CosmicRay has joined #ocaml
<mrvn_> Why Empty? A map can be empty.
<vincenz> cause you need sum-type
<vincenz> can't recurse types otherwise
<vincenz> though tecnically I could put this in one map
<vincenz> (or hash)
kinners has joined #ocaml
<Smerdyakov> vincenz, why not type 'a t = Trie of ('a option * 'a t) TrieMap.t ?
<vincenz> hmm
<vincenz> good idea :)
<vincenz> didn't knowthat was allowed
<vincenz> though if that's allowed
<vincenz> I fail to see the difference beteween that and
<vincenz> type 'a t= ('a option * 'a t) TrieMap.t
<vincenz> why allow one and not the other?
<Smerdyakov> The use of the constructor specifies when to fold and unfold.
<vincenz> ?
<Smerdyakov> Otherwise, type inference can be undecidable, or something like that.
<Smerdyakov> If you really care, read a book on type systems.
* vincenz nods
<vincenz> Anyways I'll leave in Empty
<vincenz> it's a small optimization anyways
<vincenz>
<vincenz> let is_empty= function | Empty -> true | _ -> false
<vincenz> allows for easier matching
<vincenz> :)
grirgz_ has joined #ocaml
<vincenz> I want to change my oo system to a module system, but it's based no mixins, so I 'm not quite sure on how to do it
CosmicRay has quit ["Client exiting"]
<mrvn_> vincenz: use a record of closures for the mixins or functors.
<mrvn_> You can probably also do recursive functors via CPS if you need a variable number of mixins.
<vincenz> yes but the values
<vincenz> I mean the class-mutable-values
<mrvn_> ref
<mrvn_> or return a new MODULENAME.t
grirgz has quit [Connection timed out]
<mrvn_> But copying all the data to change one variable is probably slow.
<vincenz> no I know
<vincenz> but I have mixins
<mrvn_> All mixins have a common interface or not?
<vincenz> yes, but each mixin has some data
<mrvn_> let interface = { fun1 = mixin.fun1 mydata; fun2 = mixin.fun2 mydata; ...}
<mrvn_> Bind it before filling in the dispatch record.
<vincenz> oh
<vincenz> :)
<vincenz> and where does mydata come from?
<vincenz> a create-func ?
<vincenz> create-func =
<vincenz> my data..
<vincenz> interface = {///}
<vincenz> ?
<mrvn_> You should write the functions as "let fun1 = function mydata -> let temp1 = whatever in ... so temp1 get evaluated only once.
<mrvn_> vincenz: The modules own "new" function.
<mrvn_> the .make or .create or whatever you want to call it.
<vincenz> ok thnx
<vincenz> sounds like a good system
<mrvn_> The create function would probably create mydata and the function dispatch record and return the later.
* vincenz nods
<mrvn_> The drawback is that you end up with lots of dispatch records in memory. one per instance.
<vincenz> I only have one instance
<mrvn_> Thought so.
<vincenz> though
<vincenz> right now I do have one base-class "state-machine"
<vincenz> which contains the 'environment;'
<vincenz> the main program calls methods on tihs base-class, these methods then update the environment and call the other funcs that the mixins override
<mrvn_> vincenz: That would be your dispatch record later.
<vincenz> no cause now it'd have to be on top
<vincenz> it has to be called first
<vincenz> or I have to instantiate this base-class with the mixin-combo
<mrvn_> the later
<vincenz> and then pass the internal variables of this class to all the dispatch-records
<vincenz> though...since I'm using records...will it be able to inline?
<mrvn_> let new_tbl () = let mydata = ref 0 in { Base.create () with fun1 = fun1 mydata; }
<mrvn_> The functions from the base clase won't be inlined. They have to be dispatched through the record.
<vincenz> but if I ahve a set of such stacked records, it won't be inlined either
<mrvn_> But if the mixin calls other functions they will inline.
<vincenz> mixins only call other mixins
<vincenz> (to get functionality stacking
<mrvn_> explicitly or through the base class interface?
<vincenz> let me show you an example
<mrvn_> Just think about if you can use "Mixin2.fun1 ()" or have to go through "tbl.fun1 ()"
<vincenz> mrvn_: ideally Mixin2.fun()
<vincenz> though I have to pass the extra data somehow
<vincenz> this is an example o fa mixin layer
<vincenz> it does some stuff and then calls the superlayer
<vincenz> for methods that are not overriden, then naturally the superlayer is called
<mrvn_> vincenz: super#fun -> Super.fun. That is static.
<vincenz> yes except that
<mrvn_> If you get a Mixin as parameter and call its functions then you have to go through the tbl.
<vincenz> either I make the data that the classes have module-data
<vincenz> (ike num_accesses for this layer)
<vincenz> or I have to pass it along
<mrvn_> vincenz: The upper modules can use Super.mydata.num_accesses
<vincenz> ?
<vincenz> that I don't see
<mrvn_> If Super already has a num_accesses then you don't need another one in the Mixins.
<vincenz> it won't
<vincenz> each has it's own data
<vincenz> each layer tracks different info
<mrvn_> Then Super won't know about that and can't access it.
<vincenz> no I know
<vincenz> but since I'm going from classes to modules
<vincenz> this method right here needs to access it somehow
<vincenz> there are two possibilities: make it module-data (aka only one can be run at the sametime)
<mrvn_> you store it in mydata and that gets bound to the functions.
<mrvn_> Make it local to the create function
<vincenz> yes but then you're working with records of functions
<vincenz> which doesn't allow inlining
<mrvn_> you can never inline a dynamic function.
<vincenz> I don't need dynamic functions
<vincenz> I can just have
<vincenz> module ..functor...
<mrvn_> Yes you do. You want to pass any Mixin as Super.t to the functions or not?
<vincenz> no, I want to pass it to the modules
<vincenz> like templates in c++
<vincenz> so I instantiate one thing
<vincenz> at compiletime
<mrvn_> hmm, then what is your question?
<vincenz> right now I use classes
<vincenz> I want to move it to modules as then it will be inlined at compiletime
<vincenz> however the internal data of one mixin must be passed somehow
<vincenz> so either I store it inside the module
<vincenz> (aka module-data)
<vincenz> or I pass it somehow
<mrvn_> you bind it.
<vincenz> where?!?
<vincenz> nm
<vincenz> we're on different wavelenghts
<vincenz> if you want to bind it
<vincenz> you have to create these new functions in a create() function
<vincenz> which means you lose the benefit of inlining
<Smerdyakov> vincenz, could you please write a concise description of what high-level effect you are trying to achieve? Mentioning "mix-ins" in the description is a big no-no.
<vincenz> Smerdyakov: mixins are a well known concept
<mrvn_> vincenz: never heart of it
<Smerdyakov> vincenz, nonetheless, I am asking you to describe your goal without mentioning them.
<vincenz> basically I have different 'layer's of functionality, plus a base-layer wihch contains the state(or environment)... I read a packet, I pass it to the base, it updates the environment and calls a specific function "process_access" for instance.... well I have different modules doing differnet things when "process_access" is called, so I use 'mixins' to stack these different modules, right now I use classes, but technically it's not needed as I kno
<vincenz> something like
<vincenz> module X = functor(Y : Mixin) -> let process_access (somehowpassinfo) = Y.processaccess (passparameters); do sturff
<Smerdyakov> Sorry, I can't help you if you insist on mentioning mix-ins.
<vincenz> I just described it
<Smerdyakov> So what's the problem?
<vincenz> how to pass the info
<mrvn_> vincenz: so you just pass it.
<vincenz> well module 1 might have x in the data, and module 2 y
<Smerdyakov> Don't you have a base function that calls process_access at appropriate times?
<vincenz> how do I collect this?
<mrvn_> You define a Y.data.t, create one on new and pass it on each function.
<vincenz> Smerdyakov: yes, that's not an issue
<Smerdyakov> vincenz, so then _that_ is where the data comes from.
<vincenz> Smerdyakov: I know
<vincenz> but if I use two modules
<Smerdyakov> vincenz, and that is how you pass it.
<vincenz> I'm maybe passing two params
<vincenz> if I use 3 "mixins" I will have to pass data for 3 different modules
<Smerdyakov> vincenz, how do you deal with this problem when you are actually using mix-ins?
<mrvn_> vincenz: no, make a pair, a list, an array, a map, a record out of them
<vincenz> Smerdyakov: it's nto an issue, I use class-variables
<Smerdyakov> vincenz, how does that help?
<vincenz> mrvn_: something like:
<mrvn_> vincenz: class varibales are just a record of variables.
<vincenz> let create () = {mydata: 0; superdata: Super.create()}
<vincenz> ?
<mrvn_> vincenz: yes
<mrvn_> except with correct syntax.
<vincenz> right
<vincenz> s/:/=
<vincenz> ok I'll try that
<Smerdyakov> vincenz, you are being too vague for me to help you any more. If you can write up an English description of your high-level goal, without mentioning any programming language features, then perhaps I can suggest something.
<mrvn_> vincenz: you can use anything as long as all mixin end up with the same interface. Otherwise the functor won't work.
<vincenz> Smerdyakov: never mind I've got it
<vincenz> mrvn_: well that's the idea, just wasn't sure how to do it
<vincenz> aka how to structure the data
<mrvn_> vincenz: Do you have long inheritance chains?
<vincenz> mrvn_: though one issue is that now every 'mixin' must specify ALL the possible functions and then have the ones that are not ovverriden as : let x = Super.x
<mrvn_> vincenz: yes.
<mrvn_> or maybe include Super?
<mrvn_> Does include work only on interfaces or on code also?
<vincenz> 10 mixins right now
<vincenz> each does only basic stuff
<Smerdyakov> mrvn_, 'inherit' is what you're looking for.
<vincenz> mrvn_: if you include can you still override?
<vincenz> cause otherwise I can just have 'default' mixin which calls Super
<mrvn_> Smerdyakov: inherit for modules?
<vincenz> and then include that and override any I want difference
<Smerdyakov> mrsolo_, oh, right. 'open' is what you want, then.
<Smerdyakov> mrvn_, though I guess that doesn't work in OCaml. Another reason to switch to SML. :)
<vincenz> hmm
<vincenz> that made me realize...
<vincenz> inlining is only odne at compiletime.....yet the combination of main is done in main.ml...so it will not inline..
<Smerdyakov> All uses of modules are resolved at compile time.
<mrvn_> And code can be partially evaluated at compile time.
<vincenz> I mean that only when the main (logAnalyzer.ml) is compiled will the functor-combination be known
<Smerdyakov> So?
<vincenz> so will it inline then?
<mrvn_> vincenz: make a small example and check the asm output.
<vincenz> good idea
<drz> is there something special I need to do with types in mli files?
<drz> I've got: type location = { x : int; y : int }
<drz> but when I try to use the type in the .ml files that uses it, I get: Unbound record field label y
<Smerdyakov> .mli files never introduce _any_ bindings.
<Smerdyakov> They serve only to constrain .ml files.
<Smerdyakov> You must duplicate the type definitions in the .ml file.
<drz> smerd: I have that type definition in vt100.ml and vt100.mli, then I'm trying to use it in foo.ml
<drz> smerd: does foo.ml need the type definition also?
<drz> when I remove .y in my code, the error changes to: This expression has type Vt100.location but is here used with type int
<mrvn_> drz: Vt100.x or open Vt100
<drz> which implies to me that the compiler does know what location it's using
<drz> (the actual location foo.ml is using is returned from a function defined in vt100.ml)
<mrvn_> I hope you only have one x and y in vt100.ml
<drz> mrvn: I believe so. I use x as a variable in a few functions but that shouldn't matter, right?
<mrvn_> drz: thats fine. just not two records with *.x
<drz> mrvn: no, there's only a single one with .x
<mrvn_> So what does "Vt100.x" and "Vt100.y" give as error?
<drz> mrvn: how would I use that? My current line of code is:
<drz> screen#get_block spaces 0 80 cursor.y
<mrvn_> cursor.Vt100.y
<mrvn_> looks strange but thats how it is
<drz> mrvn: hey, that compiles
<drz> mrvn: how does that work?
<mrvn_> ocaml needs the full namespace to find y
<drz> strange, I suppose some day it'll make sense to me
<drz> thank you very much :-)
<mrvn_> You could have "point.D2.x" [2 dimensions] and "point.D3.x" [3 dimensions] in one code. The namepsace makes it possible to get the right one.
<mrvn_> .D2.x looks in D2.mli, .D3.x looks in D3.mli
<drz> mrvn: but since the type of (in my case) cursor was Vt100.location, wouldn't it know to look in Vt100 for .x?
<mrvn_> drz: That is what I wonder too. Its even worse with sub records: x.Foo.y.Foo.Y.z.Foo.Y.Z.q
<vincenz> doh
<vincenz> ocaml doesn't inline
<kinners> doesn't inline functors you mean?