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!)
<Smerdyakov> But, really, if you need to ask these questions, then you should find a better text for learning OCaml. What are you using?
<Ramzi389> The internet.
<Smerdyakov> I am asking about particular documents.
<thelema> the syntax [| a::t -> ] means to check if the thing is a list with a head and tail, and if so, a=List.hd l, t=List.tl l
<Smerdyakov> You might want to read this instead: http://www.cs.caltech.edu/courses/cs134/cs134b/book.pdf
<Smerdyakov> Is it just a faulty impression on my part, or is ocaml-tutorial.org just about the worst thing ever of any kind ever?
middayc_ has quit []
<thelema> Smerdyakov: work to improve it. I have.
<Smerdyakov> Why, when we have Jason's book?
<Smerdyakov> Anything with "tutorial" in its name is eternally suspect.
<thelema> Smerdyakov: we don't have his book (for free) forever
<thelema> (legally)
<Smerdyakov> It will be worth buying for people who are serious about learning OCaml, then.
<Smerdyakov> People here seem to seriously underestimate the difficulty of presenting this material.
<thelema> like the difficulty of writing an encyclopedia? I think the power of wikis can make this achievable
<Smerdyakov> There aren't enough qualified people for that to work.
<Smerdyakov> In the next few years, I'm hoping to write an introductory programming text that uses Coq, where every function has a correctness proof from the start. I think that would solve a _lot_ of problems people have coming to functional programming.
<thelema> I doubt beginners to functional programming need correctness proofs to make them comfortable
<Smerdyakov> This has nothing to do with "being comfortable."
<Smerdyakov> This is about learning how to program.
<Smerdyakov> Watch how beginners ask questions and you can see that they have no mental models of how programs work and how to convince themselves that they work.
<thelema> I doubt proofs will bring about programming ability
<thelema> hmm...
<Smerdyakov> I'll be really surprised if it doesn't bring a huge improvement.
<thelema> I think the overhead of teaching Coq will overwhelm most people that try your method.
<thelema> s/teaching/learning/
<Smerdyakov> I don't think so.
<Smerdyakov> Have you ever used Coq?
<thelema> no
<thelema> I imagine it complicated - all automated proof systems I've seen are
<Ramzi389> What does failwith "nth" mean in the code for nth?
<Smerdyakov> Well, you might want to work with actual facts instead of guesses. ;)
<thelema> Ramzi389: it means "raise (Failure "nth")"
<thelema> let failwith s = raise(Failure s)
<Ramzi389> And what does raise mean?
<Smerdyakov> Ramzi389, the complexity of the definition of [nth] is a good reason for you to avoid using [nth] for now.
<Ramzi389> I think I have to, because I need to return -1 if the element is not found
<Ramzi389> But I think nth throws some kind of error.
<Smerdyakov> You obviously don't need to use [nth], since you could always define your own parallel version.
postalchris has quit [Read error: 110 (Connection timed out)]
<Ramzi389> Right. But it seems like I shouldn't have to write 3 functions to write 1 function.
<thelema> Smerdyakov: you don't think it a useful tool for learning to write a 'List.index' function?
<thelema> Ramzi389: raise throws an exception - are you familiar with exceptions?
<Smerdyakov> thelema, that's right. Beginners shouldn't be using exceptions.
<Ramzi389> yes, I'm failiar with exceptions. I prefer not to use them currently, though.
<thelema> Ramzi389: as you will, if you want to return -1 instead, no problem.
<thelema> Smerdyakov: I disagree.
<Smerdyakov> Special return codes like -1 are highly frowned upon in ML. Maybe it makes sense at this point in learning OCaml, but I'm not sure.
<thelema> Smerdyakov: exceptions are much better than special return codes.
<Smerdyakov> thelema, and any scheme where all the information is in the types is better than either.
<thelema> mmm... I'm not so picky about exceptions being reflected in the type of the function.
thermoplyae has quit ["daddy's in space"]
evn_ has joined #ocaml
<Ramzi389> Does this look good so far? http://codepad.org/xfpSPGY8
<thelema> Ramzi389: that will work, but I think you're using the wrong tool
<Ramzi389> I'm very surprised you're able to interpret that as quickly as you do.
<Ramzi389> What do you mean, "the wrong tool"?
<thelema> I just scanned it, there could be a huge flaw in it, but the basic idea seems sound.
<Smerdyakov> Ramzi389, you should use no helper functions or standard library functions in your definition of [first_occurrence].
<thelema> it looks like you're looping through each position, getting the list element at that position and comparing it to what you want to find.
<thelema> Smerdyakov: he'll need one aux function if he does it the way I'm thinking.
<Smerdyakov> Ramzi389, also, never use [==].
<Ramzi389> Given that first_occurrence works the way it should, I can now right index, I think.
<Smerdyakov> Ramzi389, use [=] instead.
<Ramzi389> okay
<thelema> Smerdyakov: There's valid uses of ==. Don't give absolute advice like that.
<thelema> Ramzi389: can you refine your code for first_occurrence?
<Smerdyakov> thelema, everything I'm saying to Ramzi389 today is in the context of getting started with OCaml. I'm not going to waste time prefacing everything with "for now."
<thelema> Smerdyakov: don't preface everything you say - just give reasonable advice: "you probably mean [=] instead of [==] in your function"
<thelema> Ramzi389: at the moment, your code only works for int lists. can you fix that?
<Ramzi389> thelema, i'm sure one could, but maybe not myself.
<thelema> Ramzi389: n/m, maybe that's off track.
<Ramzi389> i thought my code was polymorphic
<thelema> try writing first_occurrence in terms of List.hd and List.tl
<Smerdyakov> O_O
<Smerdyakov> thelema, why not pattern matching instead?
<thelema> Smerdyakov: because it's too unfamiliar - Once he uses hd and tl, we can change those to pattern matching.
<thelema> Ramzi389: since you use -1 as your flag, the return type of nth is int. meaning it can only work on int lists.
<Ramzi389> the return is an int
<Ramzi389> oh.
<thelema> What Smerdyakov would want you to use is an option type.
<Ramzi389> hmm
<thelema> [] -> None
<thelema> if n = 0 then Some h
<Ramzi389> Is that better?
<thelema> won't work.
<thelema> h isn't of type option.
<thelema> type 'a option = None | Some of 'a
<thelema> you need [Some h] and [Some e]
<Ramzi389> I'm not really following this.
<Ramzi389> is this syntax you're typing, or quantification
<thelema> values of type option are either "None" or "Some foo"
<thelema> where foo can be anything.
<Ramzi389> Why can't I return "None" or the head?
<thelema> inside [] goes syntax. the line starting "type 'a option..." is syntax.
<Ramzi389> So... all elements in the range have to be of the same type
<thelema> None isn't the same type as 'a
<thelema> None is the same type as Some 'a
<fbvortex> On a function, can I do a type constraint based on a type defined in another module if I make the type fully-qualified, i.e. I use the module's name?
<thelema> Ramzi389: option is like a discriminated record
<thelema> err, struct
<thelema> fbvortex: yes.
<Ramzi389> I'm sorry. I know you're teaching me, but I almost feel that this function shouldn't be this complicated.
<thelema> it shouldn't - there's an easier way to do this, but it'll require a few steps for me to refine your solution into that one.
<thelema> and I got us side-tracked into learning about option types.
<Ramzi389> Couldn't I just read the list backwards
<fbvortex> So then I'm having this problem where I do a type constraint in a file, call it x.ml to a datatype in A, call it A.record_t . When i try to compile using ocamlfind ocamlc -c A.cmo x.ml , I get an "undefined record field" error in x.ml, but if I put an "open A" at the top of the x.ml, it seems to work.
<thelema> You could reverse the list, yes. You could recurse to the tail of the list, and then do your processing on the way back out... But I wouldn't recommend either.
<Ramzi389> Why not?
<thelema> fbvortex: record fields are scoped within the module they're from. you have to do var.Module.field
<thelema> Ramzi389: same reason as I wouldn't use your current solution - efficiency
<thelema> Ramzi389: what if in nth_aux you changed the test n=0 to h=<the element you're looking for>?
<Ramzi389> it'd be faster?
<thelema> you could do the searching in nth_aux (although maybe call it index_aux instead)
<Ramzi389> let's reason about index
<fbvortex> thelema: thanks! I perhaps missed this in some documentation somewhere.
<thelema> ok.
<Ramzi389> if i am searching for an element e, and I want the last occurrence of it
<Ramzi389> i could keep a position variable which increments every time i recurse
<Ramzi389> and i recurse until []
<thelema> fbvortex: it's hiding in there somewhere - everyone runs into this at one time or another.
<Ramzi389> everytime i recurse i pass the tail.
<thelema> you might also keep track of the last place you found e
<Ramzi389> then i go through comparing the heads of the list against e
<Ramzi389> when i find a match, i return the position variable
<Ramzi389> if i don't match, i return -1.
<thelema> how about: when you find a match, you keep searching until you hit [], and you return the position of where you last matched
<Ramzi389> hmm, so i keep a "variable" called last_match
<Ramzi389> which is set to -1, but upon the first match, I update the value. all the way to []
<thelema> this doesn't have to be a variable - it can work like your position variable - an argument to your function
netx has quit [Remote closed the connection]
<Ramzi389> I feel bad. It's like I can't focus today.
<Ramzi389> I know I should have been done by now, on such a simple function, that I could have done in 1 minute in another language.
netx has joined #ocaml
<thelema> it's not just a new language, it's a whole new way of thinking about things
thermoplyae has joined #ocaml
<thelema> (I could use the word paradigm if I were feeling erudite)
<Smerdyakov> "Paradigm" has totally fallen from ivory tower grace.
<qwr> Ramzi389: List.find pred (List.rev l)
<Smerdyakov> It's about as high-brow as "thingamajig" today.
<Ramzi389> hahaha
<qwr> or you could use fold_left for iterating it ;)
<Ramzi389> I think I finally got it.
<Ramzi389> But now I gotta get my syntax correct.
<Ramzi389> So, I've decided that index is pretty pointless. All the work will be done in index_helper.
<Ramzi389> And index_helper will have 4 parameters, newList, e, currPos, and lastFound.
<thelema> Ramzi389: index can hide the two "variables" in index_helper from the outside world
<qwr> List.fold_left (fun (r, i) v -> (if pred v then i else r), i + 1) (-1, 0) list
ita has quit [Remote closed the connection]
<Ramzi389> I tried to express my intuition, maybe the syntax is wrong.
<Ramzi389> Fixed a small error
<qwr> it looks weird
<Ramzi389> :-(
<qwr> why this h, ?
<thelema> index_helper needs to go before index
<Ramzi389> I'm not sure how to get h. I think I should do List.hd newList
<Ramzi389> Okay.
<thelema> and why do you have "h, if..."?
<qwr> does it type-checks?
<thelema> Ramzi389: h is created by the match
<Ramzi389> I want to express, "If the list is not empty, then check the head against e.
<qwr> Ramzi389: i think if you remove the h, before the if it would work
<Ramzi389> If there is a match, call index_helper in this way. Otherwise, call index_helper in this different way."
<qwr> Ramzi389: and add some parenthesis ;)
* qwr thinks that half-curried functions can't be added with + :P
<qwr> Ramzi389: tail recursion is basically jump + setting arguments
<thelema> you need (currPos+1) in parentheses in both places.
<Ramzi389> Better?
<thelema> qwr: be aware that Ramzi389 is a beginner - tail recursion can wait.
<thelema> much better. should even work now.
<qwr> thelema: he uses it already
<thelema> qwr: he doesn't know he does it, much less needs to know yet.
<qwr> -1 should be also (-1)
<qwr> thelema: maybe
<thelema> Ramzi389: think about this: index_helper t e (currPos+1) (if h=e then curPos else lastFound)
<Ramzi389> I think that's good...
<qwr> (because current call parses as (index_helper l e 0) - 1;;)
<Ramzi389> elegant
<Ramzi389> you know, i really think i'm just having an off day. (Or weeks.)
<qwr> or you're still learning how to use ocaml
<thelema> now what about moving index_helper inside index?
<Ramzi389> But let me compliment you guys. Maybe it is the nature of the language that requires people accustomed to formality and pedagogy, but I haven't seen such patience in IRC chats for other languages.
<thelema> Ramzi389: replace the first ;; with "in"
<thelema> and drop e from index_helper - now that it's inside index, it has access to that e.
<Ramzi389> Ah, and I also need to add rec
<qwr> (let binding_name = value in expr-using-it is the local bindings syntax)
<Ramzi389> Just "in" or "in index"
<thelema> drop e from the last line too
<thelema> and you can still do the if simplification
<Ramzi389> I'd prefer not to, just as a matter of reading preference.
<thelema> ok.
<thelema> if you move newList to the last argument, you can use "function ..." syntax
<Ramzi389> Yay, it works.
* qwr would of course put the l into last argument in both functions and return just index_helper 0 (-1)
<Ramzi389> i'm going to go for a little while now. thank you all for your help!
<thelema> Ramzi389: you're welcome
<thelema> qwr: a little eta expansion can go a long way. I've had to pass arguments like that manually so often that I just do it now as a matter of habit
<qwr> :)
sporkmonger has quit []
<thelema> quick poll: preference between (start,len) and (start,end) for denoting ranges
<qwr> start,end ;)
* qwr thinks that it will generally result in less arithmetic and ambiguity. or maybe i'm just used to it...
<thelema> okay, include end in the range, or only up to end-1?
evn_ has quit []
^authentic has joined #ocaml
hsuh has joined #ocaml
schme has joined #ocaml
<Ramzi389> Hi again.
<Ramzi389> I suppose I can see how OCaml can detect the return type being an int or a float.
<Ramzi389> But how can it distinguish a tuple and a list?
hsuh has quit [Remote closed the connection]
<thelema> you think it detects that based on the binary value of what's being returned?
<Ramzi389> thelema: are you there?
<Ramzi389> hah
<Ramzi389> it's amazing that we send our messages at the same time like that
<Ramzi389> I think my question is bad. Maybe I can discover the answer with a better formed question.
<thelema> Lists are implemented internally as a pair (data,pointer to next node)
<Ramzi389> and tuples?
<thelema> a pair is a 2-tuple
<Ramzi389> i see
<thelema> ocaml arrays are of the form (header, elem0, elem1, ...)
<Ramzi389> can you write a function called toTuple that takes two parameters, a and b, and returns (a,b)
<thelema> let toTuple a b = (a,b)
<thelema> ocaml tuples are of the form (header, elem0, elem1, ...)
<Ramzi389> then toList a b would be = [a,b]
<Ramzi389> and the transformations from tuples and lists are obvious.
<thelema> ocaml lists are of the form (header,elem0, pointer0) (header, elem1, pointer1) (header, elem2, pointer2), ...
<thelema> let toList a b = [a;b]
<Ramzi389> yeah
<thelema> , always creats a tuple -- list elements get separated by ;
<Ramzi389> right, my bad
hsuh has joined #ocaml
<thelema> [a,b] would create a list with one element, the tuple (a,b)
authentic has quit [Connection timed out]
^authentic is now known as authentic
<thelema> ocaml records are of the form (header, val0, val1, ...)
<Ramzi389> i don't know what records are
<Ramzi389> but i'm actually not so interested in the internally representation
hsuh has quit [Remote closed the connection]
<thelema> you want to know how ocaml knows the return type.
<Ramzi389> i said it was a bad question.
<Ramzi389> but nonetheless you provided a good answer.
<thelema> if you know how ocaml knows the return type, can you tell me? (I'm being a bit pedagogical, hope you don't mind)
<Ramzi389> Well, before asking the question I would have thought it does some kind of logical analysis on the syntax of the function.
<Ramzi389> But maybe it's simpler than that, involved with keeping some sort of information in the binary, and just looking that up.
<thelema> actually, the types have no runtime representation - they're completely erased.
<Ramzi389> For example, let func a b = a *. b;; can let Ocaml deduce that func takes floats and returns floats
<Ramzi389> because of the *. operator
<Ramzi389> or function, rather
<thelema> exactly.
<Ramzi389> Is there a way I can add to the end of a list rather than the beginning?
<thelema> only by cheating. (and I mean really cheating)
<thelema> if you work within the system, lists are immutable, so you can't change the 'next' pointer of the last element to something else.
<Ramzi389> by reversing, then using ::, then reversing again?
<thelema> you can pretty easily create a new list that has all the same elements and one more.
<Ramzi389> oldlist;newElement ?
<thelema> @ appends lists, so the simple way is: list @ [newElement]
<Ramzi389> thanks.
<thelema> but this isn't efficient in stock ocaml.
<thelema> it's O(n) because of having to create a new list
<Ramzi389> okay
<thelema> prepending is very efficient - O(1), with a tiny constant
<Ramzi389> ok
<Ramzi389> i think i'm getting the hang of it. maybe i just needed to eat something.
<Ramzi389> so my current problem is: given a list of 2-tuples, create a 2-tuple of lists.
<thelema> It takes practice
<Ramzi389> Or, more descriptively, given a list of (x,y) coordinates.
<Ramzi389> Return ( [x0,x1,...,xn], [y0,y1,...,yn])
<thelema> you want to unzip your list.
<Ramzi389> I was unaware that was such a common name for this process.
hsuh has joined #ocaml
<Ramzi389> Yes, I want to unzip the list. So, like the last problem, I see all the work being done in a helper function.
<Ramzi389> oh wait, I should skip that part and work with it already nested.
<thelema> you can do it whatever way you want.
<Ramzi389> so I want to have two lists, say xlist and ylist, which I append using @ every time I encounter a new 2-tuple.
<Ramzi389> And since the input data is a list, I know to stop on []
<thelema> you'll probably want to accumulate your lists in reverse order, and when you reach [], return List.rev l1, List.rev l2
<thelema> does the concept of an accumulator make sense?
<Ramzi389> Hmm, you're right. That would be much faster. O(n) rather than O(n^2)
<Ramzi389> i'm not sure what you mean by accumulator
<thelema> let rec sum = function [] -> 0 | h::t -> h + sum t
<thelema> this has no accumulator
<thelema> let rec sum s = function [] -> s | h::t -> sum (h+s) t
<thelema> this has an accumulator
<Ramzi389> the first doesn't make much sense to me
<Ramzi389> can you pass anything to that 0-parameter function?
<thelema> it has one parameter: a list.
<Ramzi389> in the first example?
<thelema> treat "function" as "fun x -> match x with"
<Ramzi389> so parameters don't have to go before the equals sign?
<thelema> no, it's legal to write "let f = fun x -> x+1"
<thelema> "let f x = x+1" is just syntactic sugar
<Ramzi389> i'm much more comfortable with the sugar
<Ramzi389> does "let f = fun x -> x+1" read as, "let f be a function that maps x to x+1" ?
netx has quit ["Leaving"]
<thelema> yes
<Ramzi389> okay
<Ramzi389> so about accumulators?
<thelema> the second sum function has an extra argument, s
<thelema> it's the accumulator - it accumulates the answer, and is simply returned in the last step
<thelema> can you write a function to reverse a list?
<Ramzi389> i wasn't aware this was the word, but it seemed that's what i was doing anyway
Ramzi389 has quit ["http://irc.netsplit.de/"]
Ramzi181 has joined #ocaml
<Ramzi181> Sorry. I'm going to say yes.
<thelema> it's good practice to use an accumulator because it can run faster.
<Ramzi181> Efficiency is not really a priority yet. I usually prefer to learn clarity at first, then efficiency.
<thelema> so when you are unzipping a list, use two accumulators to keep the two partially unzipped lists
<Ramzi181> Suppose the head of a list is a 2-tuple. How can you see the first and second part of it
<Ramzi181> so, if h == (2,3) how can I get out the 2, or the 3.
<thelema> let rec print l = match l with [] -> () | (a,b)::t -> print_int a; print_string " "; print_int b; print_string "\n"; print t
<thelema> and we still need to get you out of the habit of using == for comparison
<Ramzi181> it was more of linguistic efficiency
<Ramzi181> i wanted to illustrate that h already had those values, not that i was assigning them.
<Ramzi181> but i guess this is the wrong room. :-P
<thelema> let print_tuple (a,b) = Printf.printf "(%d,%d)" a b
<thelema> Ramzi181: in this room, h = (2,3) means h has the value (2,3)
<Ramzi181> okay
<Ramzi181> can you use matches inside of matches?
<thelema> yes, but you probably don't need to - see "(a,b)::t" in my first example
<thelema> and if you use matches inside matches, you'll probably need () or begin/end to delimit the internal match
<Ramzi181> so i already have a match that lets h be the tuple
<thelema> so replace h with (h1,h2)
<Ramzi181> hmm
<thelema> you can also destructure tuples using let -- let (h1,h2) = h in
<thelema> if h is a pair
<Ramzi181> (a,b::t)
<Ramzi181> or ((a,b)::t)
<thelema> ((a,b)::t)
<thelema> the first destructures a pair whose second element is a list
<thelema> s/destructure/match/
<thelema> looks good to me
<thelema> except... instead of "[xlist @ a]", you want (xlist @ [a])
thermoplyae has left #ocaml []
AxleLonghorn has joined #ocaml
<Ramzi181> right.
<Ramzi181> thank you so much again.
<Ramzi181> This one took me a lot less time than the previous. I think I'm getting better.
<Ramzi181> what timezone are you in?
<thelema> CST
<Ramzi181> On these chars: unzip_helper t [xlist @ [a]], I get this error: This expression has type 'a list but is here used with type 'a
<Ramzi181> How old are you? Do you work / go to school? Will you be in here tomorrow?
<Ramzi181> oh, i think i have too many []
<thelema> yes, [] creates a list
hsuh has quit ["fuck"]
<thelema> you want (xlist @ [a])
<Ramzi181> right
<Ramzi181> so, for the other (more personal) questions?
<thelema> I'm 28, work as IT consultant, and am around #ocaml most of most days
<Ramzi181> okay. i really responded to you as a teacher. take this as a high compliment because i dislike most teachers.
<Ramzi181> :-P
<Ramzi181> hopefully tomorrow you'll be here if i need more help.
* thelema seems to teach well.
<Ramzi181> How does this read?
<Ramzi181> (int->'a)->int->int->'a list
<thelema> function that takes three parameters and returns a list of somethings
<thelema> the first argument is a function that takes an int and returns a something
<thelema> the other two arguments are ints
<Ramzi181> are the "somethings" the same? that is, is the 'a in the beginning the same type as the 'a at the end?
<thelema> of course it can be partially applied
<thelema> yes, if they were different, you'd write (int -> 'a) -> int -> int -> 'b list
<thelema> but outside of things that break the type system, this isn't possible.
<Ramzi181> wow, that's nifty.
schme has quit [Remote closed the connection]
* thelema appreciates currying and uses it when appropriate, but thinks that partial application should be the exception, not the rule.
<Ramzi181> so, i'm looking to write something that returns a list of answers
<thelema> okay, answers to what?
<Ramzi181> for example, if f(x) = x + 3, then f on the range from 3 to 5 is, f(3), f(4), and f(5), equals = [6;7;8]
<Ramzi181> Pardon my mixing of notations
<thelema> your helper has to increment m
<Ramzi181> oh... the m+1 doesn't cut it
<Ramzi181> this is what i get for trying to "save parameters" early
<thelema> no. and you're missing () around the (m+1)
<thelema> you don't have to change m itself, but you have to have a 'current_position' value that increments and eventually exceeds n
<thelema> and you need one more "in" instead of ";;" after [let answers]
<Ramzi181> Success.
<Ramzi181> This is much better. Even if the previous version worked, I still always manually added in the value f(m). But I shouldn't do that if n<m
<thelema> you can probably inline the last "let answers" as "app_int_helper [] m"
<thelema> and you don't need (m) on line 4
<thelema> otherwise it's good. It can be written as a composition of functions pretty easily
<thelema> let rec (--) = fun m n -> if m >= n then [] else m::((m + 1) -- n)
<thelema> let app_int f m n = List.map f (m--n)
<Ramzi181> Is the (m) on line 4 dangerous, if f was polymorphic?
<Ramzi181> It might have passed a tuple rather than an int?
<Ramzi181> Alright, thelema, thank you thank you thank you. It's time for me to go to sleep.
<Ramzi181> Goodnight.
<thelema> nite
r0bby has quit [Read error: 110 (Connection timed out)]
r0bby has joined #ocaml
r0bby has quit [Connection reset by peer]
r0bby has joined #ocaml
seafood_ has quit []
thelema has quit [Read error: 110 (Connection timed out)]
* palomer thinks that the ocaml gods wanted me to suffer when they decided they didn't like mutually recursive modules
goalieca has joined #ocaml
petchema has quit [Read error: 110 (Connection timed out)]
|Catch22| has quit []
adu has joined #ocaml
ttamttam has joined #ocaml
ttamttam has left #ocaml []
AxleLonghorn has left #ocaml []
hkBst has joined #ocaml
Mr_Awesome has quit ["aunt jemima is the devil!"]
adu has quit [Remote closed the connection]
ikaros has joined #ocaml
Yoric[DT] has joined #ocaml
brooksbp has joined #ocaml
Naked has quit [Remote closed the connection]
ygrek has joined #ocaml
thelema has joined #ocaml
bongy has joined #ocaml
filp has joined #ocaml
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
ertai has joined #ocaml
Naked has quit [Remote closed the connection]
ygrek has quit [Remote closed the connection]
ygrek has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
Naked has joined #ocaml
l_a_m has joined #ocaml
ikaros has quit [Remote closed the connection]
bongy has quit [Read error: 110 (Connection timed out)]
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
seafood_ has joined #ocaml
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
marmottine has joined #ocaml
brooksbp has quit []
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Tetsuo has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
ita has joined #ocaml
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
ygrek has quit [Remote closed the connection]
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
goalieca has quit [Remote closed the connection]
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
ChriS_T has joined #ocaml
ChriS_T has left #ocaml []
Naked has quit [Remote closed the connection]
Naked has joined #ocaml
Naked has quit [Remote closed the connection]
coucou747 has joined #ocaml
Linktim has joined #ocaml
filp has quit ["Bye"]
Naked has joined #ocaml
ChriS_T` has joined #ocaml
Yoric[DT] has joined #ocaml
seemant has joined #ocaml
ChriS_T` has left #ocaml []
Linktim is now known as Linktimaw
coucou747 has quit ["bye ca veut dire tchao en anglais"]
mqtt_ has joined #ocaml
<ikatz> does anyone know of a good statistics module for ocaml?
ita has quit [Remote closed the connection]
<rwmjones> ikatz, never used it, but http://pauillac.inria.fr/~guesdon/ocaml-r.en.html
<rwmjones> hmmm
<rwmjones> everyone thinks my bitmatch library was an elaborate april fools jok
<rwmjones> joke
bongy has joined #ocaml
bongy has quit [Read error: 104 (Connection reset by peer)]
mqtt_ has quit [Read error: 113 (No route to host)]
szell has quit [Remote closed the connection]
schme has joined #ocaml
netx has joined #ocaml
<flux> rwmjones, timing, remember timing :)
<qwr> thelema: anwering 10-hours ago question, end-1 ;)
magnusth has joined #ocaml
RobertFischer has joined #ocaml
sporkmonger has joined #ocaml
<sporkmonger> the noob returns... http://pastie.org/174063 <-- i just got this working (or at least, i think it's working), and now i'm wondering if this is really the best way to write this...
<RobertFischer> That looks very procedural. I'm not sure how it's being used, but you may want to figure out a more functional approach.
<sporkmonger> yeah, that's kinda what i was thinking
<sporkmonger> basically, i have a finite state machine
<RobertFischer> Okay...
<sporkmonger> and it takes a block of text as input
<sporkmonger> but it has to read the text at the bit level
<sporkmonger> so i wanted to wrap an in_channel so that i could have an input_bit method instead of input_byte
<RobertFischer> Can you define "read the text" as some kind of bitwise function/set of functions?
<sporkmonger> maybe? i don't really have a particularly good grasp of what i've really got available to me in ocaml yet
<sporkmonger> the input_bit function just reads off one byte, stores it in a buffer, and shifts off one bit at a time until it needs a new byte
<RobertFischer> Yeah. That's the procedural part. There's lots of mutable data implied by that statement.
<sporkmonger> right
<RobertFischer> The less mutable data, the better off you'll be.
<sporkmonger> that's kinda what i'm asking
<sporkmonger> how do i make it functional?
<ikatz> the general idea is that instead of running a function to modify some mutable data in memory somewhere
<ikatz> the updated data is instead returned by the function
<ikatz> so instead of iterating and changing memory several times, you call the function several times
* RobertFischer goes back to work, since ikatz seems to have this. :)
<sporkmonger> heh
<ikatz> now let me actually read your code :)
<sporkmonger> right, but that's where i ran into problems
OChameau has joined #ocaml
<sporkmonger> i couldn't see an obvious way of doing it with immutable data without somehow returning two values from the input_bit function
<ikatz> that's not out of the question
<sporkmonger> namely the bit and the new wrapped channel
<sporkmonger> and that would then produce a function that behaved dramatically different from the familiar input_byte function
<ikatz> in fact, that's pretty much exactly how it would work
<ikatz> hmmm
<ikatz> is the goal to return individual bits, or bytes-at-a-time?
<sporkmonger> bits
<sporkmonger> one bit at a time
<ikatz> what is a wrapped channel here?
<sporkmonger> simply a record that wraps an in_channel and keeps track of a buffer and how many bits have been shifted off the byte stored in the buffer
<Smerdyakov> I hate bits.
<sporkmonger> they're unavoidable in compression / dynamic markov classification :-P
<ikatz> i'm not sure there is a better functional way than returning the bit and the updated channel as a tuple
<sporkmonger> ok
<sporkmonger> in terms of general coding style, anything particularly wrong with what i've written aside from the procedural-ness?
<ikatz> the only alternative i was thinking of is recursively calling your input_bit function to get 8 bits at a time
<sporkmonger> yeah, that would really screw with the traversal function
<ikatz> ok, this is another way you might do it
<RobertFischer> ikatz and sporkmonger: What's wrong with returning the bit and the updated channel as a tuple?
<ikatz> RobertFischer: nothing, that's the first suggestion i had
<sporkmonger> "and that would then produce a function that behaved dramatically different from the familiar input_byte function"
<sporkmonger> ^ my only real objection
<ikatz> actually...
<ikatz> nevermind, same difference... i was going to say you could use a reference inside the function
<ikatz> (sorry for thinking out loud... but maybe this can work)
<sporkmonger> oh, btw, with filenames in ocaml
<ikatz> what does input_byte take for arguments?
<sporkmonger> in_channel
<sporkmonger> returns an int
ikaros has joined #ocaml
<sporkmonger> with filenames in ocaml, is it preferable to have bit_in_channel.ml or bitInChannel.ml or some other form?
<ikatz> if you were willing to add an input argument, there may be a more functional way to do it
<sporkmonger> i'd be open to it
<sporkmonger> filenames?
<ikatz> let input_bit bic = let channelinfo (* (buffer, position) *) = ref (0, 0) in function () -> (* your function *)
<ikatz> so (input_bit bic) returns a function that takes () as an argument and has an internal reference to the buffer and position
<sporkmonger> ok
<ikatz> tied to the specific channel you gave it for the first argument
<sporkmonger> that seems reasonable
AxleLonghorn has joined #ocaml
<ikatz> in my experience, lowercase filenames with underscores... but its not much experience so i won't stand behind it as the best way
<ikatz> yeah, that way you can use input_bit more easily in a higher-order function like map or fold
<sporkmonger> ok.... i guess i'm not really understanding the syntax of what you wrote
<ikatz> ok cool... because i was going to give you a better version
<sporkmonger> i understand it conceptually, but thats about it :-P
<ikatz> sorry about the inline comments
<ikatz> if i spread it across mutiple lines it becomes something like:
<ikatz> let input_bit in_c =
<ikatz> let buffer = ref 0 in
<ikatz> let position = ref 0 in
<ikatz> function () ->
<ikatz> if !position = 0 then
<ikatz> .... your function goes here
<ikatz> so "function () ->" means a function without a name
<ikatz> that knows about "buffer" and "position"
<ikatz> is that making any sense ?
<sporkmonger> i think so
<sporkmonger> so then the record isn't needed anymore?
<ikatz> right... the record is split up into 3 variables that the unnamed function has access to: in_c, buffer, and position
<sporkmonger> cool, yeah, i like that better
<ikatz> and the nice part is that buffer and position are hidden from the rest of your code
<sporkmonger> ok, so i'm a little fuzzy on why it's "function ()" rather than "function"
<ikatz> the reason for the () is that you want the function to be evaulated every time you call it
<sporkmonger> ?
<ikatz> sorry :)
<sporkmonger> i understand it's a closure, but that's about it
<ikatz> say you had "let my_get = get_char some_input_channel"
<ikatz> ocaml would evaluate "get_char some_input_channel" and produce a character
<ikatz> and assign that to "my_get"
<sporkmonger> right
<ikatz> so my_get would always have that value
<ikatz> alternatively, "let my_get () = get_char some_input_channel"
<ikatz> so every time you say "my_get ()", it evaluates the rest and gives you a different character from the input
<ikatz> in the case of input_bit, it would always return the same bit without having the ()
<sporkmonger> ok
<sporkmonger> aight, i think i understand now
<sporkmonger> but since it's now returning a function
<sporkmonger> seems like maybe it should be renamed to something like create_bit_reader or something
<ikatz> that's right
<ikatz> or "let input_bit_from_stdin = input_bit stdin" in
<ikatz> * the close quote should go after the "in"
seafood_ has quit []
<ikatz> it sounds like you konw what you're doing
<sporkmonger> so this is what i changed it to: http://pastie.org/174091
<RobertFischer> That reads a lot better to me, anyway.
<RobertFischer> As Brian Hurt puts it, Ocaml has mutable data, but the first thing you should do with it is build a cyst around it. :)
<sporkmonger> lol
<sporkmonger> aight, cool, thanks for all the help
<ikatz> yeah the only thing you could possibly do differently is position := (!position + 1 mod 8)
<ikatz> or whatever the syntax for mod is
<sporkmonger> bah
<sporkmonger> my irc client made an emoticon in the code
<RobertFischer> That's a matter of taste.
Snark has joined #ocaml
<sporkmonger> yeah
<sporkmonger> i think the way i've got it now tracks better in my brain
<sporkmonger> how do modules get named?
<sporkmonger> like, i've got a bit_reader.ml
<sporkmonger> what's the module name for it going to end up as?
bongy has joined #ocaml
<sporkmonger> all of the tutorials and such seem to have one-word modules
<Smerdyakov> First letter is capitalized. File extension is removed. Nothing else channels.
<Smerdyakov> s/channels/changes
<sporkmonger> k
<sporkmonger> hmm, so let input_bit = Bit_reader.create_bit_reader stdin;;
<sporkmonger> is there anyway to make it so that i don't have to
<sporkmonger> input_bit ();;
Linktimaw has quit [Read error: 110 (Connection timed out)]
<sporkmonger> i keep forgetting to include the ()
<Smerdyakov> There is no way to call a function without writing an argument for it.
pango_ has quit [Remote closed the connection]
<sporkmonger> ok
pango_ has joined #ocaml
<RobertFischer> sporkmonger: If you leave off the "()", you're dealing with the function as a value.
ygrek has joined #ocaml
pango_ has quit [Remote closed the connection]
<hcarty> ikatz: If you are still looking for a statistics module, ocamlgsl has some useful functions
pango_ has joined #ocaml
AxleLonghorn has left #ocaml []
pdelgallego has joined #ocaml
pdelgallego has left #ocaml []
|Catch22| has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
bongy has quit ["Leaving"]
Linktim has joined #ocaml
ChriS_T has joined #ocaml
ChriS_T is now known as Christiophe_T
Yoric[DT] has joined #ocaml
Christiophe_T is now known as Christophe_T
jonafan_ has joined #ocaml
Christophe_T is now known as ChristopheT
Linktim has quit [brown.freenode.net irc.freenode.net]
hkBst has quit [brown.freenode.net irc.freenode.net]
kelaouchi has quit [brown.freenode.net irc.freenode.net]
jonafan has quit [brown.freenode.net irc.freenode.net]
Linktim has joined #ocaml
kelaouchi has joined #ocaml
magnusth has quit ["Ex-Chat"]
hkBst has joined #ocaml
jonafan_ is now known as jonafan
ecc_ has joined #ocaml
OChameau has quit ["Leaving"]
thelema has quit [Read error: 104 (Connection reset by peer)]
|Catch22| has quit [Read error: 113 (No route to host)]
coucou747 has joined #ocaml
|Catch22| has joined #ocaml
kelaouchi has quit ["leaving"]
kelaouchi has joined #ocaml
evn_ has joined #ocaml
postalchris has joined #ocaml
schme has quit [Remote closed the connection]
bongy has joined #ocaml
thelema has joined #ocaml
Linktim has quit [Remote closed the connection]
<Ramzi181> anyone in here?
<Smerdyakov> It is considered impolite to ask that kind of question on IRC.
<Smerdyakov> Always ask your question. People will answer if they want to. It is rude to expect everyone to answer every "anyone here?" query, when it's impossible to know if the potential answerer can help the asker.
vincenz_ has joined #ocaml
ttamttam has joined #ocaml
ertai has quit [brown.freenode.net irc.freenode.net]
Ramzi181 has quit [brown.freenode.net irc.freenode.net]
vincenz has quit [brown.freenode.net irc.freenode.net]
ttamttam has left #ocaml []
ertai has joined #ocaml
Ramzi181 has joined #ocaml
vincenz has joined #ocaml
vincenz has quit [Connection reset by peer]
ChristopheT has quit [Remote closed the connection]
evn_ has quit []
Smerdyakov has quit ["BRB"]
<thelema> Ramzi181: just ask
Smerdyakov has joined #ocaml
TaXules has quit ["plop"]
<Ramzi181> thank god
<Ramzi181> Okay, so I was coding and I'm fairly sure my code is right. (Of course it's not.)
<Ramzi181> The only thing I can think of is a problem with my else syntax.
<Ramzi181> The goal of this is to produce a list of bools that are the reverse binary representation of an integer.
<Ramzi181> a positive integer.
<Smerdyakov> And what's the problem?
<Ramzi181> It always gives back all trues.
<Ramzi181> although, i am sure every line gets read.
<Smerdyakov> And what is your argument for why you think it should work?
<thelema> Ramzi181: why are you matching on the list?
<Ramzi181> Smerdyakov: My argument is that, by my hand on a piece of paper, it works correctly.
<Ramzi181> thelema: That's just to check if the list is empty or not.
<thelema> and if it's empty, you never prepend any falses
<Ramzi181> thelema: See, you don't want to have padded 0s, or in this case, padded falses on the RHS.
<Smerdyakov> Ramzi181, OK, then come up with a better argument before continuing.
<thelema> why not do your tests from 1, 2, 4, 8, etc? It looks like you're starting with a large power of 2 and going down to 1
<Ramzi181> Smerdyakov: Maybe I'll learn that code correctness proof from you some day, then I'll be able to more adequately explain to you my problems.
<Yoric[DT]> Ramzi181: have you tried #trace ?
<Ramzi181> Yoric[DT]: I don't know what #trace is.
<Smerdyakov> Ramzi181, if you write code without being able to explain to someone why it should work, then you are in trouble. Period.
<Ramzi181> thelema: The large power of 2 is the modulus. It's an inefficent way of finding the largest first divisor.
<Yoric[DT]> In the toplevel, directive #trace name_of_your_function will turn on tracing for that function.
<Yoric[DT]> After that, any call of the function will be printed-out.
<thelema> Ramzi181: when I do itob 40 on your code, I get [false; false; false; true; false; true]
<Yoric[DT]> Which is a nice way to find out where things go wrong.
<Yoric[DT]> (you could also use the debugger, of course)
<Ramzi181> really? when i do itob 40 i get all trues.
<Ramzi181> hah, your output is the output I'm looking for.
<Yoric[DT]> I get all trues.
<Ramzi181> hold the phone. how can two people execute the same code and get different outputs?
<Yoric[DT]> That's weird.
<thelema> that is wierd - I didn't do anything to your code, I just pasted it into ocaml
<Yoric[DT]> same here
<Yoric[DT]> Using 3.10.1
<Yoric[DT]> Upgrading to 3.10.2...
<Ramzi181> can you, por favor, do itob 29?
<thelema> # itob 29;;
<thelema> - : bool list = [true; false; true; true; true]
<Yoric[DT]> # itob 29;;
<Yoric[DT]> - : bool list = [true; true; true; true; true]
<thelema> I'm on a 64-bit computer... how big is your constant?
<Yoric[DT]> mmmhhh...
<Yoric[DT]> Sounds like an interesting question.
<Ramzi181> my constant is 2^30
<Yoric[DT]> # 1073741824;;
<Yoric[DT]> - : int = -1073741824
<thelema> heh
<Yoric[DT]> Sounds like a problem to me.
<Yoric[DT]> The OCaml limit is 2^30 -1 on a 32 bit computer.
<thelema> # 1073741824;;
<thelema> - : int = 1073741824
<Ramzi181> i thought the limit was 2^31 - 1 on a 32 bit computer.
<Yoric[DT]> Nope.
<thelema> Ramzi181: almost, ocaml ints are 31-bit
<Yoric[DT]> OCaml does magic with the last bit.
<thelema> (the extra bit gets used by the GC)
<Ramzi181> I don't understand. If Ocaml ints are 31 bits, then shouldn't 2^30 be handled correctly.
<Yoric[DT]> Nope.
<qwr> sign also
<Ramzi181> Ah.
<Yoric[DT]> If they're 31 bits, it means -2^30 .. 2^30 -1 .
<qwr> (gc uses a bit to have distinction between numbers and pointers. iirc)
<Ramzi181> Smerdyakov: I hope this validates me in to you, in a bit. That my error was more of a technical matter, than a coding beginner issue. (Although I am a beginner at OCaml.)
<Yoric[DT]> If you want a 30-bit unsigned integer, you need to either switch to a 64-bit computer or use Int32.
<Yoric[DT]> The second option is cheaper :)
<Smerdyakov> Ramzi181, not sure what you're saying. You're in trouble if you write programs and can't explain why they should work.
<thelema> Smerdyakov: I think you put too much emphasis on proofs of correctness. "I have only proven it correct, not tested it."
<Smerdyakov> thelema, I didn't say anything about proofs.
* Yoric[DT] admits he misinterpreted Smerdyakov's comment, too.
<qwr> uh, he says imho that if you can't explain your code to others, you don't understand it by yourself
<thelema> I wasn't necessarily responding to your last line, but your general demeanor about coding
<Ramzi181> I'm relieved to have fixed that problem. I really believed my code to be correct that time.
<thelema> there's (lots of) room for understanding things without being able to communicate them.
<Ramzi181> If it wasn't for Yoric[DT] and thelema's difference in architecture, I might have spent a lot longer of a time before discovering the issue.
<Smerdyakov> thelema, doesn't matter. If you can't explain your program, you are in bad shape.
<thelema> yay 64-bit processors
<qwr> Ramzi181: although typeing 1073741824;; in ocaml repl is quite expressive ;)
<qwr> (when you have 32 bit machine)
<thelema> Smerdyakov: at one end of the spectrum of complexity, programs are either self-evident or can't be explained, and at the other end of that spectrum, any explanation is bound to be wrong or useless.
<Smerdyakov> thelema, none of that is relevant to the kinds of programs Ramzi181 is writing now to learn OCaml.
<thelema> you love making sweeping generalizations, and I'm responding with counterexamples.
<Smerdyakov> thelema, I don't mind saying things that are wrong, when they get my intention across.
rh1 has joined #ocaml
<thelema> and for what it's worth, I think he's not too far from the self-evident end of the complexity spectrum, and hasn't has a foundation of small enough building blocks to put together to describe his program.
<Ramzi181> Smerdyakov: I think if I wanted to, I could have explained to you my program line by line.
<Ramzi181> But it was really just a base 10 to base 2 conversion. I didn't think it was necessary.
<Smerdyakov> Ramzi181, OK, then you should have done that. And also lobby for no more fixed precision integers in programming languages. :-)
<thelema> Ramzi181: sorry for underestimating you
<thelema> Smerdyakov: a proponent for the numeric tower?
* thelema wants to lobby for range checking, so that numeric overflows raise exceptions
<qwr> numeric tower rules ;)
<mbishop> thelema: they do in SML
<qwr> although both numeric tower and range checking comes with performance loss
<thelema> mbishop: I keep finding good things about SML... I'm incorporating some ideas from its Basis library into the community-ocaml stdlib I'm building
<qwr> still i would prefer the most standard number type to be numeric tower
<thelema> but being able to ask for fast, unsafe numbers too?
TaXules has joined #ocaml
<qwr> thelema: yes
<mbishop> I really like SML, it's a shame its...dead :(
<thelema> mbishop: the SMLers would likely come and harm you for that insinuation
<mbishop> I think even Smerdyakov would agree
<RobertFischer> @qwr Why can't there at least be compile-time range checking? Sure, there's a lot of points where you get into NP-Complete problems, but there's also a lot of points where stupid bugs could be caught. And I'd be willing to take range checking that catches some bugs over no safety.
<Smerdyakov> OCaml is dead, too, as far as I'm concerned. Languages with richer type systems are going to whoop its rear.
<thelema> RobertFischer: I've thought a lot about how to import Ada's range checking into ocaml.
<thelema> Smerdyakov: you may leave now.
<qwr> RobertFischer: i suspect that the performance difference between range checking and range checking _with_ switching boxed numbers on overflow wouldn't be so large
<mbishop> An ML with a hip up-to-date type system would be neat
<Smerdyakov> RobertFischer, compile-time range checking isn't going to be NP-complete for any interesting language.
<thelema> RobertFischer: dynamic range checking with static proofs that certain places don't need range checking seems easiest to me.
<Smerdyakov> RobertFischer, since "NP-complete" is a subset of "decidable."
<thelema> mbishop: what do you want, dependent types?
<RobertFischer> Smerdyakov: I'm willing to say untrue things if it gets my point across.
<thelema> lol
<RobertFischer> Smerdyakov: If there are out-and-out undecidable problems in range checking (which I'll buy -- I haven't looked into it), that's fine. But I'd be willing to take some error checking over none, even if I have to punt at points.
<RobertFischer> What I'd *really* like is a numeric type where the compiler has enough information to decide what kind of type to use.
<RobertFischer> I tell it the range, and it does the right thing.
<RobertFischer> The fact that I have to be thinking about system architecture is stupid. Compilers are much better suited to that task than the programmer.
<thelema> RobertFischer: GNAT will do that to the best of its ability
<RobertFischer> GNAT?
<RobertFischer> Got cite?
rh1 has left #ocaml []
rh1 has joined #ocaml
<RobertFischer> Ah. GNAT == Ada95 compiler.
<RobertFischer> (Assuming that's the one you're talking about: http://www.gnu.org/software/gnat/gnat.html)
<RobertFischer> Smerdyakov: Do you have an example of an interesting undecidable range problem? The problems I'm thinking of land in one of two camps: graph traversals or straight-out lack-of-information.
<Smerdyakov> RobertFischer, the halting problem easily reduces to the range checking problem for any Turing-complete language.
<Smerdyakov> RobertFischer, think of someone handing you a program. You build a new program that runs the one you were given and then makes a bad array access. The bad array access only happens if the program you were handed terminates.
<RobertFischer> Ah. That's runtime stuff. I'm just thinking about stuff known at compile time.
<Smerdyakov> I'm talking about the problem of deciding whether a program will try an out-of-bounds array access when run.
<Smerdyakov> Where "deciding" has the usual meaning from CS theory
<Smerdyakov> (That is, "dynamic solutions" are not allowed)
<RobertFischer> Right, which isn't necessarily checked by what I'm envisioning.
<RobertFischer> Unless the range of the array was known at compile-time.
<Smerdyakov> RobertFischer, I don't know what you mean in particular.
* qwr . o O ( runtime array range checking is in ocaml anyway... )
<Smerdyakov> It's undecidable whether the size of the array in a particular textual variable can be inferred at compile time....
<RobertFischer> Right, but you could always limit your access integer to some value if you knew the size of the array ahead of time. That's what I was talking about in particular.
<Smerdyakov> We are going in circles.
<Smerdyakov> Compilers can't figure out if the size of an array is known ahead of time in any general way.
<RobertFischer> Right.
<RobertFischer> That's fine.
<RobertFischer> I'm not asking them to.
<Smerdyakov> Then what are you asking for?
<RobertFischer> A system where I parameterized integer types with known ranges (when I have them).
<Smerdyakov> Have you read the Dependent ML paper(s?)?
<RobertFischer> Nope. Got cite?
<RobertFischer> (This is why I hang out in #ocaml. Interesting reading materials.)
<RobertFischer> So, when I take in an integer, I can specify that it has to have a certain value -- the possibility of it being outside that value would be a compile-time bug.
<RobertFischer> Ooh.
<RobertFischer> That's some interesting stuff.
<RobertFischer> Bookmarked for later.
<RobertFischer> Anyway, I'm back to work.
<thelema> if you have ranged integers, you can do things like having a range based on the indexes of an array.
<thelema> and then array range checks reduce to int range checks
<Smerdyakov> I think this is more or less a solved problem. It's worth reading the paper I linked (or the shorter conference version) if you're interested in extending ML to facilitate static array bounds checking.
<RobertFischer> (Okay, I'm back, but not really.) Bounds checking isn't really what I care about. Having to think about the size of my integers is what I care about -- namely, I hate doing it, and I'd like to never have to do it again.
<RobertFischer> (Now I'm gone again.)
<thelema> sadly that it's solved makes it less interesting for the ocaml gurus to implement
<thelema> RobertFischer: you want the numerical tower.
<Smerdyakov> thelema, have you read about Dependent ML? This would be a _serious_ extension to OCaml.
<RobertFischer> thelema: Except with integer (machine) types, not semantic types (going off of http://en.wikipedia.org/wiki/Numerical_tower ).
<RobertFischer> thelema: I'm perfectly happy having two kinds of numbers: integers and floats. But the fact that I have multiple kinds of integers and floats chafes.
Snark has quit ["Ex-Chat"]
ygrek has quit [Remote closed the connection]
bongy has quit ["Leaving"]
<thelema> Smerdyakov: I've read a little on Dependent ML, and wasn't impressed - maybe too big of an extension for me.
<Ramzi181> Can you check if a list is [] just like, if list = [], or do you have to use match?
<thelema> I'm not impressed by the type system keeping track of list lengths
<thelema> Ramzi181: if list = [] works fine
<Ramzi181> I suppose I've never really needed to use matching, then.
<Ramzi181> I could just use List.tl and List.hd to get the tail and head.
<Ramzi181> And otherwise just use an if to see when it's empty.
<RobertFischer> Matching reads better.
<RobertFischer> IMHO.
<Ramzi181> Because now I need to check two lists for being empty, and I think doing if l1 = [] && l2 = [] is more elegant than doing a match inside of a match.
mwc has joined #ocaml
<Smerdyakov> Ramzi181, you can figure that out with a single [match] expression.
<pango_> Ramzi181: match l1, l2 with [], [] -> done
<qwr> Ramzi181: depends. match is nicer if need head/tail. or want to do something clever depending on list contents
<Ramzi181> pango_: I didn't know that was a valid syntax. thanks
<pango_> Ramzi181: in disguise, it's just pattern matching on tuples
<pango_> match (l1, l2) with ([], []) -> ...
<Ramzi181> hmm
<Ramzi181> but it is valid without the extra parens?
<pango_> yes
<qwr> Ramzi181: the parens don't matter there
<Ramzi181> Cool. Thanks.
<pango_> btw parens in match l with (h::t) -> aren't necessary either
<qwr> the ocaml allows omitting parens almost anywhere, as long it remains unambiguous
<qwr> > [1,'a';3,'b']
<RobertFischer> qwr: Which, of course, is a really unhelpful rule. "Parens don't matter except where they do."
<RobertFischer> That
<RobertFischer> :)
<RobertFischer> That translates into something like "Try it without the parens until stuff explodes."
bluestorm has joined #ocaml
Morphous_ has joined #ocaml
<qwr> RobertFischer: i've found that remembering where they matter is easier...
<thelema> RobertFischer: yarron recently found an example where parens didn't matter and it made his syntax nice.
<thelema> back later
<qwr> RobertFischer: although the explodes _can_ sometimes cause weird errors
<bluestorm> let me guess : revised syntax troll ? :-'
<qwr> RobertFischer: like try a with b; c
<thelema> RobertFischer: parentheses are only needed to enforce order of operations
<thelema> Ramzi181: I'm going away for a bit, don't pay too much attention to Smerdyakov. :)
thelema is now known as thelema|away
<RobertFischer> thelema: Is he going to post that to Jane St's blog?
<RobertFischer> bluestorm: The fact that we can have revised syntax trolls is kinda awesome.
marmottine has quit [Remote closed the connection]
hkBst has quit ["Konversation terminated!"]
Morphous has quit [Read error: 110 (Connection timed out)]
RobertFischer has left #ocaml []
Tetsuo has quit ["Leaving"]
jlouis has joined #ocaml
Yoric[DT] has quit ["Ex-Chat"]
rh1 has quit [brown.freenode.net irc.freenode.net]
Demitar has quit [brown.freenode.net irc.freenode.net]
pants1 has quit [brown.freenode.net irc.freenode.net]
jdev has quit [brown.freenode.net irc.freenode.net]
det has quit [brown.freenode.net irc.freenode.net]
yminsky_ has quit [brown.freenode.net irc.freenode.net]
dibblego has quit [brown.freenode.net irc.freenode.net]
jonafan has quit [Read error: 104 (Connection reset by peer)]
thermoplyae has joined #ocaml
rh1 has joined #ocaml
Demitar has joined #ocaml
pants1 has joined #ocaml
jdev has joined #ocaml
det has joined #ocaml
dibblego has joined #ocaml
yminsky_ has joined #ocaml
ita has joined #ocaml
<Ramzi181> how can you group a bunch of statements to run in an if
<Ramzi181> for example, if I have if condition, 5 print statements... how can i make it so that all 5 belong to the if
<Ramzi181> instead of only the first 1, and then the other 4 always running.
<bluestorm> begin .. end
<bluestorm> or ( ... )
<pango_> or let () = ... in
<bluestorm> if a then (b ; c; d) else (e; f)
<Ramzi181> thanks.
<bluestorm> pango_: i guess it's a bit more confusing (to the newcomer) as it relies on fine-grained let .. in priorities
<bluestorm> Ramzi181: you can use if a then begin b; c; d end too
<pango_> just mentioning it for completeness
<bluestorm> (you can interchange '(' and 'begin' basically everywhere)
jonafan has joined #ocaml
yminsky_ has quit [brown.freenode.net irc.freenode.net]
rh1 has quit [brown.freenode.net irc.freenode.net]
jdev has quit [brown.freenode.net irc.freenode.net]
det has quit [brown.freenode.net irc.freenode.net]
dibblego has quit [brown.freenode.net irc.freenode.net]
pants1 has quit [brown.freenode.net irc.freenode.net]
Demitar has quit [brown.freenode.net irc.freenode.net]
<palomer> someone remind me
<palomer> how do I pattern match right at the let binding
<palomer> like f 5 = 6; f 6 = 7;;
<palomer> let f 5 = 6 ; f 6 = 7;;
<qwr> function ?
middayc has joined #ocaml
<qwr> let f = function 5 -> 6 | 6 -> 7;;
<palomer> ahh
<palomer> so the only ways to define a function is let f a = ...
<palomer> gotta go!
<qwr> you can do some some pattern matching in let
<ita> palomer: or function ...
<qwr> but i don't know how you could have multiple matches using only let
<qwr> as let (a, b) = is also pattern matching ;)
<bluestorm> i wrote a camlp4 extension snippet once, that would allow one to do haskell-like function definitions
<palomer> but nothing like let f 5 = 6 | f 7 = 8;;
<palomer> bluestorm, sweet!
<bluestorm> hum
<bluestorm> i don't think it's really usable actually
<bluestorm> and i found it to be not so useful
<Ramzi181> Can someone tell me why this is a syntax error? http://codepad.org/zaYRUNTd
<palomer> the problem with caml4p extensions is that they don't work well in emacs (you need to extend the mode too!)
<bluestorm> Ramzi181: line 14, missing ;
<Ramzi181> thanks
<pango_> and one too many line 10
<pango_> mmh no with parens line 11 it should be ok
<Ramzi181> On codepad it compiles fine, but in my Ocaml interpretter i get an error
<pango_> I almost missed it
<Ramzi181> Characters 67-79: paths_helper m n ;; Unbound value paths_helper
<qwr> Ramzi181: ; is sequence operator in ocaml. not a statement terminator ;)
<qwr> Ramzi181: that is, it is like comma operator in C
<Ramzi181> okay.
<Ramzi181> am i doing something wrong with it?
<qwr> Ramzi181: at line 10, yes
seafood_ has joined #ocaml
<pango_> works ok in the interpreter here
<pango_> qwr: doesn't matter because of parens line 11, see my previous msgs
<Ramzi181> alright, so then why is my interpreter giving me that error?
<Ramzi181> Characters 67-79: paths_helper m n ;; Unbound value paths_helper
<qwr> pango_: i tested, and you're right. has ocaml always been so forgiving?
<pango_> qwr: as far as I can remember
<pango_> (that is, around 3.05)
<pango_> can't tell for earlier versions
<qwr> ok. :)
<Ramzi181> um, it's working fine for you guys?
<Ramzi181> i'm getting that unbound value error
Demitar has joined #ocaml
pants1 has joined #ocaml
jdev has joined #ocaml
det has joined #ocaml
dibblego has joined #ocaml
yminsky_ has joined #ocaml
<pango_> val paths : (int -> int -> bool) -> int -> int -> unit = <fun>
<Ramzi181> why am i getting an error, then?
<qwr> Ramzi181: where you get it?
<Ramzi181> Characters 67-79: paths_helper m n ;; Unbound value paths_helper
<Ramzi181> and it gives a lot of weird white space.
<Ramzi181> want a screen shot?
<mbishop> you probably left out a 'rec'
<qwr> Ramzi181: as pasted, it compiles
<Ramzi181> I c/ped right from the site.
thelema|away is now known as thelema
<Ramzi181> There was a lot more white space, so I backspaced some.
<Ramzi181> And it put those weird three black squares.
<thelema> Ramzi181: ;; ends a toplevel block.
<Ramzi181> ok
<qwr> Ramzi181: save it to file and #use "thatfile.ml";;
<Ramzi181> thelema: In case you were away, my code compiles fine on Codepad, and on pango_ and qwr's computers, but not mine.
<Ramzi181> I suspect it's the comments.
* qwr thinks you deleted something needed with backspace or the winplus console fucked the multiline expression up
<Ramzi181> I didn't delete something with the backspace because it was the same thing before backspacing.
<thelema> Ramzi181: if I take the codepad and paste it into my toplevel, it works for me.
<Ramzi181> hah, I just hit enter and the console just disappeared.
<Ramzi181> I think it has to be a glitch in winplus console handling multiline expressions.
<thelema> Ramzi181: try restarting your winplus
<Ramzi181> I have several times. Same results. I just pasted the code with the comments removed, and I'm getting different weird behavior.
<Ramzi181> It's like, it just refuses to see the paths_helper part
<qwr> Ramzi181: still, try using that #use directive.
<Ramzi181> I'm new to this. What do I do exactly?
<thelema> Ramzi181: try this: http://codepad.org/Ef1GJUb8
<Ramzi181> That worked.
<qwr> Ramzi181: first lines on my terminal-window-shot
<thelema> Ramzi181: when I'm doing any big multiline, I prefer to use begin/end instead of ()
<Ramzi181> I suppose I could try it. But the use of begin and end already fixed the problem. Are you curious for me to try, qwr?
<thelema> sometimes I wish ocaml had a proper if/then/else/endif
<qwr> Ramzi181: i didn't have that error in any way
<qwr> Ramzi181: what could i try?
<Ramzi181> I understand. But I hope you trust that I did, and that I didn't doctor my screenshots.
evn_ has joined #ocaml
<Ramzi181> qwr: I meant, did you want me to try the #use to see if that still causes the same error.
<Ramzi181> I think my Ocaml interpretter doesn't like () for multilines.
<qwr> Ramzi181: you could try it. that error is weird imho.
<Ramzi181> I'm not gonna bother with it.
<pango_> Ramzi181: ( / ) and begin / end can be used interchangeably
<thelema> Ramzi181: I don't have a good explanation for why it failed, I'm happy it's working now.
<pango_> # begin 2 + 3 end * 5 ;;
<pango_> - : int = 25
<thelema> pango_: have you seen his screenshot of the same code with () failing, but begin/end succeeding?
* thelema thinks it could be the *))
<pango_> I suspect ocamlwinplus is buggy, not the ocaml interpreter
postalchris has left #ocaml []
bluestorm has quit ["Konversation terminated!"]
<qwr> pango_: that's why i thought that #use could work
<Ramzi181> hmm
<Ramzi181> thelema: when I put my comments back in, your code still fails
<Ramzi181> that is, the begin/end doesn't work.
<Ramzi181> my comments are causing trouble
<thelema> apparently the toplevel doesn't agree with your comments
kopophex has joined #ocaml
<pango_> http://caml.inria.fr/mantis/view.php?id=3836 (open for over 2 years? mmh)
* thelema sees nothing unusual in your comments
<thelema> heh. apparently ocamlwinplus has lots of fail.
<Ramzi181> i see.
evn_ has quit []
jlouis has quit ["Leaving"]
Axioplase has joined #ocaml
ita has quit [Remote closed the connection]
ikaros has quit ["segfault"]
alexyk has joined #ocaml
<alexyk> greetings -- how do you compose two functions into a single parameter to List.map?
<alexyk> e.g., we want to print_int x; print_newline () for each element of [1;2;3]
<thelema> let compose f g x = f (g x)
seafood_ has quit []
<alexyk> and how will it look in List.map?
<thelema> List.iter (fun x -> print_int x; print_newline ()) [1;2;3]
psnively has joined #ocaml
<thelema> you don't want map, you want iter (because you're not constructing a new list)
<thelema> and you just want one function that does printing, no?
<alexyk> ah, yes...
<alexyk> but I was still a bit surprised not to find an easy infix compose
<thelema> ;
<alexyk> say, I want print_int of int_of_string
<thelema> how is ; not what you're looking for? You don't need compose, you just need sequencing
<alexyk> yes -- it's a different question :)
<alexyk> so I want to have a print_int on int_of_string as a function
<thelema> ok. There isn't a builtin operator to do this - my first answer seems appropriate
<alexyk> naturally I'd create it with compose -- and I want to use an inner dot or similar infix
<alexyk> yet can't do it
<alexyk> tried let (|>) f g = function x -> f (g x);;
<alexyk> to replicate F#'s
<alexyk> # print_int |> int_of_string "1";;
<alexyk> This expression has type int but is here used with type 'a -> int
<thelema> and that doesn't work? List.iter (print_int |> int_of_string) ["1";"44"]
<thelema> (print_int |> int_of_string) "1"
<alexyk> arrgh! thx :)
<alexyk> what's the easiest way to split a line on whitespace?
<alexyk> I found Pcre.split; is there anything simpler using Str?
<alexyk> without creating a Str.regexp -- seems not to take perlish \s+...
<alexyk> so I created a Str.regexp "\\( \\|\t\\)+"
<alexyk> which is just plain ugly
<thelema> use pcre if you want prettiness
<thelema> otherwise your regexp is where it's at.
<mwc> indeed, the built in regex module is pretty spartan
<thelema> mwc: the whole stdlib isn't nearly what you get in Java or .net
<palomer> oh my
<palomer> methods without arguments act just like functions
Axioplase has quit ["leaving"]
* palomer squashes a big bug
<qwr> alexyk: Str.regexp "[ \t]+"
<alexyk> qwr: thx, indeed!
<alexyk> why do we need to supply () in print_newline () ;; ?
<alexyk> it looks like python...
<qwr> alexyk: because just print_newline is function value
<thelema> alexyk: if you just say print_newline, you've got a function
<alexyk> yes -- we;; ruby knows how to avoid ()...
<alexyk> well
<thelema> that function takes an argument: () and does something, and returns ()
<qwr> alexyk: whitespace between expressions acts like apply operator
<qwr> alexyk: so (a b) should be read as a <APPLY> b
<qwr> alexyk: and if you omit b you'll get just a
<alexyk> right -- and unit is a minimum we can give a fun?
<qwr> alexyk: and () is a unit value that will be given to print_newline as argument
<alexyk> why isn't print_newline some kind of value which needs nothing at all?
<qwr> alexyk: it's just a convinient value from a type, that has only one possible value
<Smerdyakov> alexyk, that's not compatible with OCaml's semantics.
<psnively> I like a spartan stdlib... but I do wish more of the functions were properly tail-recursive.
<qwr> alexyk: because value alone does _nothing_
<palomer> alexyk, you're thinking in haskell terms right there
<thelema> psnively: that's (more) fixed in community-ocaml
<thelema> alexyk: then you couldn't do [List.iter print_newline [();();()], or use print_newline as a callback or any use of it as a function.
szell has joined #ocaml
<Smerdyakov> thelema, I think that's not a good way of describing it, since allowing variable reference to have side effects would be a big change to OCaml; it's not even clear what the alternative means.
<psnively> thelema: Is this distinct from ExtLib?
<palomer> does it even make sense to allow variable reference to have side effects?
<qwr> palomer: you could create such semantics ;)
<qwr> but it would be quite different language then
<thelema> psnively: I've borrowed some code from extlib, and other libraries, some doesn't exist elsewhere, and it's all merged into the stdlib
<palomer> you wouldn't even have eta reduction!
<qwr> and i'm not sure how the type system would work then...
<psnively> "Merged into the stdlib" how?
<thelema> palomer: within a certain (syntactic) context, you could have unit functions auto-evaluate. The problem is that ocaml doesn't have a separate context for that - it's all expressions.
<alexyk> qwr: "a value alone does nothing" - a cool way to put it, like Mayakovsky's "voice of one is thinner than a squeak" :)
<thelema> psnively: as in it's a complete ocaml distribution, when you compile and install it, you use the improved functions as if they always were part of the ocaml stdlib.
<psnively> thelema: Oh!
<psnively> I didn't know that. Thanks!
<alexyk> thelema: how does community-ocaml relate to godi?
<thelema> alexyk: no relation - community-ocaml intends to provide a distribution of the base ocaml system that has a number of improvements.
<palomer> you would have weird behaviour, like foo and (fun i -> foo i) would be very different functions
<psnively> I wish someone would add the SO_REUSEPORT option for sockets...
<qwr> palomer: i think easist _hack_ in that direction would be discovering unification of unit -> unit with unit type and rewriting such variable reference into application of (). but imho it would be quite awful hack...
<thelema> alexyk: community-ocaml only exists as a git tree at the moment.
<Smerdyakov> qwr, bye-bye principal types....
<thelema> I imagine it wouldn't be difficult with some extra syntax -- ((% print_newline; (fun () -> print "foo") %))
<alexyk> a noob's question: so I now have a .ml file which works inside Emacs in tuareg mode. Now I want to run it at the shell prompt. When I do ocamlc script.ml it complains about the lack of cmi from mli. Do I have to have an mli? And does ocamlc do byte-compile or native?
<Smerdyakov> alexyk, the latter question should be really easy to answer with the manual.
seafood_ has joined #ocaml
<alexyk> yep, just to make sure :)
<thelema> alexyk: ocamlc produces bytecode, ocamlopt produces native. you don't need .mli
<alexyk> yes -- that's why I was curious why ocamlc script.ml asked for cmi
<Smerdyakov> alexyk, you read the manual, which says this point blank, and you weren't sure if you should believe it?
<qwr> thelema: yes. but imho it gives no real value for extra syntax as the f () is just fine and most consistent option imho
<Smerdyakov> alexyk, .cmi files are neither bytecode nor native code. Both compilers use them.
<palomer> is there a function that takes a function unit -> x and and int and creates a list of x ?
<palomer> (in the stdlib)
<thelema> Smerdyakov: there's a saying: "given three corners of the room, a student should be expected to find the fourth" - sometimes you seem to expect people to find three corners.
<thelema> palomer: no, but it's not difficult to write, either using recursion or a for loop and a ref []
<qwr> palomer: it would terminate by catching some exception?
<palomer> qwr, the length of the list is specified by the int
<qwr> ah ok
<alexyk> Smerdyakov: in the absence of an all-encompassing ocaml bible-like book, I'm never sure of anything until I get an authoritative answer form a live expert like you -- I've enjoyed your site immensely !:) (but I should RTFM too...)
<qwr> palomer: i suspect that there is no such beast in library
<thelema> let rec (--) = fun m n -> if m >= n then [] else m::((m + 1) -- n)