Why OCaml? [video]
blogs.janestreet.com
blogs.janestreet.com
1. Financial transactions are adversarial and have heavy tails. Testing is not sufficient for Universal Guarantees, type system helps here.
2. Whole class of trivial bugs are not there because of Option (Some, None) and SystemF type system
3. Type system should be part of design process (which happens in OCaml)
4.Precise and Expressive type systems.
5. Right tool for right job, but with OCaml is in sweet-spot to write huge range of programs * little scripts * mini langs for configs * big trading system
6. Teaching/Learning: * a good percentage of traders with a month long bootcamp were able to learn with a good level of competence * MIT and Harvard students were able to achieve competence in 3-4 week internships.
7. The "python" paradox, esoteric language development helps attract high-quality/better talent
8. Tools and libraries OCaml would not be great if you have to reinvent lot of libraries ala. web development, but has good reasonable ecosystem for customized solutions (like trading systems etc.)
I think what he should have said is that financial transactions are important, and that it's expensive to screw up. This is of course as true or more for, say, NASA's flight software (which is not problem that's not adversarial in the way he means) as it is for financial trading software.
Can anyone advise on whether learning OCaml is worth it when compared to Haskell, considering I am on my way with Haskell, if only slowly? The lack of tooling on Windows (I write cross platform desktop software) and the maturity of the web frameworks (compared to Haskell) has put be off learning OCaml in the past...
If you decide you'd like to learn OCaml at a later date, you'll find it easy if you've already learnt F#.
With regards to web frameworks, you've got some good options, ranging from heavyweight frameworks like WebSharper, to lightweight frameworks like Suave.
Much of F# is cross platform too. It's been open source for a long time, and runs fine on Mono.
If you'd like some extra information about F#, I'd recommend the website 'F# for fun and profit':
* A larger choice of available libraries.
* Multicore support (OCaml is getting this soon, but it's currently single core).
* A more straightforward standard library (OCaml has three different competing standard libraries (the default one, Batteries, Core), and as far as I can see the F# one is better than all of them in terms of consistency (for example, can expect the same group of Iter, Map, Filter, etc... on all grouped data structures (Arrays, Lists, Sequences, Maps, etc...).).
* Visual Studio is a damn good IDE, and makes coding in F# even better. Perhaps something similar exists for OCaml, but I'm not aware of anything of the calibre of VS. Worth noting in both cases you don't need an IDE to be effective.
I'm not dismissing OCaml, I'd like to learn it one day too, but I hope I've helped explain why some people would want to learn F# first.
I learnt both Haskell and OCaml at the same time since their core is essentially the same. But in real world scenarios the way you think about problems is different in both languages. Haskell tends to be more abstract and favor mathematical reasoning, while OCaml is pragmatic but still very expressive.
TL;DR: It depends on your needs, if you want to learn the language and start building something quickly, OCaml is definitely a better choice. You can always come back later to Haskell, and you'll be surprised to see how similar they are.
I haven't tried Haskell apart from the very basic stuff, but if you have tried your hand at it for too long, and aren't able to make any headway, then you might as well invest time in learning OCaml/F# or Erlang or Idris or Rust or Elm instead. I hear Rust and Elm are pretty good too.
OCaml doesn't do mutli-core, I think [0], whilst Haskell has great support parallelism, concurrency [1]. Erlang, of course, is absolutely amazing at that too.
I primarily learn languages to expand my understanding of various programming constructs. It feels liberating to know that things are much easier in certain languages due to presence of certain constructs absent in other languages. For instance, OCaml is insanely good for compiler design and/or static analysis primarily due to 'variants' and the type system; Go (channels)/Erlang (actor-based programming, hot-plug code)/JVM-based languages (Clojure/Scala et al running on vastly optimized vm) for building massively concurrent systems; Ruby for being expressive, powerful, and simply awesome; JavaScript for... well... getting a taste of event-driven programming.
The challenges faced when using some of these languages are fascinating and at some point, it all comes together, as you try searching for a language in another language (like trying to mimic functional/reactive paradigms in Java 7 or below when faced with problems in handling "streaming data" for example).
In my personal experience, I have found strongly-typed languages to be easier to master and adopt in production than dynamically-typed languages.
----
[0] https://news.ycombinator.com/item?id=9582980
[1] https://ghcmutterings.wordpress.com/2009/10/06/parallelism-c...
Yes and no. Currently, OCaml has only cooperative or GIL-restricted multi-threading support, but multi-process/distributed systems work just fine (largely due to its built-in near universal serialization mechanism, which handles even closures).
It's not perfect, but it's still functional.
Example:
let f x = 2 * x + 1
let s = Marshal.to_string f [ Marshal.Closures ]
let g: (int -> int) = Marshal.from_string s 0
let () = Printf.printf "%d\n" (g 2)
Note: this may not work in the REPL and you may have to put it in a file and compile it.Note also that serialization need not be polymorphic. See e.g. the s-expression mechanism [2], which relies on metaprogramming facilities.
[1] http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.ht...
[2] https://realworldocaml.org/v1/en/html/data-serialization-wit...
utop # #require "core";;
utop # #require "core.syntax";;
utop # open Core.Std;;
utop # type foo = int * string with sexp;;
type foo = int * string
val foo_of_sexp : Sexp.t -> foo = <fun>
val sexp_of_foo : foo -> Sexp.t = <fun>
utop # sexp_of_foo (1, "foo");;
- : Sexp.t = (1 foo)I think PureScript deserves to be in this list as well :)
* no lazy evaluation => your usual sense of what's executed when isn't challenged
* imperative features included, albeit often syntactically ugly => You're not stuck because you need to compose 3 monad transformers together, you can't make sense out of the resulting types, and you have absolutely no idea of how the result might be executed anymore. Empirically, the imperative syntax is just ugly enough to make you slightly ashamed of going imperative, and spend 1/4 hour figuring out whether there's a clean and reasonably easy alternative. I don't known whether it's been done on purpose but it's well done :-)
What I miss the most from Haskell in OCaml are type classes. I bet they would have been included, if OCaml had been invented after Haskell.
From Haskell you keep a type system which helps you thinking and finds many error classes, encouragement to think functionally, godd terseness/readability compromise. If you have the time, I'd advise you to learn Haskell, in order to stretch your mind and become an excellent OCaml developer, the way learning Latin makes you a better French or Italian writer.
Re: lack of tooling: I'd be surprised if F wasn't properly supported, and if you're targeting Windows that's probably your best bet. More fundamentally, your truly valuable tooling isn't the IDE, it's the type system. I need a fancy IDE for Python or Java, not for OCaml.
There's current work under the name "modular implicits" to solve this problem, though.
F# has Suave.io which is more idiomatic along with asp.net mvc where you can fit F# into.
Freya for OWIN - RESTful development looks very nice too.
Canopy - for Web UI automation (DSL on selenium) is also an awesome tool.
I've learnt Haskell in the past and it was slow primarily because Learn You a Haskell is I think poorly written.
Read Yaron's book Real World OCaml. It's great.
Haskell with its strong syntactic support was good to learn about Monads and how to work with enforced purity.
From there, I went back to Ocaml, using both Monadic IO and Ocaml's better module/functor system.
I have heard great things about OCaml but it seems to make more sense to master one strongly typed language first, and since you already are partially up to speed on Haskell, why not stick with it for now?
Nowadays I think it's easier to do real-world stuff thanks to the amazing work by Michael Snoyman et al. on Stack, the curated package set and build tool, and other projects like Chris Allen and Julie Moronuki's haskellbook.com.
By 'practical' I mean in terms of starting out new -> launching a production-worthy business application in an efficient time window.
My problem with Haskell is that I spend all of my time trying to build perfect software instead of productively pumping out software. This is why I prefer Erlang, despite the fact Haskell is a superior language in many ways.
I'm hoping increases usage by Jane Street, Facebook and Bloomberg, along with the Unikernels/Docker tie-up will lead to increased uptake and visibility. I personally find it more suitable to systems space than Go, but with far more features to help build correct code.
(shameless plug - we're using OCaml for our microservices platform in London and are now hiring - https://www.stackhut.com/#/careers)
http://www.meetup.com/sv-ocaml/events/228367572/
As incentive I will be giving away Enter the Monad t-shirts courtesy of Jane Street, thank you yminsky!
http://softwareengineeringdaily.com/?s=janestreet
It goes into a lot more of the nuts and bolts of JaneStreet and puts the use of OCaml in a more technical context.
That's one of the things that Rust absolutely got right, helping its adoption tremendously.
Here is something that might help in the mean time, https://www.typerex.org/ocpwin.html.
Asking people who aren't invested in the slightest in your language so far to start hacking on your tooling before they can try and learn your language is an interesting onboarding strategy.
I'll leave it at that. You're simply not reasonable.
For me, any language that misses these two is not worth the effort unless you have really good reasons (i.e. every clock cycle counts in an embedded program).
Anyway, to that end, what is OCaml's packaging ecosystem like?
Composing and extending modules, passing modules as parameters to other modules and this way adapting the code to your need.
And the nice thing is that all the modules are evaluated at compile-time. Which means you don't have to sacrifice performance for modularity and still get a very flexible framework for Metaprogramming[1].
[1]: https://ocaml.org/learn/tutorials/modules.html#Functors
I've found it to be surprisingly reliable and easy to use.
OCaml modules are best of breed. Better than anything else. Nothing else even comes close.
They're weird and different from modules you'll see in other languages. Then after you get used to them you'll find those other modules are at best neutered and most likely severely broken versions of what you've come to know and love from OCaml (or any of the true MLs).
OCaml modules arise from a certain treatment of "existential types" which are, in a lot of ways, the very foundation of type abstraction. If you don't care about types practically, then you can care about them spiritually as a means of describing program interfaces. Existential types are maybe the very foundation of abstract program interfaces.
So, OCaml is at least 50% good. Opam is kind of nice, too.
def sum(list):
if list:
return list.pop() + sum(list)
return 0It is always possible to convert recursive into iterative, and most of the time doing so is trivial. I recommend doing this unless your algorithm is O(log n) or better.
def sum(li, s=0):
if len(li) == 0:
return s
else:
return sum(li[1:], li[0] + s) >>> list = [1,2,3]
>>> sum(list)/len(list)
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zeroIt wouldn't be bad if it were obvious what it did, which it isn't with the name "sum", but would be with the name 'sum_and_empty". For good measure, maybe "sum_in_linear_space_and_empty" is even better.
It's also less efficient (although in the context of a recursive sum definition that's not too relevant). Essentially what you're doing here is using the length of the list as the iteration variable — the `i' in `for (i = n-1; i >= 0; i--)'. But `pop()' probably does more than decrement the length field, I imagine it also does some memory management bookkeeping at least.
I also take issue with how `list' is mutated and accessed in the same expression. I don't really use python, but I think I recall reading that it in fact guarantees left-to-right evaluation of such expressions. Even still, it's confusing and makes programmers, especially those who write C/C++ where this is undefined behavior, uneasy.
def sum(lst):
if lst:
return lst[0] + sum(lst[1:])
return 0And even when the type system allows you to know the input variable won't be mutated (say, passing by copy in C++), you don't know what other kinds of side-effects the function may be having.