Vincenz changed the topic of #ocaml to: http://www.icfpcontest.org -> join #ocaml team, contact Vincenz | http://icfpcontest.cse.ogi.edu/ -- OCaml wins | http://www.ocaml.org/ | http://caml.inria.fr/oreilly-book/ | http://icfp2002.cs.brown.edu/ | SWIG now supports OCaml| Early releases of OCamlBDB and OCamlGettext are available | Caml Weekly news http://pauillac.inria.fr/~aschmitt/cwn/
mattam_ has quit [Read error: 60 (Operation timed out)]
docelic has quit [Read error: 113 (No route to host)]
docelic has joined #ocaml
cDlm_ has joined #ocaml
cDlm has quit [Read error: 104 (Connection reset by peer)]
docelic is now known as docelic|sleepo
Smerdyakov has joined #ocaml
lament has joined #ocaml
lament has left #ocaml []
Smerdyakov has quit ["so bye"]
lament has joined #ocaml
Kinners has joined #ocaml
<teratorn> so any folks here use python too? i'm courious about methods of integrating the two.
Kinners has left #ocaml []
reltuk has joined #ocaml
lament has quit ["RALPH WON'T "MORPH" IF YOU SQUEEZE HIM HARD ENOUGH"]
reltuk_ has joined #ocaml
reltuk_ has quit [Client Quit]
reltuk has quit ["Client exiting"]
whee has quit ["Leaving"]
reltuk has joined #ocaml
mrvn_ is now known as mrvn
ott has joined #ocaml
<ott> re all
lus|wazze has joined #ocaml
cDlm_ has quit [Read error: 54 (Connection reset by peer)]
cDlm has joined #ocaml
vegai has quit [Read error: 113 (No route to host)]
vegai has joined #ocaml
ott has left #ocaml []
whee has joined #ocaml
docelic|sleepo is now known as docelic
delYsid has quit [Remote closed the connection]
cDlm has quit [Read error: 104 (Connection reset by peer)]
cDlm has joined #ocaml
Yurik_ has joined #ocaml
Yurik has quit [Read error: 104 (Connection reset by peer)]
d33p has joined #ocaml
d33p has quit ["Client exiting"]
mellum has quit ["Reconnecting"]
mellum has joined #ocaml
Demitar has joined #ocaml
<lus|wazze> how is the icfp going to work this year if the entries are going to be run locally on one's own machine, but they still say that one's machine's speed does not affect the outcome?
<mrvn> Maybe its a job thats so easy that you are idle most of the time or so hard that a speed factor of 100 does not matter.
<lus|wazze> in other words, you don't know either o_O
mattam has joined #ocaml
Demitar has quit [Read error: 113 (No route to host)]
Vincenz has joined #ocaml
docelic has quit [Read error: 113 (No route to host)]
docelic has joined #ocaml
docelic has quit [Read error: 54 (Connection reset by peer)]
docelic has joined #ocaml
docelic has quit [Read error: 54 (Connection reset by peer)]
docelic has joined #ocaml
Smerdyakov has joined #ocaml
taw has joined #ocaml
<taw> are there multisets in ocaml ?
<Smerdyakov> Are you asking about the libraries that come with the compiler?
<taw> anything that could work
<taw> i googled one implementation in some post but i'm not sure how to adapt it
<taw> type foo = X of int | Y of foo multiset | Z of foo set | ... is what i need
<Smerdyakov> Are you saying that you don't know how to implement a multiset ADT?
<taw> that's probably not that hard, but i'd rather use something already done
<taw> sure type 'a list = Nil | Cons of 'a * 'a list and a few hundred lines of routines for basic stuff too
<taw> but that doesn't mean it's the right wap
<taw> y
<Smerdyakov> What's a wapy?
<Smerdyakov> And you wouldn't need "a few hundred lines" to make a list-based multiset implementation.
<taw> way
<taw> rather type 'a multiset = ('a,int) Hashtbl.t if i wanted anything with remotely sane performance
<Smerdyakov> So do it... it should be trivial.
<Smerdyakov> As in, you can probably write each function you want with a composition of standard higher order functions
Smerdyakov has quit ["I am leaving now."]
<taw> now, why there's no Hashtbl.map ...
<mrvn> You can#t map a hashtbl since the hash values change when you map objects.
<taw> i want to map values not keys
<taw> anyway that's done
<mrvn> But whenever the value changes the hash key usualy changes. The key is supposed to be unique for the value.
<taw> ('a,b) Hashtbl.t <- 'a - key, 'b - value
<mrvn> Unless you misuse the hashtbl :)
mrvn_ has joined #ocaml
<mrvn_> re
mrvn has quit [Killed (NickServ (Ghost: mrvn_!mrvn@pD9E61122.dip.t-dialin.net))]
mrvn_ is now known as mrvn
<mrvn> That time of the day again.
<lus|wazze> =)
* lus|wazze is currently trying out erlang
<lus|wazze> it doesnt even have a lambda abstraction ...
<lus|wazze> but the lightweight processes are nice
<lus|wazze> but still, why do people call it a function language?
<lus|wazze> +al
<taw> the same way c is called "high-level language"
<taw> ;)
<taw> s/way/reason/
<taw> mmm
<mrvn> you can easily do lightweight threads in ocaml using cps.
<lus|wazze> well erlang definitely is high-level
<taw> lack of sleep, definitely :)
<taw> but c definitely isn't :)
<lus|wazze> cps?
<taw> yet, people call it high-level
<mrvn> C is universal asm
<lus|wazze> i don't know anyone who would do such a thing
<lus|wazze> C++, yes, but C?
<lus|wazze> i think there are only very few people who would suffer from the delusion that C is high level
<mrvn> compared to hexcode C is high level :)
<lus|wazze> in fact, isn't that the whole purpose of C? being low-level, but still high-level enough that hardware independant code can be written in it?
<lus|wazze> but we digress
<mrvn> C has a purpose? :)
<lus|wazze> of course
<mrvn> you probably also believe that life has meaning :)
<lus|wazze> C is a really nice, cleanly designed little language with a very specific, if somewhat narrow purpose
<lus|wazze> C++ on the other hand ...
<mellum> lus|wazze: C and cleanly designed? Have you ever written a C parser?
<mrvn> C has taken a lot of features out of neccessity that today haunt it.
<lus|wazze> well the ORIGINAL C was
<taw> well, c parsers are easy
<taw> ocaml has much harder syntax
<taw> not to mention perl :)
<mrvn> mellum: "unsigned;" was a well formed C translation unit, right?
<mellum> And it has zillions of warts. For example specifying *some* properties of struct layout, but not *all*, is just brain-damaged.
<mellum> mrvn: yes
<lus|wazze> well i think they all pale in comparison to C++ i think
<lus|wazze> but thats beside the point
<mellum> lus|wazze: that's an extremely lame argument
<mrvn> perl parsers have to guess the programmers intend at several construct because it has multiple meanings.
<lus|wazze> wasn't it actually impossible (i.e. uncomputable) to write a perfectly standard conforming C++ compiler?
<lus|wazze> usually most languages have such ambiguities, along with clear rules how they are to be resolved
<mellum> lus|wazze: seems unlikely. Why should it be?
<lus|wazze> something to do with templates IIRC
<taw> i don't think so
<mrvn> lus|wazze: perl doesn't. Its not like if a if b c() else d();
<mellum> I could believe it's NP-hard. But why uncomputable?
<lus|wazze> well then they need to invent such rules
<taw> s/rx/something that contains \123s/
<lus|wazze> but im not really concerned about that, because i wouldnt be caught dead touching perl with a 10-foot pole
<taw> 123 may be reference 1 chars 23 or octal char 123
<lus|wazze> mellum, its actually in fact worse than that. as C++'s template sublanguage is turing complete, you can't guarantee that a compiler will halt on any valid input as the halting problem is, as we all know, undecidable
<taw> perl parses that rx to guess what did programer mean :)
<taw> all compilers have some maximum nesting level
<taw> so it's not that much of a problem
<lus|wazze> then they are not completely conforming to the standard
<taw> i'm think that could be part of standard too
<lus|wazze> but i think i even read somewhere that smething in some former version of C++'s language spec made compiling the language in some cases even undecidable
<lus|wazze> but why are we even talking about c++?
<taw> sure, bugs in standards happen, but i don't think they put undecidable stuff intentionally
<lus|wazze> i believe we all agree that it sucks?
<taw> to make ocaml look nice in comparison :)
<lus|wazze> no i never said they put it there INTENTIONALLY
<taw> so it's a bug and they'll fix it in next version
<lus|wazze> i just mentiponed it as an example of how FUBAR c++ is
<taw> but until someone writes kernel in ocaml c/c++ will have its uses
<lus|wazze> well with a decent language, imho, a bug of THAT magnitude - well lets just say someone somewhere would have to work REALLY hard to introduce something like that in the spec of a language of reasonable complexity
<lus|wazze> c does, yes
<lus|wazze> for small-scale low-level type stuff
<lus|wazze> but the intersection of sets of programming tasks C++ seems to be interested in oughta be empty in my view
<lus|wazze> that being, low-level code and complex systems
<taw> i think everyone should switch from c to c++
<lus|wazze> haha thats a good one
<taw> those who use c that is
<lus|wazze> C is perfectly sufficient for the kind of tasks you would want to do with either
<taw> c hastoo serious security issues
<taw> and too little expresive power
<lus|wazze> yeah like C++ fixes those :rolleyes:
<taw> strcpy must die
<lus|wazze> that is, the low-level parts of device-drivers and the like
<lus|wazze> C is perfectly sufficient for those
<taw> c with class string, and cout << instead of printf is all what i need ;)
<taw> i'll remind you that when someone's gonna crack your servers because of stack overflow
<taw> ;)
<mellum> IMHO, c is too high level. If you want to do string handling, you chose the wrong language anyway. I want exact struct layout, for example.
<lus|wazze> im sorry but i find it REALLY hard to call a language, ANY language with manual memory managment safe at any level
<lus|wazze> i think the compromise C strikes has pretty much turned out to hit the mark
<lus|wazze> but anyway
<mrvn> Anything that goes down to hardware level has to do manual memory managment. GCs are not realy feasable at kernel level.
<lus|wazze> all that is not really important. one could argue language politics for years
<lus|wazze> mvrn i agree. thats why C still has a place in the world of programming
<lus|wazze> the corollary to that is that low-level languages cannot be safe
<mrvn> What C suffers from is all the old garbage that was neccessary at first due to cpu limitations and compiler complexity.
<lus|wazze> but you said something interesting earlier
<lus|wazze> like?
<mellum> The biggest problem with C is that people use it for tasks where it *REALLY* istn't suitable, like servers or GUIs
<mrvn> like type defaults to int.
<lus|wazze> hehe
<lus|wazze> like anybody stll uses auto foo; 8)
<lus|wazze> anyway
<lus|wazze> [20:23:10] <mrvn> you can easily do lightweight threads in ocaml using cps. <-- how so?
<mrvn> C is the only interface that realy works with everything. Any other language limits your choices.
<lus|wazze> thats correct as well
<lus|wazze> so C is a nice language for building bridges between languages
<lus|wazze> still, if you might be so kind to answer my question ... ? :)
<mrvn> lus|wazze: every function has the form (fun cps val -> do something with val; cps new_val)
<lus|wazze> :|
<lus|wazze> i wouldn't call that 'easily'
<lus|wazze> what if i want to call some built-in or library function that takes a while to terminate?
<mrvn> Now, instead of calling cps directly call "continue cps new_val" and continue would do the multithreading by storing the cps and values till this thread is to be run next.
<mrvn> lus|wazze: You would hve to rewrite the libs to use cps style.
<lus|wazze> say i want to concurrently sort a 10 million item array while calculating something else
<lus|wazze> with the builtin sort functions
<taw> you can have safe low level languages, majority of c problem are due to strings being 0-terminated instead of something saner like struct string {int len; char *str};
<lus|wazze> taw: then i simply do something like
<mrvn> taw: any kind of array will do.
<taw> c with real access boundary checking would be way better, securitywise
<lus|wazze> string foo = "hallo";
<lus|wazze> or rather
<lus|wazze> string *foo = new string("hallo");
<taw> intels even have special instructions for that, BOUND
<lus|wazze> ...;
<lus|wazze> // not releasing the memory
<lus|wazze> return;
<mrvn> You can write a C compiler that is absolutely type safe. The standard allows for that explicitly. Its just too much cpu time wasted
<mellum> Whether you can have "safe low level languages" entirely depends on the definitions of "safe" and "low level"...
<taw> i'm only talking about security
<taw> sure you can screw everything
<taw> but it's better to segfault than to execute shellcode
<taw> much better
<taw> and they should never allocate buffers on stack for dog's sake
<lus|wazze> ahh time to indulge in some rather refreshing dairy products (cherry yoghurt to be specific)
<mrvn> taw: Wehn you put strings into a struct you can just as well just use c++.
<taw> on heap, one buffer per hardware page
<taw> mrvn: yeah, they should write stuff in c++ not c if they really want to have it low level
<lus|wazze> taw you can steal introduce errors which could create either outcome
<mrvn> taw: Allocating buffers on stack is just so much faster and it gets cleaned up automatically.
<lus|wazze> as long as you allow code to produce undefined behaviour like that in any instance
<taw> mrvn: not much faster, and compiler may automatically insert free()s
<mrvn> Whats the behaviour of c++ == c++ in ocaml? (incr c) = (incr c)?
<lus|wazze> you can't do that?
<lus|wazze> oh
<mrvn> taw: a system call for an alloc takes ages.
<lus|wazze> ==
<lus|wazze> not =
<lus|wazze> i misread
<lus|wazze> its undefined :)
<mellum> mrvn: you can'
<mellum> t do that
<lus|wazze> not every malloc needs a system call though
<mellum> since incr is ref->unit and not ref->ref
<mrvn> is (incr c) := (incr c) legal?
<lus|wazze> it depends on the allocator
<lus|wazze> no
<mrvn> mellum: You can but it would be allways true then. Or is unit != unit?
lament has joined #ocaml
<lus|wazze> well you could still do
<mellum> oh, I thought you weanted to assign, not compare
<lus|wazze> (incr c, !c) == (incr c, !c)
<lus|wazze> (incr c, c) := (incr c, !c) is probably possible then as well
<mrvn> lus|wazze: thats allways false because your comparing addresses
<lus|wazze> ? no im not?
<lus|wazze> !c <-- the VALUE of c
<mrvn> lus|wazze: == is physical
<lus|wazze> yes
<mrvn> So your comparing the addresses of the two tuples which will differ.
<lus|wazze> it depends on the type of !c and if they are actually physically equal
<taw> mrvn: you don't do that in inner loop, so does it matter ?
<lus|wazze> oh you're right thats tuples im writing
<lus|wazze> i meant
<lus|wazze> (incr c; c) := (incr c; !c) is probably possible then as well
<lus|wazze> sry
<mellum> lus|wazze: == doesn't look inside the pair. It always just does cmpeq a0, a1, v0.
<lus|wazze> i know that
<lus|wazze> i mixed up ; and ,
<lus|wazze> i didnt want to construct a tuple
<lus|wazze> i wanted to make a sequential statement
<mrvn> lus|wazze: its all possible but undefined afaik.
<lus|wazze> well there are different classes of undefined
<lus|wazze> what i was actually talking about was true "undefined" - i.e. "whatever happens when the code gets executed, depending on the internal representation" like there exists, in several cases, in C
<mrvn> Its undefined in the oder of execution but not in the type or the amount of monkeys leaving your ear.
<lus|wazze> all the undefined behaviour not having anything to do with Obj.magic & friends falls into the second class
<lus|wazze> which is -- exactly what mrvn just said
<taw> it's unspecified not undefined according to standard c terminology :)
<lus|wazze> its undefined in the sense that one of several possible, valid outcomes may be the one chosenm
<mrvn> lus|wazze: Do you know if one can make a ocaml sandbox without file access?
<taw> undefined = may eat your can and burn your computer
<lus|wazze> unsdpecified, exactly
<lus|wazze> unspecified behaviour can lead to program bugs, but cannot defeat security
<lus|wazze> undefined
<lus|wazze> behaviour, on the other hand ...
<lus|wazze> btw
<lus|wazze> # (incr c; !c) = (incr c; !c);;
<lus|wazze> - : bool = false
* mrvn still wants to see a ocaml prog that takes some text as input, say c code, parses and compiles that and builds a closure for it via Obj.magic and executes it.
<lus|wazze> :////
<mrvn> lus|wazze: The vaue of c will be unspecified.
<lus|wazze> well that would actually be rather easy to do for other, simpler languages like, say, bf ;)
<lus|wazze> no c wll be incremented exactly twice in that comparison
<lus|wazze> the value of the comparison statement, on the other hand, will be unspecified
<lus|wazze> now if you were to do something like
<lus|wazze> (incr c; !c) = (incr c; !c) && (incr c; !c) = (incr c; !c)
<lus|wazze> THEN the value of c afterwards would be unspecified
<mrvn> one incr might be done after reading the second !c but before assigning c
<mrvn> s/one/the first/
<lus|wazze> hm ok thats true
<lus|wazze> if you don't see the incr as an atomic operation
<mrvn> lus|wazze: && and || have defined order.
<taw> ; too
<lus|wazze> yes
<lus|wazze> but whhen the statement on the left hand of && is of unsepcified value
<mrvn> lus|wazze: incr may be atomig. doesn't matter.
<lus|wazze> then it is unspecified whether or not the one on the right-hand side will be executed
<lus|wazze> so !c's value will be unspecified
<lus|wazze> no
<lus|wazze> if the incr operation is atomic
<lus|wazze> then there can not happen anything in between reading its value and storing it again
<lus|wazze> that is
<lus|wazze> as there are two atomic increment operations performed on c
<mrvn> (incr c; c) = (incr c; !c) ==> let t = (incr c; !c) in (incr c; c) := t
<mrvn> or let t = (incr c; c) in t:= (incr c; !c)
<mrvn> wo different values for c
<mrvn> +t
<lus|wazze> no
<lus|wazze> i was COMPARING them
<lus|wazze> i did not make any assignment
<lus|wazze> [20:59:03] <mrvn> (incr c; !c) = (incr c; !c)
<lus|wazze> i inserted the ! you seem to have omitted
<mrvn> that was the first one.
<lus|wazze> (incr c; c) := (incr c; !c)
<lus|wazze> now THAT is unspecified
<mrvn> yep.
<lus|wazze> and
<lus|wazze> (incr c; c) = (incr c; !c)
<lus|wazze> like you typed
<lus|wazze> is neither
<taw> you sure ?
<lus|wazze> because it will not even compile
<taw> hmm
<mrvn> The compare would be allways false
<lus|wazze> its a type error
<lus|wazze> the left-hand side is of type 'a ref
<lus|wazze> the right-hand side of type 'a
<mrvn> lus|wazze: forgot the :
<lus|wazze> well i thought you forgot the !
<lus|wazze> of course when you put the : there its unspecified
<mrvn> (incr c; !c) < (incr c; !c) is also unspecified.
<lus|wazze> yep
<lus|wazze> but if you think of (incr c) as an atomic operation
<lus|wazze> (which it's probably not)
<lus|wazze> then the value of c afterwards will still be specified
<lus|wazze> because it will be incremented exactly 2 tmes
<taw> not really
<mrvn> I think it can be taken as granted that a < b will finish eigther a or b completly first when they are not seperated.
<lus|wazze> i dont knw if anything can be taken for granted
<taw> i wouldn't take it for grathed
<mrvn> Otherwise the scheduler would make a lot of mistakes.
* taw <- writing toy optimizing compiler now
<lus|wazze> one might imagine a compiler which translates ocaml to erlang and makes both sides of the comparison into separate processes
<lus|wazze> just to be annoying :)
<lus|wazze> but if you take incr c as ATOMIC
<lus|wazze> then incr c simply represents one incrementation of c
<mrvn> which would not be correct since it says the oder of execution is undefined but ordered. Thats how I read it.
<lus|wazze> and that cannot be interrupted , as it is atomic
<lus|wazze> well then the value is defined
<lus|wazze> of c
<taw> ordered now ?
<taw> how ?
<mrvn> either a first or b first
<taw> does it say it's structurally ordered ?
<lus|wazze> its unspecified, apparently, HOW its ordered but its ordered in SOME way
<taw> no mixing at all ?
<lus|wazze> apparently
<lus|wazze> i havent read anything that says so, but mrvn says he did
<mrvn> taw: some mixing will be introduced later by the optimizer. But only non destructively.
<mrvn> Anything else would be damn braindead.
<lus|wazze> you can't argue according to what a specific ocaml compiler will do
<lus|wazze> you can only argue about what the specification states
<lus|wazze> if the specification does not EXPLICITLY state what order the (incr c) statements are going to be executed in
<lus|wazze> or even that they are not going to be executed concurrently
<mrvn> Lets say it another way. You could probably get away with executing it unordered but it would be so braindead your compiler wouldn#t work.
<lus|wazze> youre going to have to be prepared to accept that !c might come out as either the original !c + 1 or +2
<lus|wazze> in what way wouldn't it work?
<lus|wazze> the compiler works :<=> if the code it produces does exactly what the language specification states the source program was going to do
<taw> optimizing compilers usually don't care unless they have
<lus|wazze> thus if it isnt in the specification, the compiler may do what it wishes
<mrvn> lus|wazze: There are too many cases that are very similar but defined.
<taw> to
<taw> the more they have to care, the less they can optimize, so they try to care as little as they can
<lus|wazze> ah well this discussion is tiring
<mrvn> Off to more intresting topics:
<taw> 1 + 0 * (1 / 0) obviously won't throw divide by zero exception under any sane compiler
<mrvn> Anyone know or wants to write me a nonblocking dns lookup?
<taw> adns
<taw> there's already one
<lus|wazze> actually a sane compiler should generate ONLY the code to throw the divide by zero exception
<taw> $ adnshost www.ocaml.org
<lus|wazze> because it can detect that it should ALWAYS generate one
<mrvn> taw: I need ocaml bindings.
<taw> oh
<taw> so make ocaml bindings to libadns
<mrvn> I heard adns wasn't good.
<taw> dunno, i didn't have any problems with it
<taw> but i didn't do anything really heavy with it
<taw> nothing more than checking a few thousands adresses
<taw> at once
<lus|wazze> what can be good or bad about a dns lookup library?
<lus|wazze> it basically just needs a function look_up name which evaluates to an ip ... :/
<mrvn> taw: How do I wait for a reply from a dns server?
<lus|wazze> or in the non-blocking case needs something like
<lus|wazze> begin_look_up name
<lus|wazze> which then in some way notifies the calling thread as soon as the look-up is complete
<taw> as if i remembered ..., just read docs
<taw> it's not hard
<taw> but maybe callback mechanism will be hard :)
<taw> calling back to ocaml
<mrvn> lus|wazze: I'm going for a single thread library.
<taw> single thread, that's so 20th century :)
<mrvn> lus|wazze: So i would need to get the filedescriptors adns uses to select upon and call adns back.
<lus|wazze> :/
<lus|wazze> well I said the CALLING thread
<mrvn> If I multithread I can just fork once for every dns request and use ocamls natural resolver.
<lus|wazze> so you would in the end prolly STILL use select
<lus|wazze> so whats the difference
<mrvn> lus|wazze: The difference are the 100 other FDs I'm selecting too.
<lus|wazze> ?
<lus|wazze> select can wait on any number of FDs simultaneously i believe .)
<mrvn> limited somewhat but high enough I won't reach that.
<mellum> lus|wazze: on Windows, only 64 :)
<mrvn> I'm using lightweight threads via cps style in my program and the only thing I need is to know when adns has to do some work.
<mrvn> mellum: Urgs. That realy sucks.
<lus|wazze> :/
<lus|wazze> well select on windows sucks either way
<mellum> mrvn: Of course. They had to ensure the posix layer is as unusable as possible.
<lus|wazze> as windows has its own system for signalling completion of operations which CANNOT be checked via select
<lus|wazze> so you will be forced to have another thread to do waiting on these signals or events while you are selecting on socket descriptors in another one
<taw> just use unix :)
<taw> (or hack windows kernel to add sane select ;-)))))))
<taw> yeah, editing binaries to make windows do something more ... these were times
<mrvn> Ah, I can get a list of FDs adns uses and tell it to process a certain FD select returned.
<mrvn> Thats looks useable.
<lus|wazze> i wouldnt even complain if you could at least create such an win32 api EVENT to be set when something happens on a socket which you would normally select() after
<lus|wazze> but you cant
<lus|wazze> instead, you can let windows send you a message when something happens
<lus|wazze> so in summary there are now 3 (THREE!) ways to check for events
<lus|wazze> in windows
<lus|wazze> which cannot be checked parallelly and blockingly with a single function call
<lus|wazze> you'd need THREE processes just for that
<lus|wazze> one which is supsended in a GetMessage() call
<lus|wazze> one which is suspended in a select() call
<lus|wazze> and
<lus|wazze> one which is suspended in a WaitForMultipleObjects() call
<taw> so ;) ?
<taw> you may always switch to unix
<lus|wazze> or you could just go ahead and check for yourself in an endless loop and just live with those 100% of cpu time your program spends when idle
<mrvn> to hell with multitasking
<lus|wazze> trust me, in this case, i don't multitask by choice either
<mrvn> I would just select with timeout (0.1s or something) and then check the other events. :)
<lus|wazze> taw, well you could do THAT, but somehow I doubt that switching to unix would make writing windows applications easier
<mrvn> lus|wazze: writeing application becomes easier.
<lus|wazze> writing WINDOWS applications becomes EASIER if you switch to linux?
<lus|wazze> i somehow doubt it
<mrvn> no, just applications in general
<taw> yeah
<taw> ;)
<lus|wazze> i think youre not getting what im saying :)
<lus|wazze> the problem is not whether or not < I > switch to linux
<lus|wazze> the problem is whether or not my USERS switch to linux
<mrvn> lus|wazze: you haven't yet?
<lus|wazze> which , unfortunately , they are NOT
<lus|wazze> nope
<mrvn> I'm my own user.
<lus|wazze> currently im in a windows phase
<taw> writing windows apps under linux is much easier :)
<lus|wazze> i switch between the two ... oh say... once a year
<taw> phase 1 - write for linux, phase 2 - port
<taw> that's like writing c apps in perl
<lus|wazze> i imagine
<taw> developing on windoze is a horror
<lus|wazze> oh it depends
<mrvn> Damn, looks like I have to rewrite Unix.select for adns cause it wants those nasty C FD_Sets.
<lus|wazze> the environment itself is alright
<taw> most apps can be crossdeveloped
<taw> not all but most
<mrvn> I think I will rather implement a poll interface for ocaml.
<lus|wazze> its the api which kills
<taw> use some pseudo-posix layer
<taw> and some gui like wxwindows
<mrvn> wine can be used too.
<lus|wazze> i honestly believe they employed ergonomics experts and psychologists while developing some parts of the windows api
<taw> mrvn: using braindead api on os where there's much saner one ?
<mrvn> lus|wazze: For all the millions they put into it bloody likely.
<lus|wazze> to make them design the api's as horribly unusable, mind-numbing and most importantly, INTRUSIVE as possible
<taw> huh ?
<lus|wazze> with windows api's its almost impossible to write a program for them, without writing your program completely AROUND them
<lus|wazze> and I stronlgy suspect this is by design
<lus|wazze> to make it difficult, if not impossible, to write portable code which also runs on windows
<lus|wazze> the sad thing about that is that there even are some parts of the windows api which are rather nice
<lus|wazze> like directsound
<taw> probably not
<taw> that's how normal closed code looks like
<lus|wazze> but then again there are horrible butchered abortions of interfaces like directinput or direct3d
<taw> developed by modifying previous version to support new features invented by management and being backward compatible at the same time in shortest time possible
<lus|wazze> luckily, there exists opengl - even on windows
<mrvn> Anyone used epoll yet?
<lus|wazze> ?
<lus|wazze> whats that?
<mrvn> Its the new poll function in linux 2.5.44+
<taw> then no
<taw> how does it work ?
<mrvn> It supports edge and level triggers. You can add/remove FDs from the "to be polled" list and ask/wait for events.
<taw> damnnnnn
<taw> broken broken broken
<lus|wazze> ?
<taw> i can't write pattern for multiset containing one element now
<lus|wazze> :/
<taw> Hashtbl.t doesn't support that
<mrvn> Its has the advantage of no overhead when waiting for the same set of FDs repeadatly and the advantage of O(1) work per descriptor with an event.
<mrvn> taw: pattern?
<taw> function x -> y | z -> v
<mrvn> if length table = 1 then ... else ... ?
<mrvn> like that?
<mrvn> Too bad Hashtbl has neighter empty nor length.
<taw> yeah
<Riastradh> let hashtbl_lentgth ht = let l = ref 0 in Hashtbl.iter (fun _ _ -> l := !l + 1) ht; !l
<mrvn> Riastradh: empty needs an exception to be fast.
<Riastradh> exception EmptyHT
<Riastradh> Er.
<Riastradh> exception NonEmptyHT
<Riastradh> let hashtbl_empty ht = try (Hashtbl.iter (fun _ _ -> raise NonEmptyHT) ht; true) with NonEmptyHT -> false
<mrvn> try Hashtbl.iter (fun _ _ -> raise NonEmptyHT) ht; true with NonEmptyHT _>false
<Riastradh> Heh.
<mrvn> great minds think alike :)
<taw> now what i need is "has one element" anyway ;)
<Riastradh> exception OneElt
<Riastradh> Er.
cDlm_ has joined #ocaml
<mrvn> taw: use the length function but raise an exception when the counter reaches >1
<Riastradh> exception MoreElts
<taw> yeah, probably something like that
<Riastradh> let hashtbl_one_elt ht =
<Riastradh> let one = ref false in
<Riastradh> try
<mrvn> taw: But why would you need to know if a multiset contains only one entry?
<Riastradh> Hashtbl.iter (fun _ _ -> if !one then raise MoreElts else one := true) ht;
<Riastradh> !one
<Riastradh> with MoreElts -> false
<mrvn> isn't there a Hashtbl.fold?
<taw> to replace X of int * diexpr multiset = X (a,x) with IConst a ;)
<taw> mmm
<taw> to replace X of int * diexpr multiset = X (0,x) with one_element x
<Riastradh> Oh, yeah, if there's a Hashtbl.fold use that instead of my imperative junk.
<taw> brrr
<mrvn> taw: Wouldn't that need to check if the multiset has only one entry for a?
<taw> generally i keep sums etc. as multisets and if after optimalizations it will go to 1 element i may unsum it
<taw> x + y - x -> Sum (x,y)
<taw> x + y - x -> Sum (x,y) + y
<taw> x + y - x -> Sum (x,y) + y -> Sum (x) -> x
<taw> x + y - x -> Sum (x,y) - x -> Sum (y) -> y
<lus|wazze> nice there is even a apparently surprisingly nice gui lib that comes with erlang
<taw> Sum(y) -> y needs that check
<teratorn> so what's a good doc for an ocaml newbie?
<mrvn> teratorn: file:///usr/share/doc/ocaml-doc/docs/ocaml.html/
<lus|wazze> the ocaml introduction on the ocaml main page?
<taw> now my "multisets" allow negative number of elements, what's nice too hehe
<teratorn> lus|wazze: yes i've been reading that :)
<taw> -x is Sum (-1 element x)
<mrvn> taw: Aeh, you multiset has an integer for the number of entries for each values?
<lus|wazze> well then thats fine, keep reading :)
<mrvn> multimap : value -> number of occurances ?
<lus|wazze> hmm
<lus|wazze> anyone know which one of the erlang standard libs is the one containing the basic networking primitives?
<lus|wazze> their names are so undescriptive ...
<mrvn> are we #erlangen?
<taw> x + x + x + y => Sum {x -> 3, y -> 1}
<lus|wazze> and I dont want to have to click on each one
<lus|wazze> sorry :(
<Riastradh> There is a #erlang, but it's pretty small.
<taw> that's nice form to optimize
<mrvn> taw: Then use a ('value, int) Hashtbl
<taw> much better than dag, as it takes care of associativity and reflectivity
<taw> i do use ('value, int) Hashtbl
<mrvn> Then Hashtbl.find value = 1 is your test for one.
<mrvn> +tbl
<lus|wazze> but nobody in #erlang is saying anything and i thought maybe someone from here might know .(
<taw> no
<Riastradh> lus|wazze, you just joined #erlang!
<Riastradh> And you've waited a minute for an answer.
<mrvn> Or do you want to optimize Sum {x -> 3} into Mult {x, 3} ?
<taw> Sum hashtable -> if hashtbl contains one any element of value 1
<taw> i represent Mul(3,x) as Sum (x->3) anyway
<taw> Muls are only for variable * variable here
<mrvn> multiplication with small integers are worth optimizing
<taw> but that's during asm code generation phase
<taw> using sums is better for finding various identities
<mrvn> Why not use an assoc list?
<mrvn> Do you realy have such big sums of variables that a hashtbl is called for?
<taw> assoc list differs how from hash table ?
<mrvn> assoc list is just a list of tuples.
<Riastradh> An alist is a ('key,'value) list.
<mrvn> [(x, 2); (y, 3)]
<taw> yeah and merging them works how ?
<Riastradh> Lookup time gets really slow.
<mrvn> if List.length l = 1 then ...
<Riastradh> ...with big enough alists.
<taw> lookup is O(n), fine, merging sucks O(n^2)
<Riastradh> But for small alists (e.g., fewer than a couple hundred elements) they're fine.
<mrvn> Keep them sorted and merge is O(n)
<taw> oh
<taw> may work :)
* Riastradh pokes lus|wazze.
<taw> no, it may not
<mrvn> I guess you have probably only <10 vars in a sum usually.
<taw> sorting expressions, brrrr
<mrvn> taw: Pervasives.compare
<taw> directly yes, but compiler goes further than that
<taw> it should go thru loop evaluating it and check what are invariants etc.
<taw> now it may grow real big
<mrvn> Or write a wraper for hashtbl that counts the number of entries
<mrvn> You probably also want to remove x->0 mappings from the table.
<taw> i do it during merge
<taw> probably should optimize it more
<taw> of course optimalization is something that takes eternity * 10 to do right
<mrvn> let multiset = { mutablenum_entries:int; tbl: ('value, int) Hashtbl.t; }
<taw> oh
<mrvn> or scratch the mutable if you want multiset functional and not imperative.
cDlm has quit [Read error: 110 (Connection timed out)]
<lus|wazze> im starting to really like erlang ... lets see if i can now, about an hour after i downloaded & installed it, write a simple little irc bot already :)
lament has quit ["I WILL NOT FAKE SEIZURES"]
lament has joined #ocaml
<lus|wazze> hmm looks nice :)
watserlbot has joined #ocaml
<lus|wazze> ! :)
<lus|wazze> !quit
<lus|wazze> :(
watserlbot has quit [Remote closed the connection]
watserlbot has joined #ocaml
<lus|wazze> !quit
watserlbot has quit [Client Quit]
<lus|wazze> not bad after about 2 hours of coding, and 4 hours after my first exposure to the language and less than 100 LoC and I have it running
<taw> you could do it with 5 lines of perl ;)
<lus|wazze> an irc bot?
<lus|wazze> hm
<taw> yeah
<lus|wazze> well probably
<lus|wazze> if they are LONG lines
<taw> use Net::IRC;
<taw> 4 lines here
<lus|wazze> :)
<lus|wazze> well ok
<lus|wazze> im sure theres such a library for erlang as well
<lus|wazze> but when you write the interpreter for the protocol yourself
<lus|wazze> after all this is the actual interesting part about it, or rather, what I used to try out the language :]
<taw> depends
<taw> most interesting in perl is cpan
<taw> different mindset
<lus|wazze> no thats not what i mean
<whee> heh, writing an erlang irc bot was one of the first things I did too :)
<lus|wazze> of course its better to use the preexisting libraries for all they're worth
<lus|wazze> but for learning a language, doing some things oneself is better
<taw> doing things oneself is outright wrong for perl hackers :)
<taw> sometimes you have to do it the wrong way and actually code it, but try not to make that mistake too often :)
lament_ has joined #ocaml
lament_ has quit [Read error: 104 (Connection reset by peer)]
lament has quit ["A FIRE DRILL DOES NOT DEMAND A FIRE"]
lament has joined #ocaml
<Riastradh> lus|wazze, what did you use to learn Erlang?
<lus|wazze> the documentation on the page: www.erlang.org
<taw> what's the point of learning erland anyway ?
<taw> what is it good at ?
<Riastradh> Where on the doc page in specific?
<whee> taw: it's really good with things that are best approached with concurrency in mind
<whee> and fault tolerance
Vincenz has quit [Read error: 104 (Connection reset by peer)]
systems has joined #ocaml
* Riastradh prods lus|wazze.
lament has quit ["I WILL NOT TEACH OTHERS TO FLY"]
<teratorn> mozart-oz has some crazy concurrency also