9 ms·
OCaml Briefly
- glifchits 12y agoAfter seeing that Facebook's Flow tool was written with an OCaml parser, I was quite impressed by the beauty of its syntax. It makes functional programming feel much less intimidating, compared to Haskell or a Lisp in my opinion, and I can see the parallels to F#. Thanks for sharing this introduction, it was very apropos for me!
- tel 12y agoF# more or less started with OCaml, took some features away, added some others. If you're familiar with F# then OCaml will look natural. Though, that said, if you're familiar with OCaml then Haskell should be rather easy to pick up syntactically.
- jordigh 12y agoThere's one big difference, huge difference in my opinion, between Haskell and OCaml: OCaml makes monads almost invisible. They're much more in-your-face in Haskell. I'm not sure which one I like better, but it's nice to have a plain ol' for-loop available in OCaml.
- bad_user 12y agoMaybe, but that's not a huge difference, because when working in a language that has monads in it, then one has to get monads (in the same sense that one has to understand iterators in other languages). There's no way around it - thankfully it isn't that complicated, too bad all of these articles flying around make it seem so. The one humongous difference is that Haskell is non-strict and this changes everything.
- amirmc 12y agoI was going to ask whether 'non-strict' means lazy but I decided to look it up first. I thought others might also find it interesting. https://www.haskell.org/haskellwiki/Lazy_vs._non-strict https://www.haskell.org/haskellwiki/Lazy_vs._non-strict
- thinkpad20 12y agoI think Haskell's purity is a more humongous difference than its non-strictness, at least when you're talking about non-performance-critical applications. Laziness can produce unintuitive behavior in a program, and can make certain things harder, but purity is much more "in your face" as a programmer, and a more significant hurdle to beginners -- or at least, it was to me. I agree, though, that as the programmer becomes more sophisticated, the laziness aspect becomes a more significant difference and, ultimately, probably the biggest reason why Haskell will likely never become truly mainstream. Fortunately, there are promising languages out there which are both pure AND strict, such as Idris, Ur and Manticore.
- dllthomas 12y agoOf course, historically, there's the argument that Haskell's purity was motivated by its non-strictness. "Wearing the hair shirt" and all.
- chriswarbo 12y agoWell, the motivation was to be pure. Non-strictness removed the temptation to extend the language in non-pure ways, either intensionally or accidentally, for the sake of convenience.
- dllthomas 12y agoYou're right, of course. Though if they had cheated, the result probably would have been less interesting.
- ihm 12y agoCould you explain what you mean by this? I'd say using monads is way more "in-your-face" in OCaml since you have to explicitly say which monad you're using (via opening a module or what have you) and there's no do-notation. Perhaps you mean that one doesn't need monads as much in OCaml since it's impure and so they aren't required to manage state?
- technomancy 12y agoTo be this is a community factor rather than a technical one. You can't talk to a Haskell person for five minutes before they're trying to explain monads to you, (often whether you already understand them or not) and to an OCaml programmer they're just another tool.
- agumonkey 12y agoHi, this is the first time I hear that OCaml embeds monads invisibly ? meaning IO has no special status ? or is there some built-in module ?
- tel 12y agoIO has no special status in OCaml.
- mercurial 12y agoI'd rather say that the big difference is that since OCaml is impure, you're going to run into much less monads in general (though you do have monadic libraries like lwt).
- tel 12y agoThat's definitely a big difference: OCaml's impurity. Everything exists in a natural (sort of, see below), invisible monad. Let binding can be both pure and impure since impure statements just return plain values upon execution. Furthermore, this is why you have to use (;) all over the place---it's really just the monadic (>>). Which just goes to show that monads are actually totally natural. Force someone to live in one all of the time and they just forget it's there. The major thing is that such monads don't play nicely with laziness which drove Haskell to develop (partial) purity the way that it did. This plays out in OCaml where you have to explicitly say exactly when you're forcing lazy thunks which lets the sequencing of operations remain clear.
- seanmcdirmid 12y ago> Which just goes to show that monads are actually totally natural. Force someone to live in one all of the time and they just forget it's there. How is that different from saying "mutable state is natural?" I mean, if you don't see the monad, aren't we just right back at imperative programming, or is OCaml implemented with real monads under the cover that make a significant difference to the programming experience? Does it even have a basic effects system?
- tel 12y agoYou can build a basic effect system in the same way you do in Haskell (except without typeclasses you need to be more explicit about which monad you're living inside of). Without syntax sugar this is a bit noisier, of course. Also, without typeclasses transformer stacks are difficult and `mtl`-style transformers are impossible (I think). So, you can think of OCaml's semantics as living inside of a monad. Or just do it all implicitly by giving basic semantics to ;. And the way I was speaking I mean to say that "mutable state is natural" too. I don't know that it is universally, but it's certainly something that makes 90% of programmers today feel comfortable.
- seanmcdirmid 12y agoDoes OCaml actually need to apply special semantics to ; or do those already come with strictness? Thanks for the response BTW, this is one of those things I've always wondered about. > And the way I was speaking I mean to say that "mutable state is natural" too. I don't know that it is universally, but it's certainly something that makes 90% of programmers today feel comfortable. Well, as long as time and change are considered.
- Dn_Ab 12y agoOCaml doesn't so much make monads invisible (except for a technical yet handwavy note on semicolons just as true for C) as make them unnecessary due to being more pragmatic. It's strict and allows mutability when necessary. Of course explicitly recognizing when you're using a monad is extemely powerful and allows elegant formulations of lots of wonderful things like LogicT, probabilistic computation and continuations. Specific instances of monads are definable in most languages in use today, it's when you want to generalize over monads that Haskell stands out. For that you want higher kindedness, Ocaml can simulate them using the module system but it's rather cumbersome. There is a work around described here: https://ocamllabs.github.io/higher/lightweight-higher-kinded-polymorphism.pdf https://ocamllabs.github.io/higher/lightweight-higher-kinded.... The work around is also applicable to the cousin, F#: https://github.com/palladin/Higher/tree/master/src/Higher.Core https://github.com/palladin/Higher/tree/master/src/Higher.Co...
- gaze 12y agoI think you're munging your terminology. Side-effectful computations in haskell are done inside the IO monad. A monad is not in general a thing for side-effectful computation. They are made unnecessary for side-effectful computation in o'caml because of the inherent support for mutability. Indeed side-effectful computation can be represented as a monad, and therefore the ; in ocaml might be interpreted as a bind. Something just needs to satisfy the monad laws in order to be a monad. However, in Haskell the IO monad is explicitly defined. This is very important. The do syntax is sugar over monadic binding them together. In ocaml, sequential computation is simply scheduled sequentially. In haskell, something of type IO () is a VALUE which corresponds to an ACTION which can be RUN. The function which returns the IO action is still pure. It is the outside world which consumes the IO action and performs it. In o'caml, functions are merely impure as in other languages. The function that prints 3 and returns 8 in ocaml has type "int". The function that prints 3 and returns 8 in haskell has type "IO Int"...
- LeonidasXIV 12y ago> OCaml makes monads almost invisible. That is not true at all. If you have worked with any monadic data structure that is not hardcoded into the compiler (like List) for example Lwt you would see how tedious handling monads is. So tedious that not one but four syntax extensions exist to make it less boilerplate heavy (pa_lwt, lwt.ppx, pa_monad, omonad).
- pseudonom- 12y agoCare to elaborate on what you like about its syntax? I can imagine preferring it to Haskell or Lisp, but not thinking it's beautiful.
- glifchits 12y agoLooking at a random file in the Flow source [0] (* The entry point *) let rec go content = let env = { file = None; modified = []; line = 0; result = [] } in let lines = split_lines content in start env lines; match List.rev env.result with | [] -> [] | _ :: results -> results (* Skip the text before the first +++ (to make things work with git show) *) and start env = function | [] -> () | line :: lines when String.length line > 4 && String.sub line 0 3 = "+++" -> header env line; modified env 0 lines | _ :: lines -> start env lines Its beautiful to me because its very concise looking, while still using a fair bit of real English, meaningful symbols, and idioms like [] makes an empty array or whatever. I have to admit, much of this is lost on me, but it does feel more accessible than other FP languages. It almost has a Python feel. [0] https://github.com/facebook/flow/blob/master/hack/parsing/format_diff.ml#L67-L83 https://github.com/facebook/flow/blob/master/hack/parsing/fo...
- sampo 12y agoI agree that OCaml syntax is relatively nice, and very readable. But the first line let rec go content = may be problematic for an outsider who doesn't know that let and rec are keywords. It means let recursive function go(content) = ...
- edwintorok 12y agoLooks better with syntax highlighting: https://paste.debian.net/133342/ https://paste.debian.net/133342/
- deleted 12y ago[deleted]
- carlob 12y agoThis was written by an issuu engineer. Does anyone know if issuu uses OCaml?
- auvi 12y agoLooks like issuu uses OCaml in the backend [0]. [0] http://issuu.com/careers/ocamldeveloper
- mads_hartmann 12y agoYeah, most of the services that I work on in my team at issuu are written in OCaml :)
- carlob 12y agoGreat to know people using such an interesting language (and also being based in Europe)!
- vosper 12y agoI have been interested in OCaml for a while, and this is a nice piece. One question, though - some of the examples start like this: - : Is that the prompt from the OCaml REPL (does OCaml have a REPL)? EDIT: I think I misread things - it's the output from the examples that has the "- :" prefix, so I'm guessing it is REPL output.
- arthurcolle 12y ago# let x = 5;; val x : int = 5 # that's what the REPL looks like on my end
- gnuvince 12y agoThat's what the prompt answers back. # 3;; - : int = 3 # fun x -> x*x;; - : int -> int = <fun>
- deleted 12y ago[deleted]
- mads_hartmann 12y agoThe grey boxes are the input to the REPL. You should be able to just copy paste the contents of any of the boxes. The green boxes are the output of the REPL.
- yawaramin 12y agoYou can think of '-' as meaning 'the last evaluated expression' and ':' as meaning 'has the type'. So the OCaml repl replies to your input by saying something like 'the last evaluated expression has the type ...'.
- codygman 12y agoHow does Ocaml do on having predictable memory usage? This is still a weak spot in Haskell, though I absolutely love the language and it hasn't mattered yet for my use cases. Doesn't it hurt having a GIL? How awesome is having the ML module system?
- mads_hartmann 12y agoOCaml has an extremely predictable memory usage. Part III of Real World OCaml covers this is great detail[1] GC pauses haven't hurt us really. We usually just spawn a ton of processes so if one process pauses a bit to GC we won't notice. The module system is awesome. It's something i plan to cover next time I find the time to extend the article. [1] https://realworldocaml.org/v1/en/html/pt03.html https://realworldocaml.org/v1/en/html/pt03.html
- jamii 12y agoThe ocaml runtime is wonderfully simple (http://rwmj.wordpress.com/2009/08/04/ocaml-internals/ http://rwmj.wordpress.com/2009/08/04/ocaml-internals/) and the compiler focuses mostly on good codegen rather than advanced optimisations. In practice, it's common to be able to look at a block of code and predict how fast it will be and how much memory it will allocate. This is not my experience in haskell - the difference in performance when certain optimisations do or don't trigger is huge and is hard to predict just by reading the source code.
- pjmlp 12y ago> Doesn't it hurt having a GIL? There is ongoing work to make the runtime multicore friendly without GIL. Plus the GIL doesn't affect when you write concurrent code, which makes use of green thread, think go-routines. It is only an issue in Python and Ruby because they jump out to C extensions which use the GIL, while OCaml is a native compiled language. Anyway OCaml vnext whenever comes out, might be GIL free.
- yodsanklai 12y agoI'm very surprised articles about OCaml (and more generally functional programming) are popular on Hacker News. FP isn't exactly a new thing. I would assume most CS graduates have experience with functional programming (I learned "Caml Light" as an undergraduate in 1996).
- dragonwriter 12y agoI think -- even if they were exposed in school, and not all working programmers are CS graduates -- that many working programmers have little current experience with FP, and many lack either experience or current awareness of any particular FP language addressed in any given article (or, if they do, don't have experience with it in the context that the article is presenting.) Such that, even though they might be distantly familiar with FP in general, its quite likely that articles on particular FP techniques, FP languages, or applications of FP to a particular problem area can still be useful. Sometimes, it'll be useful just by reminding you of something you've been too caught up with dealing with what is immediately useful to think much about since school, but which might be more applicable to the problems you have now than the problems you had in programming work closer to the time you were in school.
- agravier 12y agoAs you learned Caml Light, chances are you went to a French university. As far as I understand, outside of France, OCaml/Caml Light are seldom taught at university. WRT FP, many universities will use Java or C++ to teach programming fundamentals (a terrible thing imo). Some teach or used to teach Scheme or Python.
- drifkin 12y agoWe did a little bit of OCaml in our undergrad PL class at UCLA. If I remember correctly, it was only a couple weeks, and you're probably right in that it was a bit unusual. The less exotic classes I took mostly used C++.
- fab13n 12y agoFP isn't a new thing in academia. But having it used in practical conditions, by companies intended to make money and writing "normal" software (i.e. not things related to formal semantics), is still really newsworthy. And that's OCaml's appeal IMO: it focuses on things that aren't sexy to academics. Good compiler performances due to careful codegen rather than exotic theories, willingness to be "polluted" by side-effects rather than wrangling monad transformers, eager evaluation to get predictability rather than cute code...
- e12e 12y agoHaving a quick look at ocaml again, I find I'm hoping someone will take the time to write a "How I start"-article[1] for it, detailing things like installing (something like wget raw.githug...opam_installer.sh && ./opam_installer.sh bin - that gets you the latest opam locally), setting up janestreet core and utop, and finally bootstrapping some kind of not-entirely-trivial hello-world app and/or library for use with "opam install ...". I did for instance find a couple of interesting (to me) libraries: https://github.com/esperco/ocaml-imap https://github.com/esperco/ocaml-imap and https://github.com/nojb/ocaml-maildir https://github.com/nojb/ocaml-maildir . But only the first can i "opam install" -- as a newcomer to ocaml (or returnee of sorts) -- I my intuition tells me that being able to set up a chroot/image with just stuff via opam would probably be what I want. But that's exactly why it'd be nice if someone that actually does this (and uses ocaml in anger) wrote up a proper "How I start"-article. [1] https://howistart.org/ https://howistart.org/
- rhizome31 12y agoIs there a tutorial out there showing off the OCaml tooling from a working coder perspective? I mean setting up a project, managing dependencies, debugging, testing, etc. I really think that average joe programmers like me could benefit from features offered by strongly typed FPL, but lack of good tooling is a show stopper. Elixir does an amazing job at this, but it's not as safe and general purpose as OCaml or Haskell.
- pjmlp 12y agoSomething like this? https://realworldocaml.org/ https://realworldocaml.org/