Live data from Hacker News

Why We Use OCaml

tech.esper.com

21–30 of 144 posts

Re: Why We Use OCaml

#21
post #11

Earlier quoted context omitted.

the "with-" pattern (originally from lisp, i believe, but ruby did a lot to bring it to the masses), where something like a filehandle manages its own lifecycle, and calls your closure in between. so rather than the C-like let f = open-file-for-writing(filename); for line in array { write-line-to-file(f, line); } close-file(f); you can do with-open-file-for-writing(filename) {|f| for line in array { write-line-to-fil…

Of course, you can build your own closure: void do_stuff_with_file(struct relevant_data *, FILE *); ... { struct relevant_data data = { ... } with_open_file_for_writing(do_stuff_with_file, data, filename); } IMO, the biggest downside there being how far it typically pushes the definition of that function from the call site. Small functions - a good practice anyway - ameliorates that a bit.

you can, but it's sufficiently clunky that it simply doesn't feel like a natural thing to do in the language. good language design is a lot more about the things it makes easy and natural than the things it makes possible.

Re: Why We Use OCaml

#22
post #11
post #4

Could someone comment on what instances you would typically apply lambdas and closures in real-world code? I figure that they are at least more convenient than callbacks with a *userData parameter like in C.

the "with-" pattern (originally from lisp, i believe, but ruby did a lot to bring it to the masses), where something like a filehandle manages its own lifecycle, and calls your closure in between. so rather than the C-like let f = open-file-for-writing(filename); for line in array { write-line-to-file(f, line); } close-file(f); you can do with-open-file-for-writing(filename) {|f| for line in array { write-line-to-fil…

You can also wrap the call-closure with an exception handler to make sure that 'f' is always closed when you leave with-open-file-for-writing.

Re: Why We Use OCaml

#23
post #4

Could someone comment on what instances you would typically apply lambdas and closures in real-world code? I figure that they are at least more convenient than callbacks with a *userData parameter like in C.

One instance would be function composition. If functions are values in your language, you can define function composition in the language, that is given a function f : a -> b and g : b -> c, you can define their composition g . f : a -> c as

g . f = \x -> g(f(x))

(Here \ denotes lambda)

Why would it be useful to have function composition in your language? Well it gives you similar power as "method chains" in an object oriented language, without being tied to specific classes, especially if the language also supports polymorphic functions. It also interacts nicely with other abstractions usually found in functional languages: For example consider map, of Map-Reduce fame

map : (Functor f) => (a -> b) -> (f a -> f b)

then one has

map (g . f) = map g . map f

Now imagine that map would cause the function to be send to thousands of nodes in a cluster, then the above identity tells you that instead of doing that twice, once for f and once for g, you might aswell take g . f and send it out once. Also say you would for some reason know that f . g = id, the identity function, then

map id = id,

so you would not need to do anything. This might appear trivial, but if you can teach the compiler about those cases, you can do interesting stuff with it. In the case of GHC (the Glasgow Haskell Compiler), it is able to use such rules in its optimization phase, which allows people to write apparently inefficient but declarative code and let the compiler eliminate intermediate values. See for example https://hackage.haskell.org/package/repa.

Re: Why We Use OCaml

#24
post #3

What are some advantages of OCaml over Haskell?

A few mentioned in this article are true modules and polymorphic variants. Both can be partially modeled in Haskell, but it's tougher. I feel that almost nobody would disagree that these are advantages of OCaml.

Most people also suggest that strict evaluation and impurity are good traits of OCaml. This is more a contested point, however, as lazy evaluation and strict evaluation are more like duals than one being definitely better than the other. Furthermore, unrestricted side effects are a major tradeoff between convenience and safety—it's up to your use case to decide what's best.

Finally, OCaml obviously has an "O"bject system in it. My understanding is that serious OCamlers shy away from it for reasons of complexity and low value. The major stuff is provided by the module system and doesn't have anything particularly "object" about it.

Re: Why We Use OCaml

#25
> OCaml includes many features that are not available in the more mainstream programming languages ... and we believe this gives us a competitive advantage. ... The purpose of this post is to explain the benefits of OCaml and compare it to other languages. We hope to convince readers, especially other developers, to consider adopting OCaml for their projects as well.

The authors did a great job explaining the benefits of OCaml and why I as a developer should think about using the language. I actually want to play around with it now in a side project.

As a start-up manager though, I think the business case is strongly against them and don't believe there is any "competitive advantage" from using OCaml... in fact, I think the opposite. Here's why:

* There is not a strong community behind OCaml. You can't take advantage of the numerous libraries and references created by the community like you can with Ruby, Python, Javascript, Java, or any of the other mainstream languages. * OCaml is hard (and so are most functional programming languages). You will always need exceptionally talented developers to work on your code base and that will get expensive. * OCaml is not popular. You will have to pay an additional premium for OCaml developers due to the lack of experienced talent. * OCaml is a risk. If you're starting a consumer-oriented service, you need to prove there is a market for it. Will OCaml help you get to market faster? I don't know. Will Ruby-on-Rails? Yes. I'd pick RoR any day just to eliminate the risk of getting to market late.

Re: Why We Use OCaml

#26
post #11

Earlier quoted context omitted.

the "with-" pattern (originally from lisp, i believe, but ruby did a lot to bring it to the masses), where something like a filehandle manages its own lifecycle, and calls your closure in between. so rather than the C-like let f = open-file-for-writing(filename); for line in array { write-line-to-file(f, line); } close-file(f); you can do with-open-file-for-writing(filename) {|f| for line in array { write-line-to-fil…

You can also wrap the call-closure with an exception handler to make sure that 'f' is always closed when you leave with-open-file-for-writing.

right. and the beautiful thing is that once you realise that you only need to do it once, not everywhere you open, write to, and close a file.

Re: Why We Use OCaml

#27
post #20

Earlier quoted context omitted.

Haskell uses lazy evaluation by default, which makes it hard to reason about the space usage (or termination) of a particular program. OCaml on the other hand is not lazy by default (but supports it if you need it). At least that is one of the reasons why I chose to learn more OCaml than Haskell.

Why do you think termination is easier to reason about in eager languages? I think it's quite the opposite: in lazy languages functions compose, in strict ones they don't necessarily. For example, you cannot compose a "take ten values" and "square all elements" function in a strict language if the argument you apply their composition to has infinite length (e.g. is cyclic).

With a lazy language its not always obvious if a certain expression needs to be evaluated now or not. In particular I was writing some list comprehensions in Haskell, trying to solve some of the project Euler problems, and when I introduced a bug I got an infinite loop. When I fixed the bug I got the correct answer thanks to lazy evaluation, but the buggy code and the correct code looked awfully similar. Maybe it is just my inexperience with lazy languages that caused trouble (I came from C), and learning two radically new concepts: functional programming and lazy evaluation was too steep of a learning curve. Or perhaps list comprehensions aren't really supposed to be (ab)used like that. Unfortunately I don't have that code anymore, it would've made it more clear what I'm refering to...

Re: Why We Use OCaml

#28
Interesting list. I'm curious if the author has looked at Rust and how they think it stacks up. Rust is obviously still pre-1.0, and it doesn't have an identical feature list, but it seems to me to perhaps be a lot more practical for a lot of work than OCaml (largely because Rust can basically be used anywhere C++ can be, and it has good support for C FFI).

Re: Why We Use OCaml

#29
post #20

Earlier quoted context omitted.

Haskell uses lazy evaluation by default, which makes it hard to reason about the space usage (or termination) of a particular program. OCaml on the other hand is not lazy by default (but supports it if you need it). At least that is one of the reasons why I chose to learn more OCaml than Haskell.

Why do you think termination is easier to reason about in eager languages? I think it's quite the opposite: in lazy languages functions compose, in strict ones they don't necessarily. For example, you cannot compose a "take ten values" and "square all elements" function in a strict language if the argument you apply their composition to has infinite length (e.g. is cyclic).

The eager vs. lazy distinction is not relevant here. There are some programs that under eager application semantics will not terminate, but under lazy application semantics they will, and vice versa. What complicates reasoning about termination is the presence of mutation. In a lazy language, you'll never have mutation so you don't have to worry about those complications. You could have an eager language with no mutation (e.g., Elm[0]), but for the most part eager languages include some form of mutation and so you may have a harder time proving termination.

[0]: http://elm-lang.org

Re: Why We Use OCaml

#30

> OCaml includes many features that are not available in the more mainstream programming languages ... and we believe this gives us a competitive advantage. ... The purpose of this post is to explain the benefits of OCaml and compare it to other languages. We hope to convince readers, especially other developers, to consider adopting OCaml for their projects as well. The authors did a great job explaining the benefit…

But there is a strong community behind OCaml. A lot of undergraduate programs use a dialect of ML for their core classes.

While most OCaml implementations have poor standard libraries, Jane Street Capital has released several open source libraries that make it easy to implement high quality, performant applications.

Post reply on HN