News for hackers. Stuff that matters.
Re:OCaml 4.03: Everything else by BWStearns on Tuesday March 01, 2016 @11:51PM (#11208150)
If I were already sold on using Haskell or OCaml for a new project, what would be the big seller for OCaml being the choice? I haven't dug into SML or OCaml and I'm not expert with Haskell yet but from looking at them they don't look substantially distant from Haskell.
Re:OCaml 4.03: Everything else by seagreen on Wednesday March 02, 2016 @12:22AM (#11208232)
I've only written Haskell, but I'll try to give a fair shakedown from my perspective:

+ OCaml is eagerly evaluated while Haskell is lazily evaluated. This makes it easier to reason about things like memory use in OCaml.

+ IO is reflected in the type signature of Haskell functions. You may find this annoying because it stinks to have to change a lot of type signatures just because, e.g., you want one of your utility functions to make a log entry when called.

On the other hand, IO is often a huge deal either semantically or from a performance perspective. For big projects having IO reflected in the type system can be a huge help.

+ The ecosystems are different. Haskell's is bigger, though I've heard the quality of OCaml libraries tends to be very high.

Re:OCaml 4.03: Everything else by mercurial on Wednesday March 02, 2016 @01:16AM (#11208388)
> IO is reflected in the type signature of Haskell functions.

What you mean is, "effects are reflected". Haskell has a monadic effect system (IO is very rough-grained part of it), which can be combined via monadic transformers.

Situations where you don't want to use OCaml:

- you need good parallelism and using multiple processes are not enough (concurrency is fine, though)

- you want a large pool of developers (also applies to Haskell, but less so)

- you like monadic effect systems

- you need a number of libraries which are not present in the OCaml ecosystem

- you want a build system that doesn't suck

- you want a good standard library

- you want typeclasses

Why you'd want to use OCaml over Haskell:

- fast compilation (especially if you compile to bytecode)

- no monadic effect system

- no awful, ridiculous record field name collisions (OCaml lets you have two distinct types with an "id" field, imagine that)

- best-in-class package manager

- faster than Haskell (I think?)

- eagerly evaluated (Haskell's informal motto is "if it compiles it works", complemented by "until you get a memory leak") and therefore makes it much easier to reason about performance

- high-quality ecosystem (though not always very well documented)

- labeled arguments (many Haskell libraries have these functions with lots of arguments which are quite confusing in the absence of labeled arguments)

- great support for Vim/Emacs (IMHO, the Haskell equivalent to Merlin/ocp-indent are not nearly as good, or at least were not as a few years ago)

- great REPL via utop (just don't use the standard one, it's terrible)

- an object system if you really need one

- functors

- pleasant "printf debugging" option, with a possibility of using a real debugger if you need

Re:OCaml 4.03: Everything else by seagreen on Wednesday March 02, 2016 @02:00PM (#11212114)
> What you mean is, "effects are reflected". Haskell has a monadic effect system (IO is very rough-grained part of it), which can be combined via monadic transformers.

Technically I'm on solid ground, IO _is_ reflected in the type system and not all effects are (memory use being the big omission, which we both mention). Saying "effects are reflected" is probably more helpful though.

> monadic transformers

There are ways combine capabilities without using monad transformers. For instance with typeclasses (if any non-haskellers are reading this here's an example: https://github.com/commercialhaskell/stack/blob/8b010060b0d7...).

> IMHO, the Haskell equivalent to Merlin/ocp-indent are not nearly as good, or at least were not as a few years ago

Editor tooling is still a big weakness of haskell:( A lot has been done on it though and progress is starting to pick up.

I agree 100% with your other points.

Re:OCaml 4.03: Everything else by fsloth on Wednesday March 02, 2016 @01:48AM (#11208454)
"- you want a build system that doesn't suck"

This is a very surprising claim. Do you have any examples how Ocaml specifically induces systems built on it to suck?

Re:OCaml 4.03: Everything else by samwgoldman on Wednesday March 02, 2016 @02:16AM (#11208525)
I don't think that's what was meant, but rather that ocamlbuild sucks. It's not the best.
Re:OCaml 4.03: Everything else by LeonidasXIV on Wednesday March 02, 2016 @04:18AM (#11208900)
The others are even worse. I tried using OMake and apart from having some neat features like watching files and automatically recompiling it was an incredible pain of setting it up - mainly due to the strange programming language used in its build files. Also, it has seen 0 updates in the last years.

It already starts with the compiler, calling them manually is quite a pain, especially if you want include any kind of library, which is why ocamlfind is such a huge win.

Re:OCaml 4.03: Everything else by nv-vn on Wednesday March 02, 2016 @10:25AM (#11210474)
Oasis isn't that bad apart from a few options that are tricky to get (or the fact that, as far as I know, there's no sane way to make it install executables to your ocamlfind directory, which makes it fairly unsuitable for PPX extensions). For the most part, it's about as easy/intuitive as using Cabal.
Re:OCaml 4.03: Everything else by LeonidasXIV on Wednesday March 02, 2016 @10:47AM (#11210628)
Yes, I am using it too, but too bad it is basically unmaintained since its author moved to work for Google. I had hoped it could generate many more files like config for Merlin or Makefiles for build systems than ocamlbuild.
Re:OCaml 4.03: Everything else by mercurial on Wednesday March 02, 2016 @01:33PM (#11211905)
Re:OCaml 4.03: Everything else by 12121091872 on Wednesday March 02, 2016 @04:05AM (#11208862)
I'm curious: The configuration file syntax is odd, but otherwise it tends to work. What are the additional problems?
Re:OCaml 4.03: Everything else by fsloth on Wednesday March 02, 2016 @04:28AM (#11208938)
Ah, yes, I parsed it wrong.
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @01:50AM (#11208461)
What if I want some hybrid? From OCaml, I want the awesome module system and strictness by default. (I'm not dismissing laziness or any other evaluation strategy - just saying strictness is a better default.) From Haskell, I want effects tracked in types, higher-kinded types and painless parallelism.
Re:OCaml 4.03: Everything else by thinkpad20 on Wednesday March 02, 2016 @02:16AM (#11208524)
There's one language I know that gives nearly all of those things, which is Ur (of the ur/web framework fame). Modules, type classes, eager evaluation, HKTs. It even adds features that aren't in either language such as first-class records and row polymorphism, type-level programming, macros and probably more. It's apparently very high performance, and even has a nice C FFI. The major downside is that it's only meant to be used for writing web servers, and for whatever reason, despite the huge number of features it supports, there seems to be little demand (or effort) to broaden its usage beyond this role. It also suffers from poor documentation, both from a language manual perspective as well as the compiler itself, which quite frankly has some of the sparsest comments I've ever seen in a code base of its size (when I was perusing before, there were practically zero comments across tens of thousands of lines of code). So yeah, probably not headed for the mainstream in its current state. Also I don't think there's much in regards to parallism in the language, although this might be able to be put in a library ¯\_(ツ)_/¯
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @02:45AM (#11208595)
I've played with Ur/Web before, and I'm very impressed with its type system, but unfortunately I don't have much use for it, because, as you mentioned, it can only be used to make Web applications, which I don't find terribly interesting. I even remember telling Adam Chlipala on Freenode at some point in time, that it would be very nice if Ur could be used for more general-purpose programming.
Re:OCaml 4.03: Everything else by thinkpad20 on Wednesday March 02, 2016 @10:50AM (#11210642)
Yes, I asked him a similar question a while back when I was investigating the language. I recall the response was something along the lines of that he wrote the language primarily for research into type-safe web APIs, and the language's features were a means to that end rather than an end in themselves. This is unfortunate because as a language it's one of the most exciting that I know of, but like you I have little interest in web apps.

In fact with its current compiler (AFAIK) it can only be run as a web server, which means it's not even possible to write a program which just writes Hello World to stdout and exits. This was frustrating enough to me that I soon gave up on the language. :(

Re:OCaml 4.03: Everything else by Tehnix on Wednesday March 02, 2016 @09:50AM (#11210202)
You can somewhat switch Haskell to being strict-by-default with the new Strict/StrictData pragma[0], which should be in GHC 8.0. There's also a great write-up of it here [1].

As someone else mentioned, Backpack is trying to "fix" the module system in Haskell[2], which should be interesting. That said, I don't have much of a problem with it, but then again I haven't seen the light of the OCaml way yet :)

[0] https://ghc.haskell.org/trac/ghc/wiki/StrictPragma

[1] http://blog.johantibell.com/2015/11/the-design-of-strict-has...

[2] http://plv.mpi-sws.org/backpack/

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @09:55AM (#11210249)
The real benefit of using a strict-by-default language is that laziness shows up in types. That is, I can check the type of a variable, and tell whether it's guaranteed to be a value (if it has type `Foo`), or it's a potentially still unforced thunk (if it has type `Lazy Foo`). For instance, the real type of lazy lists would be:

    data Front a = Nil | Cons a (Stream a)
    type Stream a = Lazy (Front a)
Haskell doesn't do this, not even with the Strict or StrictData pragmas.
Re:OCaml 4.03: Everything else by lmm on Wednesday March 02, 2016 @07:46AM (#11209568)
In order of less mainstream to more so

* Idris : modules?, strict by default, effect tracking by default, higher-kinded types, parallelism I think (at least on some platforms)

* Ceylon: modules, strictness, experimental higher-kinded types (possibly only on JS), parallelism (possibly only on Java)

* F#: modules, strict by default, parallelism

* Scala: some modularity, strict by default, higher-kinded types, parallelism

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @08:30AM (#11209753)
None of Idris, Ceylon or F# doesn't have ML-style modules:

(0) “In principle”, you could encode modules in Idris using dependent sum types, but... Good luck with that! It isn't going to be terribly usable. In general, Haskell and related languages don't consider it worth the effort to give modules proper types. I guess we can be thankful Agda's modules don't suck as badly as Haskell's - at least they can be nested.

(1) Ceylon and Scala's type systems are sophisticated enough to encode some of the use cases for modules with objects, but invariably the result is awkward. And other use cases are just impossible. For example, how should I encode an ML functor that takes as arguments two modules with shared type members? If it's possible at all, I don't even want to imagine how horrifying it will be to manually turn all the sharing by fibration into sharing by parameterization.

(2) F# doesn't allow any encoding of ML-style modules. Nothing. Nichts. Nada. It's the only so-called “ML dialect” where the most important feature from ML is completely missing.

Re:OCaml 4.03: Everything else by nv-vn on Wednesday March 02, 2016 @10:35AM (#11210542)
You could encode a module as a record with a stored type and functions for it for Idris. Then you can simply create functors as functions that take one type of record in and return another type. The syntax is ugly, but you can define macros to make it slightly more appealing. It's not an optimal approach because of namespacing of record fields, but I remember hearing that one of the next few Idris releases was going to change how record fields get namespaces.
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @10:46AM (#11210623)
ML's module language has subtyping. Given any module signature, you can obtain a supersignature by forgetting any of the following:

(0) The presence of a value component.

(1) The presence of a type component.

(2) The concrete definition of a type component, while still remembering its presence.

I am not sure you can do this in Idris, other than manually shuffling data between multiple dependent record types. Which is rather inconvenient: If you have a module with 20 components, the last thing you want to do is manually shift 15 of them to another module.

Also, unlike vanilla Haskell (no extensions) type classes, which can only have a single type parameter, ML modules can have more than one type component.

Re:OCaml 4.03: Everything else by nv-vn on Wednesday March 02, 2016 @10:29AM (#11210495)
While Idris doesn't have a module syntax, it's type system allows you to express ML modules with relative ease. It's not a great solution, but it's above Haskell in terms of this.
Re:OCaml 4.03: Everything else by cies on Wednesday March 02, 2016 @03:13AM (#11208690)
It's easy to hard to force Haskell into "not being lazy". I'd say Haskell in lazy-by-default. You could do lazy eval in non-lazy-by-default langs by using something akin to `Promisses` in JavaScript.

A better module system for Haskell is in the makings (Backpack by EZ Yang), but may or may-not be what you are looking for. To my understanding the module system of Haskell is not very limiting at all.

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @05:11AM (#11209057)
> You could do lazy eval in non-lazy-by-default langs by using something akin to `Promisses` in JavaScript.

In a strict language, a lazy thunk can be represented as a single mutable cell. In ML, thanks to type abstraction, the mutation is confined to the module that implements laziness, and, in the rest of the program, there's no way to tell that anything impure is happening.

> To my understanding the module system of Haskell is not very limiting at all.

Even Haskell's own designers admit otherwise. Haskell actually originated as an attempt to standardize a lazy, purely functional language for the research community. Modules and records weren't very high in the priority list, and it really shows. But sometimes behind a black cloud there's a silver lining, and the limitations of records inspired Haskell programmers to invent lenses, which are very, very, very awesome.

But, to this day, Haskell still doesn't have a decent alternative to ML-style modules and functors. As far as I can tell, in vanilla Haskell (no extensions), you can only encode functors on modules with a single type component. With either type families or multiparameter type classes, you can encode modules with more than one type component, but the result is very awkward.

Re:OCaml 4.03: Everything else by dbaupp on Wednesday March 02, 2016 @06:48AM (#11209368)
> In a strict language, a lazy thunk can be represented as a single mutable cell. In ML, thanks to type abstraction, the mutation is confined to the module that implements laziness, and, in the rest of the program, there's no way to tell that anything impure is happening.

Unfortunately, the general story isn't quite so nice, due to thread-safety.

Immutable data structures are great for thread-safety, as there's no problems with data races or generally invalidating things, because there's no writes... but laziness introduces secret writes, among other problems. This means a type providing laziness either can't be used across multiple threads simultaneously, or is forced to have extra overhead (e.g. atomic operations, blocking & registering for being woken up when trying to force a thunk that another thread is already forcing), and users of a library definitely need to know if a module is using mutation in the former way, and may want to know about the latter.

Of course, if shared-memory concurrency/parallelism is forgone, this isn't a problem, but that omission has its own downsides. And... I would suspect the overhead of just implementing it in a thread-safe way can be considered negligible in many cases, especially if data is guaranteed to be pointer-sized (or less).

(Concurrency/parallelism are sometimes described as "abstraction breaking" for this sort of reason.)

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @07:07AM (#11209430)
You have a point. We might actually end up with a multitude of lazy types (akin to `RefCell` vs. `Mutex` in Rust). In high-level languages like ML and Haskell, forcing all lazy data to be boxed, and atomically mutating pointers to boxed data, seems like a reasonable solution.
Re:OCaml 4.03: Everything else by tome on Wednesday March 02, 2016 @06:55AM (#11209396)
I don’t understand what you’re saying. Haskell (specifically GHC) has perfectly thread-safe secretly mutable thunks. Are you suggesting there’s a problem with doing this in a strict language? An impure language? Or something else? I don’t see why you’d say there’s a problem with a secretly mutating thunk datatype.
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @07:25AM (#11209504)
He means that updates to those thunks have to be guaranteed atomic. This can be achieved in three ways: (0) disallowing threads running in parallel, (1) using atomic operations [only works on small enough pieces of data, such as pointers to boxed data], or (2) using explicit concurrency control [locks, whatever]. We know GHC doesn't do the first, and the third would also be overkill, so it probably does the second. This also explains why unboxed data in GHC is less lazy.
Re:OCaml 4.03: Everything else by runT1ME on Wednesday March 02, 2016 @02:41AM (#11208583)
Scala seems to do all these. Unfortunately it also has a bit of a messy OO system that can make inference more painful than the aforementioned options, but life's about trade offs I suppose...
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @05:11AM (#11209056)
Scala offers awkward encodings for some of the things you can do with ML modules, but sometimes it falls short. For instance, you can't emulate datatype declarations inside signatures (as opposed to inside modules themselves). Or SML-style datatype replication. Or OCaml-style applicative functors.

Lack of global type inference is far from the only problem with Scala.

Re:OCaml 4.03: Everything else by nv-vn on Wednesday March 02, 2016 @01:36AM (#11208439)
>I've heard the quality of OCaml libraries tends to be very high. I feel the same way regarding Haskell libraries, but I do definitely think that there's more work put into documentation of OCaml libraries than their tends to be on Haskell's, which arguably makes as big a difference as the actual quality of the library.
Re:OCaml 4.03: Everything else by wyager on Wednesday March 02, 2016 @01:55AM (#11208474)
OCaml is a bit more traditional. Strict evaluation and mutability may be more friendly to programmers with an imperative background.

My general experience with OCaml hasn't been great. To be blunt, it seems sort of like a less-well-thought-out version of Haskell.

The biggest downsides that I remember were:

* IO sequencing via (;) : () -> () -> (). This is sort of a relic from before we had monads, and is relatively pretty clumsy.

* No type classes. "Generic" operators like (<) work by binary comparison (!!!). This is terrible and leads to nonsensical ordering semantics for non-trivial data. There's also no generic (+), (), etc. There are separate functions for ints and floats. Again, clumsy.

Questionable unboxing techniques. On a 64 bit processor, ints are 63 bits because ocaml has to use a bit to tag them as non-pointers. On the other hand, Haskell differentiates boxed/unboxed values statically at the kind level, so there are no weird pointer tagging tricks or related overhead.

I have limited experience with OCaml, so take this with a grain of salt. I also think OCaml has valid use cases. In Jane street's case, I can see OCaml being a better choice than Haskell for the reasons I mentioned. The people there definitely know the advantages and disadvantages of both. One of the hardest interview questions of my life was a very interesting Haskell question from Jane Street!

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @02:04AM (#11208498)
Speaking as someone who went from Haskell to ML, I don't see the loss of type classes as a terribly big deal. The implicitness of type classes is useful “in the small”, but the global benefits of a real module system in terms of type abstraction and separation of concerns outweigh the local benefits of the occasional shorter definition using type classes. In addition, ML modules have structural signatures, which makes it easier to retrofit existing modules to new hierarchies. For comparison, try making Haskell's existing Monoid class a subclass of Semigroup, without recompiling any code. :-p
Re:OCaml 4.03: Everything else by semisight on Wednesday March 02, 2016 @12:03AM (#11208188)
Can't speak for OCaml yet; I've wanted to learn for a while but decided to go with Haskell first.

On the Haskell side of things--it's biggest seller (functional purity) is also the biggest downside. To give you an idea, papers have been written about the best way to implement common data structures purely functionally.

From what I've seen, OCaml has less "abstraction overhead" because it can dip into imperative code. While Haskell is really fun, it definitely has moments where you want to beat your head against your desk.

Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @01:56AM (#11208476)
The real downside isn't purity - purity is a good thing! What Haskell suffers from is a lack of flexibility w.r.t. the evaluation strategy of pure functions. More precisely:

(0) Haskell starts with a bad default - laziness.

(1) Haskell uses special annotations to introduce strictness. The presence of these annotations isn't tracked by the type system, which reduces the usefulness of the type system as a tool for understanding your program.

(2) More sophisticated evaluation strategies (e.g., memoizing functions, which can be seen as a generalization of laziness) are difficult to achieve in Haskell, even though it's completely straightforward in ML.

Re:OCaml 4.03: Everything else by baldfat on Wednesday March 02, 2016 @09:32AM (#11210109)
I would strongly recommend looking at Racket and/or Closure. I tried the Haskell world and what a hassle to get it working on more then one machine the same way. The package management in Haskell is still more painful then other systems and is overly taxing. I work at two locations both using the same exact Dell machine with OpenSUSE and both gave problems. I also tried it on two windows machines and ugh.

OCamal also suffers from portability issues but haven't tried that hard. I love the idea of OCamal but the practical/pragmatic side of me gets rubbed the wrong way.

Personally Racket has a ton to offer and has been growing its user base a lot recently. I love this language and you can amke it whatever you want to do. Racket is a progamming language for programming languages. Clojure gives you a more pragmatic functional language and running on the jvm with a very large community.

Re:OCaml 4.03: Everything else by BWStearns on Wednesday March 02, 2016 @04:41PM (#11213257)
I'm messing with Clojure now and really enjoying it. Haskell was fun but hassle is definitely the right word for pretty much everything other than writing individual functions in it. Package management was really the thing that drove me to say "this is really cool, I'm going to come back when it's more friendly or I have more time."
Re:OCaml 4.03: Everything else by oldmanmike on Wednesday March 02, 2016 @11:13AM (#11210824)
Have you tried Stack yet?
Re:OCaml 4.03: Everything else by truncate on Wednesday March 02, 2016 @01:57AM (#11208480)
Its easy to write imperative code in OCaml. OCaml also has a class system. These two points make transition from languages such as Python, Java... easier.
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @02:43AM (#11208588)
On the contrary, I think OCaml's class system is potentially very confusing to someone coming from mainstream object-oriented languages.

Java programmers would be confused the most, because they would have to unlearn the most. In Java, a class is a type on its own right. An object of class (and, hence, type) `Foo` has a very specific data structure, even if this data structure is unknown to the user. On the other hand, in OCaml, a class is just a constructor for objects of a particular structural type. Two objects with the same structural type can have completely different underlying data structures. Making things even more confusing, inheritance doesn't entail subtyping - a class `foo` can inherit from a class `bar`, without `foo`'s type being a subtype of `bar`'s type. This happens if `bar`'s type contains negative occurences of its self-type. As a result, few intuitions about Java's class system carry over to OCaml.

Python programmers would be somewhat less surprised, but if their idea of a typed object-oriented language is “something that looks like Java”, they could encounter all the difficulties mentioned in the preceding paragraph. On the other hand, if they have no experience at all with typed languages, OCaml's class system can still be a source of pain, in that inferred object types can be utterly incomprehensible for someone not familiar with how the type checker works. By contrast, the inferred type signatures for the non-object-oriented subset of OCaml are usually very tame.

---

Sorry, e_d_g_a_r, I can't reply to you directly, because the website says I'm “submitting too fast”, but here is an example: http://pastebin.com/yUmNnFD5 . By the way, this isn't a bug in OCaml's type checker - it's the way it's supposed to work.

Re:OCaml 4.03: Everything else by e_d_g_a_r on Wednesday March 02, 2016 @02:53AM (#11208624)
Can you provide an example of " This happens if `bar`'s type contains negative occurences of its self-type"
Re:OCaml 4.03: Everything else by catnaroek on Wednesday March 02, 2016 @05:54AM (#11209176)
I inverted the roles of `foo` and `bar` with respect to my previous post. In `foo`'s definition, the self-type is `'a`. Note how `foo` has a method that takes an argument of type `'a` - a contravariant occurrence of the self-type. The consequence is that, although `bar` inherits `foo`, their associated structural types are neither a subtype of the other.

    lolcathost% ocaml
            OCaml version 4.02.3
    
    # class foo =
        object (_ : 'a)
          method test (_ : 'a) = ()
        end;;
    class foo : object ('a) method test : 'a -> unit end
    # class bar =
        object
          inherit foo
          method other = ()
        end;;
    class bar : object ('a) method other : unit method test : 'a -> unit end
    # let f = new foo;;
    val f : foo = <obj>
    # let b = new bar;;
    val b : bar = <obj>
    # f#test f;;
    - : unit = ()
    # b#test b;;
    - : unit = ()
    # f#test b;;
    Characters 7-8:
      f#test b;;
             ^
    Error: This expression has type bar but an expression was expected of type
             foo
           The second object type has no method other
    # b#test f;;
    Characters 7-8:
      b#test f;;
             ^
    Error: This expression has type foo but an expression was expected of type
             bar
           The first object type has no method other
    #
Re:OCaml 4.03: Everything else by lmm on Wednesday March 02, 2016 @08:02AM (#11209627)
I guess this means contravariance, which commonly comes from having a method that accepts an argument of the same type. Consider Comparable in Java. Maybe you want to say Animal implements Comparable<Animal>. But that would mean that any Animal is comparable to any other Animal - the compiler would let you compare a Cat to a Dog. Whereas really what you want to do is reuse the implementation of Animal, but Cats are only comparable to other Cats, and Dogs are only comparable to other Dogs - so Cat and Dog should inherit from Animal, but their types won't actually be subtypes of Animal. (There's no way to express this constraint in Java).
Re:OCaml 4.03: Everything else by technomancy on Wednesday March 02, 2016 @07:13AM (#11209458)
You can learn OCaml in a couple weeks.
Re:OCaml 4.03: Everything else by woodcut on Wednesday March 02, 2016 @08:14AM (#11209687)
Provided you had prior experience with functional languages then yes.
Re:OCaml 4.03: Everything else by nv-vn on Wednesday March 02, 2016 @11:10AM (#11210806)
Not even, it was my first functional language (other than about an hour I had spent playing with F# a few months before) and I managed to be proficient enough to read real-world code and able to write my own code in it. Overall, OCaml doesn't have any very difficult concepts that stop you from using it. Can't get currying? Just pass args explicitly, even use tuples for them. Don't get monads? Ignore Lwt/Async. Don't know about functors? Just don't write module-heavy code, etc. Overtime you can sort of start to grasp the other features, but it's not a language that takes months just to be able to use.