Live data from Hacker News

Why OCaml, why now? (2014)

spyder.wordpress.com

51–60 of 132 posts

Re: Why OCaml, why now? (2014)

#51

One thing I don't like about OCaml is that I always find myself writing the same things, like "to_string" functions for my variant types (although there must be some ways to alleviate this burden). Also, when your programs use abstract data types you lose the benefits of pattern matching. In that case, I'm happier with languages like Go or Ada with a friendlier syntax.

If you have an ADT but want pattern matching, try Scott Encoding.

For instance, here we have Option

    module Option = struct
      let scott (some : 'a -> 'r) 
                (none : 'r) 
                (opt  : 'a option) =
        match opt with
        | Some a -> some a
        | None   -> none
    end
For Option, since it's non-recursive, the Scott Encoding and the recursor/inductor/Church Encoding are identical. Here's a linked list, though

    module LL : sig
      type 'a t
      val fold  : ('a -> 'r -> 'r) -> 'r -> ('a t -> 'r)
      val scott : ('a -> 'a t -> 'r) -> 'r -> ('a t -> 'r)
    end = struct      
      type 'a t = Cons of 'a * 'a t | Nil
      let rec fold cons nil = function
        | Cons (h, t) -> cons h (fold cons nil t)
        | Nil         -> nil
      let scott cons nil = function
        | Cons (h, t) -> cons h t
        | Nil         -> nil
    end
Anyway, the pattern should be more clear now. These provide effectively "functionalized" pattern matching which you can apply whenever you need. In particular, you can think of these as expressing a (potentially partial) "view" of the abstract type. For instance, my linked list might have not been a linked list exactly but instead some kind of tree, but `scott` and `fold` let me expose a "view" of that tree as though it were a linked list.

Re: Why OCaml, why now? (2014)

#52
Nice post! There are a lot of good reasons to use OCaml over Haskell which are more compelling than “JavaScript”, though. A few of them are:

1. modularity (and now that they have added generative functors à la SML, you can have true abstraction)

2. benign effects: in Haskell "proper", you do not have effects; rather you have "codes" for effects, which get interpreted into effects by the RTS; this rules out the possibility of, e.g., using effects to implement a semantically pure interface. On the other hand, OCaml has actual effects, which can be used in an open-ended way to implement all sorts of functional interfaces.

3. strictness: arguments abound about whether laziness or strictness is better; for me, it comes down to the fact that with some pain, you can embed laziness in a strict language with effects, but you cannot embed full-on ML-style strictness into a language like Haskell; moreover, strictness-by-default permits safe uses of benign effects.

I'd call Haskell an expression-oriented programming language, since the types end up classifying expressions and algorithms (i.e. the particular "effects" you used get put into the type). Whereas I'd say (OCa)ML is a value-oriented language, since values (canonical forms) are considered separately from general expressions (canonical and non-canonical forms); moreover, implementation details don't end up in the types, so you can really consider them to be classifying values and functions (i.e. equivalence classes of algorithms, not algorithms themselves). This is largely orthogonal from strictness vs laziness, but as soon as you add partiality in, strictness becomes the only tractable way to have canonical-form-based meaning explanations for the judgements of the theory.

P.S. My day job is writing Haskell. (In case the Pedagogical Brethren wish to come and "correct" me.)

Re: Why OCaml, why now? (2014)

#53
post #48

Earlier quoted context omitted.

I won't claim any special knowledge, nor do I have any actual solid research to back up my intuitions. I can certainly recognize the feeling that O'Caml makes you more productive from when I first discovered it, but that was mostly just because of algebraic datatypes. (And pattern matching which, while not terribly useful in general circumstances, is hugely useful in practical CRUD-like applications.) Polymorphic var…

(Note, not being critical of you, just placing this here because I was thinking about it recently) Maybe because CS is so young, there is a tendency to confuse theory and practice. Whether a particular language makes one more productive isn't math, it's engineering. When we talk about how monads might allow you to separate concerns and relieve a mental load -- we are talking engineering. When we talk about how monads…

I won't address all your points, but I think [1] deserves special attention: I think we can all agree that if you want to write software that will let you land a small vehicle on Mars, then you don't want/need the opinion of a theoretician, you just need $1B and a team of extremely disciplined programmers who will ADHERE TO PROCESS. Then you impose so much process that they either leave or prevail. What we're speculating about here (at least I think we are?) is if this is a sustainable model for general development and if we can do better. Even if we can't get better runtimes from FP languages, could we perhaps make programs which generate better C programs than those elite programmers that were chose for this particular mission? (I think we can. It has very little do with humans, but a lot to do with the fact that programs are very meta in that we can create programs that generate programs that generate programs ad-infinitum. If we can get our specifications right, the rest becomes trivial.)

A Mars lander program director explicitly said that he chose C because it was what he was familiar with. (I'll edit and post a link if I can find the video.) Just for context, his decision was also based solely on familiarity and experience. For him it wasn't quite so much about language, it was more about process (6 different industrial-strength linters, etc.)

> Just because something is elegant mathematically, does not mean it's good engineering practice. Haskell, for example, can be practical, but it struggles between the math and the reality of limited machines and human cognition[2]. Likewise, when you start talking about SML vs OCaml, you're talking engineering, not math -- and possibly a language tailored to engineering vs math.

That's the thing I would dispute, but it's hard to convince people who aren't already drinking the Kool-Aid, as it were. Compared to compiler-assisted reasoning about side-effects, the difference between SML and O'Caml is completely trivial.

Your [2] is just absurd :). Clearly, you don't have to understand the body/implementation of a function, just its type. :)

More seriously, I'd be interested if there's a particular experience that soured you on FP (or perhaps Haskell, in particular)...?

Re: Why OCaml, why now? (2014)

#54
post #14

Earlier quoted context omitted.

Total agreement about most of those things, but I want to indicate that Haskell has some amount of row typing available via libraries like Vinyl and it certainly has c-types.

the most recent vinyl version (0.5) https://hackage.haskell.org/package/vinyl-0.5 winds up being a REALLY nice balance of flexibility, good type inference, and a few other things. Its actually simple enough that for a work project I decided it would be simpler to write a custom version of the same datastructure just to avoid extra deps. (and because I needed some slightly bespoke invariants)

:) Thanks! And yes, I don't know about Anthony, but my intention has always been for Vinyl to be a proof-of-concept for what happens when you try to make a clean, minimal & well-factored HList experience; my motto is, “Now build your own Vinyl”.

Re: Why OCaml, why now? (2014)

#55

Nice post! There are a lot of good reasons to use OCaml over Haskell which are more compelling than “JavaScript”, though. A few of them are: 1. modularity (and now that they have added generative functors à la SML, you can have true abstraction) 2. benign effects: in Haskell "proper", you do not have effects; rather you have "codes" for effects, which get interpreted into effects by the RTS; this rules out the possib…

I generally prefer programming with immutability, but I certainly appreciate the ability to use "benign effects" in my programs. Besides the case for performance, I have applied a strange combination of benign effects, GADTs, and functors to generate a sort of "proof of type equality" between two values passed into a framework, each of which are not known to the framework because they're passed into the framework by two separate clients of the framework. At that point, I had the ability to reason about two values with arbitrary and potentially distinct types, as either being not the same (None), or the same Some(x, y) with x and y having the same type.

I have no clue if there's a more elegant way to do this (edit: there probably is), but even I (as a n00b) was able to figure out how to do this by using benign effects. There's only a single mutation in this library - but it was such a critical one that made everything else possible.

I'm curious about the reason for preferring generative functors over applicative functors. It seems like both could have valid use cases. Could you point me to a writeup that explains why you believe generative functors are superior?

Re: Why OCaml, why now? (2014)

#56

I think the author doesn't give enough credit to things that OCaml has that Haskell doesn't have: a powerful module system (ie, functors), polymorphic variants/subtyping, etc.

There's a bunch of other nice features of OCaml such as named arguments, fast compile times, strictness, c-types, and reasonable records. To achieve (some of the feature in) Elm style "structural subtyping" records in OCaml you use the more verbose "object" keyword which is just a record with row polymorphism. Most choose to stick with standard records because they compile to more efficient code. I think the ML modul…

Named arguments may be just "syntax sugar" but its one of the biggest things I miss from Haskell. They make library functions more consistent and they also make it much easier to write point free code because you don't need to resort to combinators like "flip" or "." as much.

Re: Why OCaml, why now? (2014)

#58
post #11

I think the author doesn't give enough credit to things that OCaml has that Haskell doesn't have: a powerful module system (ie, functors), polymorphic variants/subtyping, etc.

Toolchains also matter and OPAM (the package manager) has gone from strength to strength since this post. It's the basis for the OCaml Platform which combines a number of useful tools and libs into a coherent workflow (making development much more productive).

OPAM still doesn't run natively on Windows though :(

Re: Why OCaml, why now? (2014)

#59

Earlier quoted context omitted.

Could anyone summarize how well PureScript and Elm treat sourcemaps/debugging in the browser? For a while I thought that js_of_ocaml didn't support sourcemaps, but it turns out, one of my dependencies wasn't compiled with debug flag (-g) and I was able to get a pretty good sourcemaps/debugging experience in Chrome dev tools once I fixed that issue. Is there something js_of_ocaml can learn from PureScript/Elm's JS com…

I can't really comment on source maps in Elm, but the approach in PureScript has been to generate clean, readable JS which is debuggable directly. Source maps are on the roadmap, but not really a priority right now. I haven't heard any complaints about the ability to debug compiled PureScript yet.

That's a nice approach for debugging! If the mapping is close enough, I don't mind reading the JS output. I'm curious about the general approach to compilation, though. It seems like a statically typed language could take advantage of the knowledge of types to generate an even more efficient version of the program that uses typed arrays and views (though, yes, it would require implementing a garbage collector unless relying on some kind of WeakMap in the JS engine). I've heard of garbage collected languages compiling to LLVM which would allow Emscripten to assist you, but I've also heard that LLVM has a really hard time with GC languages.

Re: Why OCaml, why now? (2014)

#60
post #51

One thing I don't like about OCaml is that I always find myself writing the same things, like "to_string" functions for my variant types (although there must be some ways to alleviate this burden). Also, when your programs use abstract data types you lose the benefits of pattern matching. In that case, I'm happier with languages like Go or Ada with a friendlier syntax.

If you have an ADT but want pattern matching, try Scott Encoding. For instance, here we have Option module Option = struct let scott (some : 'a -> 'r) (none : 'r) (opt : 'a option) = match opt with | Some a -> some a | None -> none end For Option, since it's non-recursive, the Scott Encoding and the recursor/inductor/Church Encoding are identical. Here's a linked list, though module LL : sig type 'a t val fold : ('a…

If you look at this from an "expression problem" point of view, this version with the records-of-functions is very similar to OO programming. But without inheritance, classes and so on.
Post reply on HN