mbishop changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | Grab OCaml 3.10.2 from http://caml.inria.fr/ocaml/release.html (featuring new camlp4 and more!)
<Ramzi> thelema: are you here?
Axioplase has quit ["leaving"]
jlouis has quit ["leaving"]
r0bby has quit [Read error: 104 (Connection reset by peer)]
evn has joined #ocaml
r0bby has joined #ocaml
^authentic has joined #ocaml
authentic has quit [Read error: 110 (Connection timed out)]
^authentic is now known as authentic
|Catch22| has joined #ocaml
Deimos_ has joined #ocaml
<Deimos_> hi
^authentic has joined #ocaml
<Deimos_> what is the difference between [] and () ? for example : let rec f l = match l with | [] -> () ..... or let rec f l = match l with | [] -> []
<qwr> [] - empty list, () - unit value
<qwr> basically, they have nothing more in common, than that both are constant literals
<Deimos_> ok thx =)
* qwr . o O ( what's a difference between "" and 0? :P )
authentic has quit [Read error: 110 (Connection timed out)]
^authentic is now known as authentic
<psnively> One is a string and one is an int?
<psnively> [] is interesting because it's an 'a list.
<psnively> A list of (as of yet) undetermined type.
<Ramzi> do you mean to tell me the empty set of naturals is the same as the empty set of reals?
<psnively> No.
<psnively> I mean to tell you that OCaml can't decide (yet) what [] will eventually contain.
<qwr> nor does it matter
<qwr> as this particular value contains nothing and will never contain anything more ;)
<qwr> only thing that gets more specific is the type as 'a list is polymorphic type
<Ramzi> if you compile a .ml, what is the entry point of the program?
evn has left #ocaml []
<qwr> toplevel
<psnively> So in a .ml, you'll often see around the end something like: let () = my_main_function(...)
<thelema> Ramzi: the whole .ml gets evaluated
<psnively> See y'all later!
psnively has quit []
<thelema> Ramzi: and you should bind the result of get_char somewhere so you can use it. "let binding" != variable. your prof wants you to avoid refs
<qwr> although points-free style code would be quite impressive in some sense :P
<Ramzi> it's really quite amazing how I just figured some things out for myself.
<Ramzi> and then you guys reply in here with identical answers.
* thelema is psychic
<Ramzi> i like doing that while reading wikipedia, too. read a problem, stop and think about it, and then continue reading to see your thoughts already on the page.
<thelema> someone has already thought most good thoughts.
<Ramzi> maybe most bad ones too?
<thelema> no, there's a *lot* of bad ideas. Like pickle-feather
<Ramzi> I'm looking to write a custom get_char function from stdin. It'll read a char, but return " " for spaces, newlines, and tabs. And it will return the capitalized version of alphabet letters.
<Ramzi> I'm newer to OCaml I/O even than I am to OCaml.
<thelema> match works on characters
<Ramzi> try (input_char stdin)
Deimos_ has quit ["Quitte"]
<thelema> match x with 'a' -> 'b' | _ -> 'a'
<qwr> all the texts would contain stuff you're never thought of, if you'd remove most of your brain. :P
<Ramzi> does the character get saved to input_char?
<qwr> no, it returns it
<Ramzi> but before returning it, i want to see it, and do stuff to it, and then return it.
<Ramzi> hmm, i should just have a different function. like filter c
<qwr> so write a function that does the stuff
<Ramzi> that gets results from the i/o that i already have.
<thelema> Ramzi: sounds like a plan
<Ramzi> so, 26 cases?
<Ramzi> how can i see the ascii value?
<Ramzi> and say, if it's in this range, return that number plus something.
<Ramzi> 97 to 122
<Ramzi> is a-z
<qwr> | 'a'..'z' ->
<Ramzi> 65 to 90 is A-Z
<Ramzi> Is that the syntax, .. ?
<qwr> yes
<thelema> Char.code 'x'
<Ramzi> thank you and thank you.
<Ramzi> can you start the first match with a |?
<qwr> you can also do match input_char stdin with 'a'..'z' as c -> foo c
<Ramzi> like match c with |a -> A
<qwr> yes. | directly after with is optional
<Ramzi> thx
<Ramzi> how can you refer to a newline and tab character?
<qwr> '\n' '\t'
<Ramzi> can you put in their ascii value?
<Ramzi> like match c with 97 -> 65
<thelema> no, the number 97 isn't the character a
<thelema> match Char.code c with 97 -> 65
<Ramzi> so it doesn't deduce, that since i'm matching it against a character, that it should be a character
<thelema> it's a type error, just like 2 + 2.0
<thelema> ocaml doesn't do any automatic coercions
<qwr> simply, int is not a char ;)
<Ramzi> can you seperate multiple things in a match with a comma
<Ramzi> for example match c with a,b,c -> Z
<Ramzi> or 'a','b','c' -> 'Z' rather
<thelema> no, but you can do match c with 'a' | 'b' | 'c' -> 'Z'
<qwr> 'a'|'b'|'c' -> Z
<Ramzi> this | isn't quite an or, but it sorta is
<Ramzi> do the cases get evaluated in order
<Ramzi> for example, match c with 'a' -> 'A' | 'a' -> 'B'
<Ramzi> Will always return A and never B, right?
<qwr> probably compiler warning too
<Ramzi> well, i want to say, for a-z return A-Z, for \t and \n return ' ', and for everything else, return that thing.
<Ramzi> i thought about the wild card for the "everything else" but thought that a-z would also fall into the wild card
<qwr> yes, it evaluates in order
<Ramzi> if I do _ -> _, that'll mean "return whatever it is" right?
<Ramzi> hmm, that can't be right.
<qwr> it means what a fuck is _?
<thelema> Ramzi: no, x -> x
<Ramzi> because for a list you can say (_ :: _) to refer to the heads and tails, but if you say return _ it wouldn't know which to return
<qwr> basically, _ is not a value
<qwr> so, it's not an expression. and can't be used as a such
<Ramzi> k
<thelema> _ isn't an identifier
^authentic has joined #ocaml
<Ramzi> suppose I have a list of tuples, [ (a,1), (b,2) ... (k,5) ... (z,0)]
<Ramzi> and i want to see if the letter k appears in the list. and if so, increment the number next to it. So that (k,6) goes on the list
<thelema> look in the List module for assoc list functions
<Ramzi> is that the same as a hashmap?
<thelema> no, it's an association list - a list of pairs (key, value)
<thelema> maybe you're not allowed to use those functions - that'd make this problem pretty easy.
<thelema> but you probably could look at their implementation and learn from that.
<Ramzi> i think it's a different matter, actually. probably easier to code myself
<Ramzi> well, i didn't see anything in the lists associations about changing the value
<Ramzi> and i also want to preserve the order
<thelema> Are you allowed to use List.map?
<thelema> This problem seems pretty easy to do with that.
<Ramzi> i'm going to air on the side of caution
<Ramzi> i think this is a good exercise for me anyway. or do you think it's too hard?
<thelema> "err" on the side of caution
<Ramzi> I want to write a function called increment, that will take a list of 2-tuples.
<thelema> no, it's not too hard at all, it's just that the solution I'm thinking of basically is map + a simple transform function
<Ramzi> so match against ((char, num)::t). If the current tuple doesn't match, recurse on the tail
<thelema> Ramzi: don't throw away the elements that don't match.
<Ramzi> if it does match, push (char, num+1) on the front of t
<Ramzi> and return that merged with h
authentic has quit [Connection timed out]
^authentic is now known as authentic
<Ramzi> no, i'm wrong about that last line.
<Ramzi> confused myself with the recursion
<Ramzi> hmm, i think i've spotted bad code
<Ramzi> but maybe not. you tell me
<Ramzi> well, it's not, since it compiles. so then explain it to me.
<Ramzi> there's this compare function that takes 2 parameters.
<Ramzi> but yet List.sort compare l
<Ramzi> that works, with just 1 parameter.
<thelema> List.sort takes two parameters: compare and l.
goalieca has joined #ocaml
<Ramzi> ohhh. look how my brain parsed that
<thelema> if you look at the implementation of List.sort, every time it calls compare, it does so with two arguments
<Ramzi> right.
middayc has quit []
<Ramzi> so it reads starting from the left
<Ramzi> if i have a b c, and a takes two parameters, and b takes 1 parameter
<thelema> Just like English.
<thelema> no, b could take any number of parameters (if it's a function)
<Ramzi> yep.
<Ramzi> parantheses. that's my answer.
<thelema> a b c == (a b) c
<Ramzi> but it won't work out the correct answer if there is only one, right?
<thelema> only one what?
<Ramzi> a (b c d), so a takes 1 param, and b takes 2.
<thelema> yes.
<Ramzi> if it tried to interpret it as (a b) c d, then the c d are doing nothing
<thelema> if a only took one parameter, then applying c to (for example) a list would give a type error.
<Ramzi> ok
<thelema> technically, all functions take one parameter, and return a function that takes the next parameter
<thelema> let p1 = (+) 1 in (p1 2) * (p1 3)
<Ramzi> | 'a' .. 'z' -> 'A' .. 'Z' is a syntax error
<Ramzi> hmm, i hope i don't have to do 26 cases by hand, although it'd probably be faster that way
<thelema> | 'a' .. 'z' as x -> Char.uppercase x
<Ramzi> where do you find the Char api?
<thelema> it's quite spartan
<Ramzi> i mean, in general, to find the api of a class, how do you find it?
<Ramzi> for the list i could just google ocaml list and it came right up
<Ramzi> but not for ocaml char
<hcarty> Ramzi: Go up one level from the link thelema gave : http://caml.inria.fr/pub/docs/manual-ocaml/libref/
<Ramzi> ssdaa
<Ramzi> lol
<mbishop> I win
<mbishop> :P
<Ramzi> i clearly lost
<Ramzi> but i think hcarty typed a lot more than you
<mbishop> well that's his problem :P
<hcarty> In #ocaml, everybody wins!
<thelema> Ramzi: I start here when I want to look something up on ocaml: http://caml.inria.fr/pub/docs/manual-ocaml/index.html
<Ramzi> http://codepad.org/A0EdXD6Z i'm not following the nature of these errors.
<Ramzi> oh nvm
<Ramzi> grrr
<Ramzi> so I had this case [] -> () to get rid of the "warning pattern matching not exhaustive error"
<Ramzi> and I thought that units can "get thrown away"
<Ramzi> but that only occurs for lines that aren't "end lines"
<Ramzi> so there was a return type mismatch and I should have had [] -> []
<thelema> units can get thrown away, but if you end with a unit, it gets returned.
<Ramzi> right. i diagnosed it as soon as i hit paste.
<Ramzi> or, enter rather
coucou747 has quit ["bye ca veut dire tchao en anglais"]
^authentic has joined #ocaml
<Ramzi> thelema: did you get my pm?
<Ramzi> hmm
<Ramzi> well, i don't wanna register. :-P
authentic has quit [Read error: 110 (Connection timed out)]
^authentic is now known as authentic
<Ramzi> i think i'm all done. but the program is supposed to run on stdin
<Ramzi> i'm not sure how to do that
<thelema> what kind of input?
kelaouchi has quit ["leaving"]
<thelema> If you're comfortable with scanf, you can use that.
<Ramzi> let's do a simple one. suppose you have a program that will take in a word from stdin, and print it back out
<Ramzi> so you save this program in a .ml
<Ramzi> if you compile you get a.out right?
<Ramzi> something.out
<Ramzi> now it should be waiting for you type input, i think
<thelema> yes, you get a.out if you don't specify a executable name
<thelema> if you run it, it'll wait for you to type a word, yes
<thelema> (probably a whole line, using normal buffered IO)
<Ramzi> alright, then I want the user to type into stdin until they type ^D, at which time my program will take their input and manipulate it
<Ramzi> the way i wrote my program reads one char at a time from stdin
<Ramzi> but, i guess, i don't want it to start working until after they're done typing.
<Ramzi> is this making sense?
<thelema> probably won't do anything until the first line.
<thelema> when the user does ^D<enter>, the read_char will raise End_of_file
<thelema> if you want to do that, you'll have to buffer everything they type (Buffer.t seems appropriate), and then manipulate that.
<Ramzi> actually, when i do ocamlc my.ml it gives me camlprog.exe
<thelema> stupid windows.
<Ramzi> then when i run camlprog.exe, nothing happens. it doesn't wait for stdin
<thelema> does your program run any of its functions, or just define a bunch of functions and that's all?
<Ramzi> just defines them all. :-P
<Ramzi> that's the way the cmd prompt should look
<Ramzi> i want my code to kick in after the ^D, at which time the get_char from stdin will read the f in foo
<thelema> common practice defines a main () function, and ends the code with "let () = main ()"
<Ramzi> if i end the code will let () = someFunc()...
<Ramzi> ohhh let me try that
<thelema> how would you do that kind of input handling in C?
kelaouchi has joined #ocaml
<Ramzi> the same way
palomer has joined #ocaml
<palomer> anyone know of an equivalent to pango_parse_markup in lablgtk?
<thelema> in C, you could magically stop your program from reading input until ^D?
<Ramzi> if it's a file, i'd go till eof. for user input, i'd wait until i got the input i need, then stop. or return an error
<thelema> palomer: not I. pango_parse_markup doesn't appear in the lablgtk2 source.
<thelema> Ramzi: just only write output once the End_of_file is reached.
<Ramzi> thelema: I'm very sorry about tonight. My head is wonky. I got it it working.
<Ramzi> I needed to do let () = ... as psnively said earlier
<Ramzi> it seems with OCaml I have a lot of "ohhh" moments where it makes sense how things work.
<Ramzi> I was worried if I did let () = myMainFunc() then it'd start reading input when there was none
<Ramzi> but i realized that i hardcoded in a special flag for it to stop on, and not some eof character
<Ramzi> and that it would wait for input and the end flag before continuing
<thelema> C has an implied "main();" put in by the linker. Ocaml just evaluates everything you give it.
<thelema> and I don't know of any system where the basic IO functions read input even when there is none.
<Ramzi> remember our conversation about dumb thoughts being thought
<Ramzi> well, maybe in the future someone will use "basic IO functions reading input when there is none" in place of picklefeather
<Ramzi> and it would have already been thought before. by me
<thelema> heh.
mwc has quit [Remote closed the connection]
<Ramzi> thelema: do you use AIM?
<thelema> Ramzi: I think I had an account at one time.
<thelema> it's not in my IM client, only Jabber, ICQ and Yahoo
<Ramzi> earlier i said i confused myself with the recursion. i think i was right to be confused
<Ramzi> suppose I have a list of tuples, [ (a,1), (b,2) ... (k,5) ... (z,0)]
<Ramzi> and i want to see if the letter k appears in the list. and if so, increment the number next to it. So that (k,6) goes on the list
<thelema> yes...
<Ramzi> we said to just push (char, num+1) in the front of the tail
<Ramzi> but you need to do more than that.
<thelema> and I tried to remind you not to throw away other elements.
<Ramzi> ah, it's all coming back to me now
<Ramzi> lol
<thelema> :)
<Ramzi> you're right. you're right.
<Ramzi> believe me though when I say I read it, but i just didn't interpret it correctly. :-P
<thelema> I'm sure there's all sorts of pieces of advice you weren't ready to hear properly when they were given.
<Ramzi> thanks? :-)
<Ramzi> list @ something appends to the end of a list, right?
<Ramzi> basically, in my code, if I have (list @ (currChar, 1)) it doesn't work, but if I have ((currChar,1)::list) it does.
<thelema> @ appends two lists
<Ramzi> right!
<Ramzi> that's experience right there
<thelema> you probably want (currChar,1) :: recursive_call tail
<Ramzi> if i made this mistake yesterday i woulda caught it since i was using the @ left and right
<Ramzi> thank you for your continuing help these past days.
<Ramzi> i'm done for tonight. i got it working.
<thelema> n/p
<thelema> good night
<Ramzi> i've had a very positive experience learning ocaml.
<Ramzi> my code runs correctly so quickly. either with no debugging, or very easy to catch errors.
<Ramzi> compilation is the tricky part. but it catches that for you.
<thelema> yup, we love static typing.
<thelema> there's just some improvement possible in the compiler's error messages
<Ramzi> yeah
<Ramzi> or just with experience
<Ramzi> like the @ thing. the compiler isn't gonna say, "put some brackets around that yo"
<Ramzi> in my head list @ element was the same as list @ [element]. with experience those errors will be easier for me to spot
<Ramzi> other than that. smooth sailing. alrighty, goodnight.
Ramzi has quit ["http://irc.netsplit.de/"]
r0bby has quit [Remote closed the connection]
<palomer> man, I've spent 3 weeks rewriting this code from haskell to ocaml
<palomer> and the ocaml code is sooo much cleaner
<dobblego> let me guess, you blame Haskell, not yourself
|Catch22| has quit []
<palomer> It's more like I find the object system very helpful for writing clean code
r0bby has joined #ocaml
<palomer> though I find your statement a little insulting, especially since I don't know you
<dobblego> I am guessing; I'm not sure where the insult comes from
<palomer> that I am the sole reason that my code would be ugly and I would be too naive to see it
<dobblego> why is that an insult?
<palomer> with a hint of sarcasm
<thelema> if you had written the code in ocaml first, it'd be much cleaner after translating to haskell, I bet. Most of the cleaning is you understanding the problem better, I bet.
<palomer> no way!
<palomer> I would have kept the same design in haskell
<palomer> (I see no other way to do it)
<dobblego> perhaps that's the problem
<thelema> fair enough - ocaml does allow imperative code when that's more appropriate, and this can make code cleaner
<dobblego> so does Haskell
<palomer> there isn't a problem; only a simple conclusion: the ocaml object system fits my problem very well
<palomer> and the imperative stuff helps a little too
<palomer> (bye bye mapM and friends!)
<thelema> palomer: you had to work hard to wrap your brain around the ocaml object system
<palomer> thelema, yes, and it still surprises me
<palomer> but my code is cleaner for it
<dobblego> mapM has nothing to do with imperative code
<dobblego> you might mean mapM_, which still doesn't, but looks more like it does
ttamttam has joined #ocaml
ttamttam has left #ocaml []
<palomer> if I'm going to map a function a -> m b (which, to me, is the closest thing I have to an imperative function) to a list of values, then I have to use mapM
<dobblego> that has *nothing* to do with imperative code
<dobblego> perhaps we are now exposing the problem
<palomer> a. there isn't a problem
<palomer> b. I should know better than to argue with a haskeller about this, my apologies
* palomer is off
<dobblego> I am not a Haskeller
<dobblego> I just don't pass unqualified comment
<thelema> palomer: cheers
<dobblego> it seems I have been trolled, oops
dobblego has left #ocaml []
<palomer> ok, I'm back:P
<palomer> man, I don't like how those haskell guys talk! why can't we all be friends!
TSC has joined #ocaml
<palomer> http://lambda-the-ultimate.org/node/2727 <-- a nice discussion on how to have side effects without mapM and friends
<palomer> and, to end the discussion, compare the code List.map (fun x -> print_int x) [1;2;3] with sequence $ mapM print [1,2,3]
<palomer> then again, I'm not arguing with anyone anymore<:O
<palomer> but yeah, the bummer with haskell is that I had to sprinkle type classes everywhere to get something similar to inheritance
<thelema> palomer: you probably mean List.iter
<palomer> thelema, righto
<palomer> (though both work, right?)
<thelema> well, List.map would produce a nice list [(),(),()] as return
<palomer> which would give me a warning
<palomer> and then I would insert an ignore
<palomer> I have ignore sprinkled in many places
<thelema> List.iter print_int [1;2;3]
<palomer> ignore(\n\tcode\n); <--this is a typical pattern in my code
<Jedai> palomer: "sequence $ mapM print [1,2,3]" the sequence in this code is completely unnecessary (in fact it will be a type error), which somehow makes me doubt your knowledge of Haskell (and map instead of iter ditto for Ocaml)
<thelema> About the only time I use ignore is to throw away the taskID of a scheduled idle job. (no way to schedule job without returning a taskid, which usually I don't care about, as I won't cancel the job.
<Jedai> So I don't see how "mapM_ print [1,2,3]" is more complicated than "List.iter print_int [1;2;3]" (or less by the way)
<palomer> ahh, righto, I was thinking sequence $ map print [1,2,3]
<palomer> 1. sometimes you have to use map, sometimes mapM
<palomer> 2. you have to put liftM in many places
<Jedai> palomer: Yeah, so in this case you use mapM_, the type says it all
<palomer> Jedai, how long have you been programming in haskell?
<Jedai> palomer: Ok, it seems dobblego remarks was completely just, you don't know Haskell well, neither OCaml, but you're more at ease in OCaml because its multi-paradigm allows you to use a familiar style most of the time
<palomer> 1. I've been programming in haskell for 3 years
<Jedai> palomer: Now ? Maybe 2 years
<palomer> 2. if you can't see how having one function instead of 2 for the same purpose is helpful, then I can't convince you of anything
<Jedai> palomer: And you still don't know the difference between sequence/map/mapM ? I'm worried
<palomer> ho hum, I'm not going to argue with you
<palomer> think what you like, I'm leaving (for real this time)
<Jedai> palomer: iter and map are different functions, besides Haskell is all about purity, it seems normal that you use different functions to deal with monadic effects than with non-monadic values
<Jedai> palomer: the monadic variations works for others monad than IO you know, and in this case they have very different semantic than their non-monadic inspiration, using the same name for both version would be utterly confusing
<palomer> Jedai, I'm not saying haskell should lose mapM and friends
<palomer> Jedai, all I'm saying is that if you're code is heavy with side effects, then it can be helpful to not have to use (and abstract over) two sets of functions
<palomer> http://lambda-the-ultimate.org/node/2727 <--which is what these guys are trying to accomplish
<palomer> anyways, no hard feelings, you seem like someone who knows what they're talking about
* palomer is REALLY off to code this time
Demitar has quit [Read error: 110 (Connection timed out)]
ikaros has joined #ocaml
ttamttam has joined #ocaml
ttamttam has left #ocaml []
Yoric[DT] has joined #ocaml
Tetsuo has joined #ocaml
jsk has quit ["Leaving."]
Snark has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
jsk has joined #ocaml
Mr_Awesome has joined #ocaml
goalieca has quit [Remote closed the connection]
bzzbzz has quit [Read error: 104 (Connection reset by peer)]
bzzbzz has joined #ocaml
ttamttam has joined #ocaml
ttamttam has left #ocaml []
magnusth has joined #ocaml
petchema has joined #ocaml
ikaros has quit [Remote closed the connection]
Yoric[DT] has joined #ocaml
<Yoric[DT]> hi
<rwmjones> morning
hsuh has quit [Remote closed the connection]
jsk has quit ["Leaving."]
<Yoric[DT]> Mmmhhhh...
<Yoric[DT]> I have a small problem with sdl.
<Yoric[DT]> When linking in native mode, I encounter "/usr/bin/ld: cannot find -lsdl".
<Yoric[DT]> I probably got something wrong with my arguments.
<rwmjones> are you missing libsdl-dev?
<Yoric[DT]> I assume I don't, since I succeeded in compiling sdl itself.
<Yoric[DT]> I mean ocamlsdl itself.
<Yoric[DT]> That and the bytecode version works.
<qwr> palomer: in some sense List.map and List.iter are fundamentally different operations - first is transformation and second is invocation of action
<qwr> palomer: haskell just differentiates these explicitly
<Yoric[DT]> ok, problem solved
* qwr . o O ( you didn't have it in library path? )
<Yoric[DT]> Actually, I attempted to link it twice.
bzzbzz has quit [Read error: 110 (Connection timed out)]
<Yoric[DT]> (my ocamlbuild-fu is not strong yet)
Yoric[DT] has quit ["Ex-Chat"]
hkBst has joined #ocaml
bzzbzz has joined #ocaml
<rwmjones> what would List.iter mean in Haskell? surely it couldn't have any side-effects so would be useless
filp has joined #ocaml
coucou747 has joined #ocaml
jsk has joined #ocaml
delamarche has joined #ocaml
<Smerdyakov> rwmjones, it would probably be a monad fold operation.
<magnusth> rwmjones: or the mapM_ operation
schme has joined #ocaml
^authentic has joined #ocaml
^authentic has quit [Read error: 104 (Connection reset by peer)]
^authentic has joined #ocaml
comglz has joined #ocaml
prince has quit [Client Quit]
^authent1c has joined #ocaml
authentic has quit [Read error: 110 (Connection timed out)]
^authent1c is now known as authentic
^authent1c has joined #ocaml
^authent2c has joined #ocaml
^authentic has quit [Read error: 110 (Connection timed out)]
filp has quit ["Bye"]
authentic has quit [Read error: 110 (Connection timed out)]
^authent2c is now known as authentic
^authent1c has quit [Read error: 110 (Connection timed out)]
ertai_ is now known as ertai
Yoric[DT] has joined #ocaml
ikaros has joined #ocaml
ikaros has quit [Read error: 104 (Connection reset by peer)]
ikaros has joined #ocaml
TheLittlePrince has joined #ocaml
delamarche has quit []
delamarche has joined #ocaml
schme has quit [Read error: 110 (Connection timed out)]
ttamttam has joined #ocaml
ttamttam has left #ocaml []
Yoric[DT] has quit ["Ex-Chat"]
pango_ has quit [Remote closed the connection]
^authentic has joined #ocaml
evn has joined #ocaml
pango_ has joined #ocaml
marmottine has joined #ocaml
comglz has quit [Client Quit]
postalchris has joined #ocaml
authentic has quit [Read error: 110 (Connection timed out)]
^authentic is now known as authentic
mikeX has joined #ocaml
evn has left #ocaml []
<qwr> rwmjones: I meant mapM_ as List.iter like iteration in haskell
<rwmjones> ok ... it's been about 12 years since I really used Haskell in anger
<qwr> mapM_ f l = sequence_ (map f l), that is mapping each list element into monadic action and composing those into action sequence
ita has joined #ocaml
TheLittlePrince has quit [Client Quit]
evn has joined #ocaml
evn has quit [Remote closed the connection]
ikaros has quit [Remote closed the connection]
bluestorm has joined #ocaml
psnively has joined #ocaml
magnusth has quit ["Ex-Chat"]
alexyk has joined #ocaml
<alexyk> greetings -- I have a seemingly tail-recursive function to process a file line by line and print to other files; yet it causes stack overflow and grows while runs
<alexyk> let main () =
<alexyk> let rec do_line ic col_old col_sum cols rows vals =
<alexyk> try
<alexyk> ...
<alexyk> do_line ic col col_sum' cols' rows' vals'
<alexyk> | _ -> failwith "bad triplet"
<alexyk> with End_of_file -> (col_sum+1, cols+1)
<alexyk> in
<alexyk> let lastCsum, lastCols = do_line stdin 0 0 0 0 0
<alexyk> as you can see, the do_line is the nested rec function reading lines
<alexyk> and it calls itself at the very end of itself but the | _ default match
<alexyk> does it break tail recursion? why doesn't ocamlc/opt optimize it?
<thelema> try/with block breaks tail recursion.
<alexyk> argh -- so that was the idiom I used to read files line by line; should I switch to a for loop?
<flux> it's a shame that there is no good functional standard idiom for reading files
<thelema> no, just wrap your input function so it returns an option.
<flux> however, I've used the approach of converting exceptions to values
<thelema> flux: some of the libraries I've evaluated include "iter over file line-by-line" and "char-by-char" functions. They're not hard to write.
<flux> thelema, and how would one use those to merge two files? difficult :/
<psnively> Sounds like you want zippers. :-)
<thelema> granted - the right way to do that involves lazy streams. Extlib's Enum module seems very appropriate.
<flux> streams don't work if you want to go back and forth in the file
<hcarty> There are some posts on the list about this: http://groups.google.com/group/fa.caml/browse_thread/thread/1048a73fbfb2024a
<flux> or even just back, if you don't happen to provide such an enumerator
<flux> (for implementing 'tac')
<flux> I suppose the lower layers are still there, though, even if nicer interfaces exist
<flux> while it is good to optimize for the common case, it's good to remember the other cases too :)
<thelema> make the common case easy, make the uncommon case possible
<qwr> so you provide multiple apis - with lower and higher abstraction levels
* qwr thinks that is ok
<qwr> since nice highlevel apis tend to make some "hacks" impossible
<qwr> and random-access can be considered as a "low-level hack" here
<qwr> (it won't even work with all sorts of file handles - like pipes)
<hcarty> I think these are the kinds of APIs the core OCaml folks want to community to put together
<psnively> I think we need to hound Oleg into providing native delimited continuations for native OCaml, and develop these kinds of APIs around them.
rwmjones has quit [Read error: 104 (Connection reset by peer)]
rwmjones has joined #ocaml
<alexyk> thelema: beautiful, stack stays constant! Another reason to kick "Practical Ocaml" -- I took the file reading idiom from there
<thelema> alexyk: good job.
<alexyk> file setup question: when I have several globals and functions in a file, why do I have to terminate each with ;; as in toplevel? Is the whole file read like in toplevel even by ocamlc?
<thelema> you don't have to.
<thelema> if you're not using the toplevel, ;; is optional.
<thelema> that said, you may find the source of a typo sooner if you use them.
<alexyk> ah I see -- I develop in tuareg and send buffer to toplevel to check syntax, which wants ;;
<alexyk> BTW -- do any of you guys develop in F#? I've installed (gasp) a Visual Studio in a VMWare Fusion on my Mac and it highlights syntax errors as I type
<alexyk> I ran back to Emacs/tuareg/ocaml since that's what I'm more used to -- but Mono is here too
<hcarty> OcaIDE does something similar for OCaml I think, though from what I have heard it is less advanced than the F# support in VS
* thelema uses emacs
<alexyk> and #light syntax is much nicer in F#
<hcarty> emacs here as well, because its auto-indent catches bugs for me
<hcarty> s/bugs/typos/
Demitar has joined #ocaml
<alexyk> so why can't ocaml get a #light syntax with camlp4?
Linktim has joined #ocaml
<hcarty> No one has written one. There is ocaml+twt, but it is a preprocessor separate from camlp4
<alexyk> yes, saw that and also threads on fa.caml to the effect that #light is somehow very hard even with camlp4
<bluestorm> i've done something a bit like #light with camlp4 when learning it, but i'm not satisfied with it, it's not usable as-is, and i did that as a proof of concept anyway
<bluestorm> i guess it's doable but as we have ocaml+twt, it seems nobody bothered to write one
<bluestorm> alexyk: wouldn't ocaml+twt fit your needs ?
<alexyk> bluestorm: does it work with emacs/tuareg setup?
<bluestorm> i'm not sure, but iirc there was an adapted mode
<bluestorm> « Emacs/VIM/etc. modes: use with extreme caution; this is a new syntax, after all. My experience is that tuareg is generally usable (with some manual corrections necessary), but you have to be very careful about checking whether it has inserted spaces or tabs. (See below for an experimental emacs mode) »
<bluestorm> alexyk: if you're fluent with elisp, you could write something for the "on the fly syntax checks"
<bluestorm> there is a emacs framework for that (flymake iirc) and camlp4 could probably provide the necessary capacities
<bluestorm> (that's not easy for sure, but i think it could be done, without writing another syntax checker)
<alexyk> bluestorm: need to develop in ocaml first, elisp second :) am readling Practical Common Lisp though
<bluestorm> if you want to learn elisp, there is an in-emacs manual wich is not bad at all
<bluestorm> (emacs documentation is generally quite good in my experience)
<alexyk> bluestorm: agreed, but a book is so much better, and PCL is awesome -- that's why Practical OCaml is such a bummer
<alexyk> is Hashtbl the direct equivalent of perl/python/ruby hashes? If I have a huge input list with repetitions, can I just stick things into a Hashtbl for counting distinct ones?
<bluestorm> you can think of an hash table as an array with keys of any type (in your case, string)
<bluestorm> so the answer must be "yes"
<bluestorm> for example you can create an (string, int) Hashtbl.t that would record the number of occurences of each string
<alexyk> so why does Hashtbl want an initial size while perl/python/ruby ones don't need one?
Linktim_ has joined #ocaml
<thelema> alexyk: performance / implementation reasons
<thelema> I suppose perl/python/ruby hashtables have a default size.
<alexyk> wonder why ocaml exposes that
<psnively> So as not to make assumptions about your Hashtbl usage patterns.
<alexyk> making me think hard where thinkin' is scarce already :)
<hcarty> alexyk: You can set the initial size to anything - it will grow to be as large as needed
<thelema> alexyk: don't think that hard.
<hcarty> If you have a reasonable guess for your initial size, then it just means that it has to grow less, or not at all
<alexyk> if it's huge, will it preallocate? I have millions of customers to process and a sparse list at that, so I need to remap them to consequtive integers
<thelema> hcarty: you pay a CPU/GC penalty for guessing too small, and a RAM penlty for guessing too large. But neither penalty is severe. Order of magnitude guess suffices.
Linktim- has joined #ocaml
<alexyk> so if I give a 10M initial number, will it claim RAM right away?
<bluestorm> yes
<bluestorm> 10 M is not very reasonable unless you really expect 10M items
<alexyk> ah, effective, not the key range?
<bluestorm> of course
<alexyk> ok
<thelema> not the key range, the size of the initial array to hash into.
<alexyk> cool, that I know
* qwr . o O ( what's wrong with vim? :P )
<alexyk> um, the syntax is not OO-like? Hashtbl.blah my_hash anything?
<hcarty> qwr: The indenting is slow and/or inaccurate in my experience
<hcarty> Otherwise I never would have gone to the Dark Side (emacs)
<ita> qwr: the highlighting gets wrong too easily
<hcarty> alexyk: It's not an OO module
smimou has joined #ocaml
<alexyk> any OO wrappers around Hashtbl out there?
* qwr hasn't really noticed the slowness. although maybe I haven't used right vim scripts ;)
<Smerdyakov> alexyk, most OCaml programmers don't like OO.
<psnively> Why would you want one?
<psnively> ==Smerdyakov
Linktim has quit [Connection timed out]
<alexyk> well, h.add x y looks better than Hashtbl.add h x y (* IMHO *)
<qwr> alexyk: you can write OO wrapper for it. although i don't really see why it should matter.
<alexyk> Smerdyakov: then why not SML/NJ all the way?
<ita> alexyk: you are used to it ..
<hcarty> qwr: omlet seems to have the best indentation, but once files get over ~100 lines it gets very slow... 10s of seconds to indent a new line in my experience
<Smerdyakov> alexyk, I always choose SML over OCaml when I'm not integrating with existing OCaml software.
<qwr> hcarty: haven't used it. probably won't either, if it's so slow.
<flux> my personal rationale for preferring foo#bar instead of Module.bar is that once I've told the language what foo is, I should be able to drop all that repetition :)
* qwr can sometimes use tab/backspace to change indention level...
<psnively> There are good reasons to like SML. There are good reasons to like OCaml.
<alexyk> Smerdyakov: is the non-OO core the same enough? how often the difference from your comparison table are really exercised?
<flux> I still don't wrap Hashtbls into an object, though
<Smerdyakov> alexyk, the cores are very similar.
<Smerdyakov> alexyk, and I don't understand what you mean by "the same enough." Enough for what?
<alexyk> Smerdyakov: same enough for brain damage not to occur! :) And what about performance?
<qwr> alexyk: if you mean whether ocaml can compile sml or sml ocaml, then no
<Smerdyakov> alexyk, performance is one of the items on my comparison. SML has a much better situation than OCaml there.
<Smerdyakov> alexyk, and I'm a programming languages research PhD; I know far more than 2 programming languages, with no signs of brain damage yet. ;-)
<alexyk> Smerdyakov: saw that, just was wondering if you achieved ease of switching between two very similar languages after a while, and whether you still stop and thing of ~1 and -1 and such
<Smerdyakov> I have no problem switching. I don't know if that says anything useful for anyone else.
Linktim_ has quit [Connection timed out]
<Smerdyakov> Also, I don't negate number very often. ;)
<alexyk> Smerdyakov: I noticed when I dabble in Haskell/Erlang/OCaml I constantly refer to a comparison table in my mind similar to yours for SML/OCaml
<Smerdyakov> alexyk, OK. Not everyone works like that.
<Smerdyakov> It's definitely bad if you "think in" one language while programming in another.
<alexyk> but it's easier if languages are *more* different -- I want to see common themes and they're clearer if described in different enough terms
<delamarche> alexyk: Smerdyakov is right, if you read enough about the discipline of software development and play around with enough languages, you think less about the language you have
<delamarche> and more about how you would naturally express something
<delamarche> and then you think about how you're actually going to have to do it in your language :)
* qwr hasn't really hasn't had more problems than writing lets into haskell toplevel and omitting them from ocaml...
<delamarche> Steve McConnell has a good discussion of this in Code Complete, he calls it "programming _into_ a language"
<alexyk> Smerdyakov: no, once I delve into a langauge I think in it, but like to cross-compare to see what is the underlying idea which can be expressed in this language in this way and in other languages in other ways. E.g. is this language expression possible due to the syntactic sugar or is it a universal idea?
<delamarche> I liked it, at least.
<qwr> alexyk: you're still learning the language then
<alexyk> qwr: surely
<Smerdyakov> This is a great time to be involved with programming languages, because I think we finally have the pieces together that you can program by writing exactly what you mean for many domains.
<Smerdyakov> I'm not saying you can do this with OCaml. The type system is too inexpressive, if nothing else.
<alexyk> Smerdyakov: do you prefer Haskell then? :)
<qwr> Smerdyakov: and still all languages suck in some way. but i'm still happy to have ocaml and haskell :P
<Smerdyakov> alexyk, no, I prefer Coq.
<psnively> You'd think that we'd have direct support for existential and universal quantification by now...
<psnively> Smerdyakov: What, if anything, do you make of YNot?
<Smerdyakov> psnively, interesting, but I think imperativity shouldn't be around much longer for anything but OS and development tool coding.
<psnively> Thanks. :-)
<thelema> Smerdyakov: what are you thinking about when you say "development tool" in this context?
<Smerdyakov> thelema, the overall category of things that I'm saying will use imperativity is software that supports applications, rather than being an application.
<thelema> it makes lots of sense to me that an IDE should be written in a high level language, even the compiler.
<Smerdyakov> thelema, I'm giving an upper bound, not an exact characterization.
<thelema> so you're thinking things like libc? I understand the OS being in an imperative language.
<thelema> but I don't understand the separation you're trying to make.
<Smerdyakov> The important property is that it's software that you don't need to write very often.
<delamarche> booya
<delamarche> I think Smerdyakov must find me annoying, because he makes well-articulated statements about things, and then I agree with them using such profound epithets as 'booya'.
<thelema> Why do you think there's no need for new OSes?
<Smerdyakov> thelema, who said that?
<thelema> delamarche: I imagine he finds me more annoying, forcing him to say what he means...
<alexyk> this link tells of what to do with Hashtbl to look nice: http://t-a-w.blogspot.com/2006/05/ocaml-programming-best-practice.html
<alexyk> is it in any of the extended libraries by now or do I have define my own ht_keys still?
<thelema> Smerdyakov: well, you seem to say that the category of imperative software is that which doesn't need to get written often. I imagine a world with one OS, but realize that won't happen. There'll always be a need for new OSes. But you imply otherwise with your generalization about not being written very often.
|Catch22| has joined #ocaml
<Smerdyakov> thelema, oh, I see. I'm thinking along the lines of one OS, too. I don't care what most developers are doing; I only care what needs to be done to produce quality results.
Linktim_ has joined #ocaml
<thelema> and I guess I'm saying that one OS won't produce quality results in all places needing an OS.
ttamttam has joined #ocaml
<Smerdyakov> I think you aren't thinking of an OS offering the right primitives.
<Smerdyakov> The right primitives for an OS to offer are ways of enforcing isolation. Folks should be able to add whatever they need if it plays well with that mechanism.
<Smerdyakov> I'm in favor of static mechanisms and single-address-space systems.
* thelema has been impressed with singularity too.
<thelema> (at least some of it)
<thelema> but I admit that such an OS might have difficulty scaling from cell-phones / embedded devices to PCs to supercomputers
<Smerdyakov> I don't think there needs to be any scaling problem.
<thelema> I admit moore's law will enable lots of capability in even the low end, but it's my understanding that there's some basic tradeoffs in design that will favor one end of that spectrum or the other.
<Smerdyakov> Like what?
<thelema> like the difference between arrays and resizable vectors - fixed limits with high efficiency vs. no limits with lower efficiency
<Smerdyakov> Why would that be related to low-level runtime system support? Why couldn't you have a runtime system supporting both?
<thelema> I'm referring to how bits of the kernel are implemented.
<Smerdyakov> I'm not a big fan of kernels that are more than proof checkers.
<thelema> proof of type-safety, yes... but there's still work for the kernel to do in handling devices.
<Smerdyakov> I don't agree.
<thelema> you prefer an extreme microkernel?
<Smerdyakov> I think that all programs should be able to interact with hardware directly.
<Smerdyakov> I prefer extreme microkernels that are proof checkers.
<thelema> and given some static safety, you can guarantee that programs are well behaved...
alexyk has quit []
<qwr> Smerdyakov: kernel would statically check that the programs don't use resources that are not allowed for them?
<Smerdyakov> qwr, the kernel would only check that programs do what they claim to do.
<Smerdyakov> qwr, this lets you build up software based on whatever abstractions you like.
<thelema> well, characterizing what a program claims to do seems a magical skill.
Linktim- has quit [Read error: 110 (Connection timed out)]
<Smerdyakov> thelema, what do you mean? I'm talking about specifications in higher-order logic.
<thelema> people can do that, but we still elide tons of details.
ygrek has joined #ocaml
<thelema> doing so in a formal manner seems... unwieldy. I imagine proofs of simple programs that are much larger than the program itself.
<Smerdyakov> It's easy to include all the details you need for isolation purposes.
<Smerdyakov> And it's very easy to automate the proofs.
<Smerdyakov> You just need to start with languages with proper static controls.
<thelema> in the right language, yes.
<qwr> Smerdyakov: and what about existing software? write a highlevel vm's for them?
<Smerdyakov> qwr, yes, though hopefully mostly toss them to the curb. :D
<thelema> qwr: that's the best one could do in such a system.
Linktim_ has quit [Read error: 110 (Connection timed out)]
<Smerdyakov> thelema, static analysis to determine where dynamic checks are needed can also be very effective.
ttamttam has left #ocaml []
<thelema> Smerdyakov: I'm strongly in favor of such analysis, and would love to implement such on ocaml's arrays
<thelema> Smerdyakov: talking about pluggable verification, I imagine that would handle such things as memory access (at a minimum) and at higher levels, data security (proving a program doesn't leak "top secret" data
<Smerdyakov> Sure. Those (type safety and information flow) are the main focuses of research on lightweight static analysis.
<thelema> I imagine your idea of scaling would involve a simple system like an embedded device not doing information flow analysis
<Smerdyakov> There are all sorts of options there, including cryptographic signing of analysis results by beefier machines.
<thelema> and more complex systems having more stringent requirements as to the programs they'll accept.
<thelema> this falls into microsoft's attempts at "signed code = secure code" pretty nicely.
delamarche has quit []
<thelema> except their implementation of such involves no static analysis.
delamarche has joined #ocaml
<thelema> I imagine some people being very happy to set themselves up as a trusted authority (like verisign with SSL certs) for certifying safe code.
<thelema> in which case, your kernel simplifies to a crypto-cert checker.
<thelema> (much simpler than a proof checker, I'd imagine)
<thelema> and why not just have the proof checker be a module of this simpler system - having it signed by some authority gives better assurance it's valid than just that it happens to sit at the beginning of your hd0
ttamttam has joined #ocaml
ttamttam has left #ocaml []
* thelema finished thinking aloud
jlouis has joined #ocaml
Ramzi has joined #ocaml
Snark has quit ["Ex-Chat"]
<Ramzi> thelema: you in?
<Ramzi> I want to talk about "the philosophy of OCaml," which I guess I could do with others of you.
<Ramzi> But I'd like for thelema to be here to participate.
<thelema> I is. go ahead
<Ramzi> Okay. So as you know I've had a very pleasant experience with OCaml.
<Ramzi> And I thought of how I would explain to others why it's great. But it seemed like, the answers I came up with can also be true for other languages.
<thelema> yup, that makes it harder to evangelize.
<Ramzi> For example, I would have said, thinking in OCaml forced me to break up functions into short meaningful chunks.
<thelema> what's great about ocaml isn't any one thing, it's the balance between a million things.
<Ramzi> In JAVA, for example, I usually one method with tons of stuff in it. Loops and stuff.
<Ramzi> But none of my ocaml functions exceeded 20 lines.
psnively has quit []
<thelema> I have longer functions, but it's usually natural to break them down into smaller ones, and since it's so easy to do so...
<Ramzi> What this allowed for was, seeing if a "function part" was coded correctly, based on the interpreter telling you what the inputs and outputs are.
<thelema> yup, ocaml encourages good functional decomposition of problems.
<Ramzi> This allows "testing as you go," sort of, rather than finishing the project and having to step through a ton of code to find where the error starts.
<Ramzi> But really, doesn't that just mean I'm a bad JAVA programmer? :-P I mean, JAVA may encourage a laziness.
<Ramzi> But it by no means necessitates it.
<Ramzi> And the lessons learned from OCaml, such as decompisition of problems, can be applied to JAVA.
<thelema> yes, but the ease of decomposition won't quite be there.
<thelema> so in a way, java encourages you not to decompose
<Ramzi> I also felt like, "When the interpreter tells you what the domain/range is, you can know if you made a mistake in your code, if they don't match what you wanted."
<Ramzi> But the same is true in JAVA, because you TELL IT what the domain and ranges are. And the JAVA compiler will yell at you if you try returning the wrong thing.
<thelema> it's easier for a person to look and see that the types are correct than to figure out what the type should be. Especially with more complex types (which Java doesn't really give you)
<Ramzi> Another thing I would have said was, code often ran correctly the first time in OCaml, which is rare for me in JAVA. But it took me a lot longer to code in OCaml. Maybe if I coded slower in JAVA, I would have to debug less.
<Ramzi> You mean that OCaml helps you see "what the types should be"?
<thelema> the part of the process of coding where the compiler is involved is more with ocaml, and the part where the debugger is involved is more in Java.
<Ramzi> Right. But that needn't be the case.
<Ramzi> If I planned more rigorously in JAVA, I wouldn't have to debug as much.
<thelema> ocaml tells you the type, and you verify that those work for you. But in Java, you have to come up with the type and the compiler tells you if you're "right"
<Ramzi> I'm not sure that's true. I still had to decide that I'll have a function that takes a list of tuples.
<Ramzi> This is no different than deciding in JAVA to have a function that takes an ArrayList.
<Ramzi> Don't get me wrong, I really *feel* that there is more rigor to OCaml.
<Ramzi> But I can't express it.
<thelema> You do still have to keep types in your head for different identifiers, but I can write a function whose type would be difficult for me to express.
<thelema> (actually, I have, in my command-line argument parser)
<thelema> but mainly that's because the type was so long, and I was only dealing with one part of that composite at a time in my code.
<Ramzi> What if I asked you, "What is OCaml good for?"
<Ramzi> I don't think it's unfair to admit that different languages are better for different tasks. So what's OCaml's strength.
<thelema> I'd have to answer: it's general purpose. It won't best other languages in their areas of specialty, but encroaches on many of them. It's especially suited for 1) AST processing and 2) complex numerical code.
* qwr fucking hates java. it has so high penalty on using abstraction and separating code into small separate pieces
<Ramzi> qwr, care to expand?
<Ramzi> thelema: have you ever used mathematica?
<thelema> yes.
<Ramzi> What do you think of it?
<thelema> pretty, and specialized.
<qwr> Ramzi: yes. i prefer to not mix code with different intents
<qwr> Ramzi: which often means parametrizing code with other code blocks
<qwr> Ramzi: and what is smallest independent code block that you can pass?
<qwr> Ramzi: a fucking class
<Ramzi> hah
postalchris has quit [Read error: 110 (Connection timed out)]
<Ramzi> that's an exageration. The methods of a class should be considered the "independent code block."
<qwr> Ramzi: so i write two line function and 5+ lines anonymous class to pass it?
<thelema> Java lost me when I tried to return a pair from a method. ick.
<qwr> Ramzi: you cannot pass a method as argument
<Ramzi> sort of, you can. you just embed that method into the argument.
<Ramzi> for example, yesterday the issue of sort came up.
<Ramzi> You said List.sort takes two arguments, a compare function, and a list.
<qwr> Ramzi: and then? yes you can sometimes play games with interfaces
<Ramzi> But let's say I had a list of Objects in JAVA. The compare function would be inside the object.
<qwr> Ramzi: how it will get inside it?
<Ramzi> I mean, really you're still writing the same compare. Just one exists in the object, and the other does not.
<qwr> Ramzi: you have to hardcode it into specific object
<Ramzi> qwr: In the class, you add a public method called compare.
<qwr> Ramzi: or derive extra class
<qwr> Ramzi: yes i know. that's hardcoding it into object
<Ramzi> qwr: You hardcode it into a specific class.
<Ramzi> The object, which is an instance of the class, already contains the code.
<qwr> Ramzi: often it creates code associations where there is none naturally
<Ramzi> You think there is no association between an object type, and the way to compare the object type?
<qwr> Ramzi: depends.
<qwr> Ramzi: but often yes. you may have different possible sort orders for example
Yoric[DT] has joined #ocaml
<qwr> Ramzi: all i can say, that i have often multiple anonymous classes per hundred lines of java code. and i still feel that there is much unnatural coupling in that code.
<Ramzi> I forgot what it's called. It's either comparable or comparator.
<qwr> Ramzi: Comparable
<Ramzi> But there are ways for you to write different compare functions based on the attribute you wish to look at.
bongy has joined #ocaml
<Ramzi> Hmm, what if I made this philosophical claim.
<Ramzi> Given that I could write a program object orientedly, or functionally, such that the user could not distinguish which one was done how...
<Ramzi> this must mean that both approachs are isomorphic to each other.
<Yoric[DT]> That's the idea behind scala.
<palomer> if class A inherits from class B, is it possible to call the initializer of B when creating an A ?
<qwr> Ramzi: what attribute?
<qwr> if you have multiple compare functions per data object
<qwr> those function _DO NOT_ belong to the data object
<qwr> and shouldn't be coupled with it
<Ramzi> let's say you have a class Dog, and you want to sort them by age, name, color, type, etc.
<flux> palomer, the initializer is called automatically?
<qwr> then write separate function for each comparision
ita has quit [Remote closed the connection]
<Ramzi> and it shouldn't be in the data object?
<qwr> no
<bluestorm> in practice, most concepts you'll manipulate when writing programs (unfortunately ?) are _not_ dogs
<Ramzi> what about statically?
<Ramzi> haha
<Ramzi> look, I understand that it's unnecessary to create objects when you're just trying to do some mathematical operations.
bla has quit [Read error: 113 (No route to host)]
<bluestorm> i've found the idea of "the world is object" to apply very well in a programmer view of the outside world, but no so well when writing, say, a compiler
<Ramzi> i'm with you.
<Ramzi> hmm...
<qwr> and user doesn't really matter here - you could write you're program in assembler and wouldn't still notice
<Ramzi> so what are we trying to compare? Ease of writing?
<bluestorm> (one could say it means that programmers have a much better knowledge of compilers than of the outside world :-' )
<qwr> but it would be unmaintainable mess and take awful lot of time to write
<qwr> Ramzi: for a program longer than 1 line you wont write it. you'll modify existing code
<Ramzi> Is there a fact of the matter about which is more effective, or is it personal preference?
<Ramzi> I mean, if you're a boss who wants his workers to get the job done quickly, will you have them write in OCaml or JAVA? I'm sure there must be a study.
<Ramzi> *job done quickly and correctly
<bluestorm> i guess it depends on what the job is
<Ramzi> For a game, probably java. For some numerical analysis, perhaps OCaml?
<qwr> Ramzi: Ocaml if they'll able to learn it and client don't have requirements on the platform where that software will run
<Ramzi> thelema seems to have disappeared.
<Ramzi> Well, yesterday I did a problem in OCaml, and it forced me to plan and decompose the problem into smaller parts.
<Ramzi> And it took me a long time but it worked right away.
<Ramzi> I realized that had I done it in JAVA, I probably would have finished a lot quicker, and in only one method.
<qwr> Ramzi: I decompose in java too.
<Ramzi> The same amount, or less?
<qwr> Ramzi: and are frustrated when the damn language gets on my way
<Ramzi> I wish I had literal examples right now.
<Ramzi> Hey, I have one.
<qwr> Ramzi: probably more, because I have to do some search for least sucking way that is possible in java
<qwr> Ramzi: while I would just write a code in ocaml
<Ramzi> I did a project in Ruby, and I needed a list of "consistent types."
<Ramzi> So, for example [1,2,3] is fine. Or [[1],[2],[3]] is fine.
<Ramzi> But [1,2,[3]] is not fine.
thelema has quit [Read error: 110 (Connection timed out)]
<Ramzi> I wished ruby would let me know when I made the error.
<Ramzi> Of putting [3] in with the 1,2.
<Ramzi> And I thought, oh hey, OCaml would tell me.
<qwr> Ramzi: want a example? http://codepad.org/RzXiFVYU
<Ramzi> But I thought about it, and the function would still come out as 'a list -> 'a list
<qwr> Ramzi: that's how I write java...
<Ramzi> wow, that's horrid. lol
<qwr> (the := is a trick of editor, actually that line source file is DescriptionVersion v = (DescriptionVersion) desc;)
<Ramzi> trick of editor?
<Ramzi> oh, nvm
<Ramzi> So what do you think of my OCaml problem?
<qwr> Ramzi: err what your function would do?
<Ramzi> hmm, wait, i couldn't have [1,2,[3]]. because that list would contains ints and lists.
thelema has joined #ocaml
<qwr> Ramzi: yes.
<Ramzi> what about code correctness? maybe Smerdyakov should teach the chat about it.
<Ramzi> I guess I feel, because functional programming feels more like math, it's easier to devise proofs for it?
<thelema> Ramzi: because there's not quite as many side-effects in functional programming, it's easier to reason about
<qwr> Ramzi: probably still hard, if you allow side effects (like in ocaml)
<Ramzi> i see. so having a loop or 5 imperative statements in a row, or something. that needs to be reasoned about.
<qwr> Ramzi: but it's generally easier to read ocaml or haskell code
<Ramzi> it's like, more stuff in the function that could go wrong.
<qwr> than some crazyle mutable mess
romanoffi has left #ocaml []
<thelema> Ramzi:trying to keep track of the effect of mutating a global variable... that's hard
<Ramzi> if you could think of a classical, or even contrived, examples of a program where using OCaml is just obviously better, what would it be?
<Ramzi> (Like the Dog example in JAVA. :-P)
<thelema> Ramzi:some people like showing quick sort in ocaml as an example of its power.
<thelema> let rec quicksort = function
<thelema> | [] -> []
<thelema> | pivot :: rest ->
<thelema> let is_less x = x < pivot in
<thelema> let left, right = List.partition is_less rest in
<thelema> quicksort left @ [pivot] @ quicksort right
<Ramzi> can you change the first line to the form i'm familiar with please?
<qwr> Ramzi: I really didn't see, how was java good in that dog example :P
<Ramzi> because a dog is an object, with certain properties.
<thelema> let rec quicksort l = match l with
<Ramzi> it's easier to think of a dog as an object than a list of functions.
<mbishop> I don't think I ever put up a quicksort in ocaml, but I have one in sml
<qwr> Ramzi: i can use objects in ocaml, if there are really stuff that belongs to the dog
bluestorm has quit ["Konversation terminated!"]
<Ramzi> question, why define is_less?
<Ramzi> qwr, you don't think things "belong to the dog"
<qwr> Ramzi: i mean, if the code is really dog specific or not
<Ramzi> alright, how about some practical questions.
<thelema> Ramzi:is_less gets defined to simplify the partition command (List.partition (fun x -> x < pivot) rest) gets harder to read and introduces new syntax
<Ramzi> how does ocaml compare in terms of code efficiency and package support?
<qwr> Ramzi: you could use ((>) pivot) instead of that is_less ;)
<Ramzi> doesn't is_less just return true/false?
<qwr> Ramzi: so what more you need for sorting?
<Ramzi> couldn't you type List.partition (x < pivot) rest
<palomer> is it possible to call a method from a superclass? like method foo a = super#foo a ?
<qwr> palomer: cast it
<qwr> palomer: or don't specify the class
* qwr would do the latter
<qwr> palomer: hmm you want override and then call?
<thelema> palomer:within the object, when you inherit, you can give names to the classes you inherit from (ocaml allows multiple inheritance), and then you just call the method on th esuperclass, yes
<Ramzi> thelema: i get the sense you're more interested in discussing code than discussing language theory.
bla has joined #ocaml
<thelema> Ramzi:ocaml vs. what in terms of efficiency and package support?
<Ramzi> let's say, C and JAVA.
<qwr> palomer: inherit foo as super
<thelema> Ramzi:ocaml is very efficient. C can be written more efficiently, but ocaml comes close. Java doesn't come close.
<Ramzi> hmm, and C++?
<thelema> package support = library bindings? or quality of language suport for encapsulation?
<qwr> Ramzi: probably faster, but usually much more painful to use
<Ramzi> uh... i want to make guis really fast, how about that?
<Ramzi> from what I've seen, java often beats C++ on speed tests.
<thelema> C++ is on par with ocaml for most tasks. (slight advantage to C++ in speed, huge advantage to ocaml in ease of use)
<thelema> fast for a gui is slow for other things - people are quite slow.
<qwr> Ramzi: jvm has specific problem with client-side guis - it starts compiling code when user clicks some button ;)
<Ramzi> does ocaml have robot support. that is, can i make it take control of my mouse cursor, click, and send fake keyboard input?
<qwr> Ramzi: the jit, you know ;)
<thelema> Ramzi: I'm not aware of any code written in ocaml to do that. It'd be quite platform specific.
<Ramzi> java has robot support and is platform independent
<qwr> Ramzi: but in raw speed, you won't notice any difference between ocaml and C in gui - if you don't something incredibly stupid in one of the implementations
<Ramzi> i'm not talk about speed in gui. typically i don't think of those things together.
<Ramzi> i meant speed for data processing, and gui for... well, ease of use for user.
<thelema> two separate things, sometimes accomplished in different languages for a single project.
<pango_> Ramzi: faking mouse and keyboard events is the worse way to automate tasks
<Ramzi> pango_: how else?
<thelema> ram; proper apis
<qwr> Ramzi: make proper interfaces
<Ramzi> let me ask a specific question, then.
<Ramzi> there is a flash tetris game, that i would like to code a bot to play.
<Ramzi> what proper apis or interfaces do i have at my disposal?
<qwr> Ramzi: what you want to achieve?
<thelema> Ramzi:do you have the source for the game?
ygrek has quit [Remote closed the connection]
<Ramzi> i want the bot to play the game. no source.
<pango_> Ramzi: APIs, or cli
<Ramzi> what api?
<thelema> then the only way you have to interact with the game is kb/mouse, and you're stuck with that. If that game were designed for a computer player, there'd be an interface for it to make moves (other than kb/mouse)
<qwr> Ramzi: is your goal to write bot that knows game rules or a bot that reads screenshot and does visual processing? ;)
<Ramzi> right. well, i think often times you want to automate tasks and the only way you have to interact with it is kb/mouse
<pango_> personally I wouldn't care about automating a tetris game without api
<Ramzi> qwr: it'd have to do both
<Ramzi> pango_: Microsoft live search club had these flash games that you can get points and redeem for prizes.
<pango_> for one, I'm waiting for gui applications to provide interfaces before I start coding one
<thelema> Ramzi: the point is that going through kb/mouse is often the worst way for two programs to interact.
<Ramzi> people wrote bots for them.
<qwr> Ramzi: yes. but if your goal is not visual recognation research, then its stupid way to write tetris-playing bot
<Ramzi> i agree. i'm not fond of it, but if i have to i have to.
<Ramzi> qwr: lol, what? it's not a stupid way, it's the only way.
<pango_> Ramzi: I'd take sanity over their prizes
<Ramzi> pango_: Fair enough. Maybe it's the wrong chat, but sometimes people like scamming or hacking just for the challenge.
<pango_> there's always another way
<Ramzi> for example, there are homebrew guys. Like for the Nintendo wii. Man, they crack open the console and make chips and do all sorts of crazy things.
<Ramzi> and for what? to play burnt games or run pc apps.
<Ramzi> but it's not about running the pc apps, it's about the challenge.
<pango_> I'll pass
<Ramzi> to each his own
<pango_> If it wasn't for the nefastious job of the makers, there would be no challenge
<thelema> find the appropriate win32 calls, and you too can make a robot with ocaml.
<qwr> Ramzi: if you really want you can do in ocaml any lowlevel stuff with X that you could in C - you can write wrappers for C functions. actually there are ready-made X wrappers for ocaml and haskell ;)
<qwr> Ramzi: or you could write X proxy ;)
<Ramzi> what do you guys do, qwr and pango_?
<qwr> Ramzi: same for win32
<Ramzi> for a living, i mean
<qwr> Ramzi: I write mostly libraries and dsl's for big stupid java systems ;)
bongy has quit ["Leaving"]
<Ramzi> how old are you?
<qwr> Ramzi: 28 ;)
<pango_> Ramzi: reseach and development (mostly on large storage matters)
<pango_> yes
<Ramzi> I'm 20. will be graduating in a year.
<pango_> nearly 39
<Ramzi> i guess i'd be looking for something rewarding that pays well.
<qwr> lately have written half-finished ML'ish language for jvm too, to have less to do with pure java ;)
<Ramzi> suggestions?
<Smerdyakov> Ramzi, http://www.janestcapital.com/tech.html , if you want to code OCaml.
<Ramzi> Smerdyakov: I'd like for you to teach about code correctness sometimes, as you seem to be adament about that.
<Smerdyakov> Ramzi, I'll write a textbook some day.
<Ramzi> i'll have to wait?
<Smerdyakov> I'm not going to start lecturing on IRC....
<Ramzi> why not?
<Ramzi> lol
<qwr> because he has better things to do? :P
<jonafan> unless you're really cranky, then you might start lecturing on irc
<jonafan> but the topic is hard to predict
<Ramzi> i don't think it's unreasonable to lecture in irc
<Ramzi> what if the chat demands it
<Ramzi> do any of you play project euler?
<jonafan> i just started it a couple of days ago
Yoric[DT] has quit ["Ex-Chat"]
<Ramzi> you use ocaml?
<thelema> I went overboard on the factoring problem. That was fun.
<Ramzi> which?
<jonafan> i'm on problem 9
<mbishop> I did a few project euler problems, but I did them in Scheme
<jonafan> a^2 + b^2 = c^2 such that a + b + c = 1000
<Ramzi> i'm at the point where programs don't help unless you know the math trick.
<thelema> Ramzi:problem 3 - factor 600851475143
<Ramzi> how'd you go overboard?
<Ramzi> hmm, maybe that would overflow in ocaml
<jonafan> gotta use the Num module
<mbishop> Your current rating is 4% genius, having solved 8 out of 188 problems.
<thelema> Ramzi: building tables of distances between multiples of 3, 5, 7 so that I skip dividing by them.
<Ramzi> that's crazy
<jonafan> haha
<thelema> Ramzi: and remember, I've got a 64-bit processor - that's not a big number.
<Ramzi> Your current rating is 26% genius, having solved 49 out of 188 problems.
<Ramzi> i cheated on both of those
<Ramzi> hahahah, in notepad
<thelema> mathematica would probably chew through those pretty well.
<Ramzi> well, i plugged 100! into mathematica, then pasted it into notepad.
<Ramzi> And did a find/replace on \d with \d+ where \d is any digit
<Ramzi> then i just plugged that new expression into mathematica.
<thelema> heh.
alexyk has joined #ocaml
<thelema> you should put on your resume "meta-programming", then.
<Ramzi> i did solutions like that for a few of them.
<thelema> mbishop:did you use a method other than brute force calculation?
<Ramzi> anyone ever studying theory of computation?
<thelema> Ramzi: yes
<Ramzi> thelema: why IT given such a theoretical mind?
<thelema> I have a strong practical side too.
<Ramzi> that's good too
<Ramzi> i wonder what the "right" solution to the 100! is.
<Ramzi> everyone just seemed to use bignums, which feels like cheating
<jonafan> there's no other way to calculate factorials
<Ramzi> the should be a way to calculate the sum of the digits without having to store 100! in memory
<thelema> I think I remember a way to calculate digits of 2^1000 without full calculation.
<thelema> err, I remember *of* a way. I don't know the way.
<Ramzi> maybe you mean, you know how to take the modulus of things with large exponents.
<Ramzi> without having to caclulate it first.
<Ramzi> for example, what is 3 mod 3^2352352
<thelema> no, that's different, it had to do with 2, specifically.
<thelema> and the answer to that is 3.
<Ramzi> i mean, 3^523524523 mod 3. clearly 0.
alexyk has quit []
<Ramzi> and 3^45252523423552 mod 2 is clearly 1.
<Ramzi> but a better example, would be 3^121 mod 11.
<Ramzi> you don't have to calculate 3^121. You could just calculate 3^11 mod 11.
<Ramzi> And then square that, mod 11.
<thelema> p^n-1 mod n -- yes...
<Ramzi> hmm? this didn't have that form.
<thelema> that method would produce 3^22 mod 11.
<Ramzi> my mistake
<thelema> the method you're thinking of involves binary decomposition of the exponent, and using repeated squaring to produce the sequence to multiply.
<Ramzi> still, (3^11 mod 11)^11 mod 11 is a "smaller" computation than 3^121
<Ramzi> right.
<Ramzi> with 100!, maybe you can represent the answer as a string in base 100 or something.
<thelema> 3^121 = 3^1 * 3^8 * 3^16 * 3^32 * 3^64, all of which are pretty easy to calculate.
<thelema> with factorial, there's no trick, but I thought I remembered of a trick for powers of 2.
<Ramzi> i'm not saying there's a trick to calculate the base 10 answer of factorial.
<Ramzi> i'm saying there might be a trick to storing the answer in a way that uses little memory.
<Ramzi> at the expense of processing time.
<pango_> 100! is not that large
<thelema> it's less than 200 digits
<thelema> (way less, but just as an upper bound)
<Ramzi> what if the question had been 1000!?
<thelema> less than 3000 digits, still pretty short. <3k of ram
<thelema> when written as BCD, which is pretty inefficient.
<Ramzi> out of curiosity, how are you approximating the number of digits?
<Ramzi> BCD?
<thelema> BCD - Binary Coded Decimal -- oops, you'd get two digits per byte. 1.5k
<pango_> # String.length (string_of_big_int (fact 100)) ;;
<pango_> - : int = 160
<pango_> # String.length (string_of_big_int (fact 1000)) ;;
<pango_> - : int = 2571
<thelema> as to the approximation, x! < x^x has (log x) * x digits
<thelema> :)
<Ramzi> What if you saved the answer in base 26 using chars?
<Ramzi> how much memory needed?
<thelema> ick. why not use base 256?
delamarche has quit []
<thelema> anyway, you just have to change the base of the log. log_26 1000 * 1000
<Ramzi> we could use base 256, but i didn't want to run into problems of representing it with ascii, since some ascii chars are blank
<Ramzi> so i just picked the alphabet
* pango_ wonders if yencode would be more efficient
Morphous_ has quit [Read error: 110 (Connection timed out)]
Morphous_ has joined #ocaml
postalchris has joined #ocaml
<pango_> mmmh off-by-one in previous results, String.length (string_of_big_int (fact 100)) = 158, String.length (string_of_big_int (fact 1000)) = 2568
<Ramzi> i always make this dumb mistake
<Ramzi> i get tricked into thinking that a higher base can hold more values in a smaller memory
<Ramzi> for example, hex can hold the 3 digit number 255 in 2 digits, FF.
<Ramzi> But if you use chars, then FF is really 16 bits.
<Ramzi> and you only need 8 bits to hold 255.
<thelema> hex characters are only base 16, not base 256
<Ramzi> it's the same idea, you can't hold more numbers using base 256 in less memory.
<pango_> with n bits you can encode 2^n different values... You know you picked an optimal encoding when you can use them all to represent different numbers
psnively has joined #ocaml
* qwr wonders, wtf you're trying to do? create a compression algorithm? :P
<thelema> qwr:just discussing representations of 1000!
<thelema> ramzi got the idea that since this is a *huge* number, it would be hard to keep in ram.
<thelema> I pointed out that even as BCD, it'd take <1.5K
<qwr> only 1000! ? you could use a convention, where 1 means 1000! ;)
<qwr> then it takes 1 bit
<thelema> in base 1000!, it's simply 10.
* thelema tries to do problem 188 using only 64-bit math
<thelema> err, 63-bit math
marmottine has quit [Read error: 104 (Connection reset by peer)]
<thelema> hah. got it. Except I think there might be a logic error in their solution...
<thelema> or maybe I made an error when coming up with my first solution. (more likely me.)
Tetsuo has quit ["Leaving"]
TSC` has joined #ocaml
<Ramzi> congratulations.
<Ramzi> thelema: are you a turing machine?
TSC has quit [Read error: 110 (Connection timed out)]
zkincaid has joined #ocaml
m3ga has joined #ocaml
postalchris has quit [Read error: 110 (Connection timed out)]
hkBst has quit ["Konversation terminated!"]
ikaros has joined #ocaml
alexyk has joined #ocaml
<alexyk> I'm using DynArray and it works fine in toplevel after #require "extlib", however I get DynArray.create unbound when trying to compile, even though I give extlib.cma on command line to ocamlc -- what else do I need to tell it?
ikaros has quit [Remote closed the connection]
<pango_> alexyk: try -I +extlib
<alexyk> pango_: ocamlc barfs
<pango_> or ocamlfind ocamlc -package extlib -linkpkg <other ocamlc arguments>
<alexyk> um, do I need to open Extlib before using DynArray?
<pango_> I think DynArray is included in Extlib... I never actually used the extlib
<alexyk> ok it works in ocamlfind -package extlib, but why ocamlc extlib.cma doesn't where str.cma does?
<pango_> str.cma is in include path
zmdkrbou has quit [Remote closed the connection]
<pango_> add -verbose to ocamlfind line to see expanded command
<alexyk> yes -- it creates -I /opt/ocaml/lib/ocaml/pkg-lib/extlib, then -L.../extlib ...extlib/extLib.cma -- but I wonder what's the right +extlib should be... It's a GODI OCaml so it's all in the standard pkg-lib places
<alexyk> and ocamlc from GODI must have a shorter way to find its own extlib
<pango_> -I +extlib is a shortcut for -I `ocamlc -where`/extlib
mwc has joined #ocaml
<alexyk> ah -- ocamlc -where yields /opt/ocaml/lib/ocaml/std-lib
<alexyk> and extlib is in pkg-lib/extlib
<alexyk> it's from GODI installed with prefix /opt/ocaml
<alexyk> so it doesn't know it installs things into pkg-lib too
<alexyk> can I add things to some env variable which -I checks? or -I is just one `ocamlc -where`?
<pango_> according to the documentation, that's the only one
<alexyk> hmm -- wonder what GODI means when splitting into std-lib, pkg-lib and site-lib
<alexyk> ok -- guess I'm stuck with ocamlfind here, or will define some set of include dirs in environment when I find how...