First: Haskell is a pure functional language, meaning that side effects, IO, keeping state, all that must be dealt with inside the type system, which while undoubtly clean and powerful, it makes it often cumbersome to do things that should be quick and simple. OCaml, on the other hand, is pragmatic. It promotes and facilitates functional programming but it also let's you easily "drop down" (so to speak) to an imperative way to write code. You have mutable variables, imperative loops, you can perform side effects anywhere, etc. As a rule of thumb, you can write fully functional code, yet sometimes when the best way to write a certain thing is imperatively, you can do so with no hassle.
Second: Haskell is lazy, and OCaml is strict. This makes it much easier to reason about performance and makes for much more predictable code. At the same time, it has first-class support for laziness when you do need it, but you have to explicitly "opt in", so to speak. Haskell also lets you force strict evaluation, but you will find it's much easier to build laziness in a strict language than the other way around.
There are also other important differences (like typeclasses vs functors) but I feel these two are the biggest ones.
So you have an implicit dependency graph of evaluation that doesn't exactly match the chain of function call. You may find that some slow code gets deferred until in the middle of some time-sensitive code, for example. You could also have something blow up that's completely unrelated to the calling code, again because of the laziness.
The opposite of lazy is strict, and Haskell does let you "opt in" to strictness when you require it.
In OCaml, you have to opt-in to lazy evaluation.
Haskell does have escape hatches with unsafePerformIO and IORef/STRef
- Laziness can be hard to reason about for newcomers who have really only had experience with strictness
- You have to learn a lot of concepts from category theory right off the bat, because it uses IO and monads. You need to know what a monad is, and almost all monad tutorials are notoriously bad at explaining what a monad is. You also don't know when to stop, when you've learned 'enough' category theory
- The community is full of clever tricks and idioms that aren't really necessary to write haskell code, but a beginner might think they need to know it. Examples: monad transformers, free monads, comonads, lenses, coroutines
- The type system is substantially more complex. Haskell has higher kinded polymorphism, rank-n-types, and a neverending set of extensions that a lot of haskellers use that'll keep you busy learning the rest of your life. Haskell code can also be very polymoprhic, and the type errors can be really confusing sometimes. Ocaml doesn't have these, but you can simulate the most important features: higher kinded polymorphism with functors, and rank-n-types with records
That's why Ocaml is easier to learn and use
Yes
> - You have to learn a lot of concepts from category theory right off the bat, because it uses IO and monads.
No - in particular, you don't have to understand monads to use the IO monad. You just have to understand the IO monad API. That's pretty similar to not having to understand how motors work in order to drive a car.
> - The community is full of clever tricks and idioms that aren't really necessary to write haskell code, but a beginner might think they need to know it.
Yes, and that's the major mistake people may do when starting Haskell. You don't need (and you probably can't) know everything you read about in order to be efficient in Haskell. Just use the simple stuff and live the happy life.
> - The type system is substantially more complex.
Yes, but it shouldn't be a problem. See point above, learn only what you want/need and live the happy life.
(also, Ocaml is an amazing language. It's fine if you enjoy it and don't enjoy Haskell)
The evidence is overwhelming, considering how many people want to learn and write Haskell and how many people struggle with it. If people could ignore all of this stuff they would've figured that out by now, but they can't ignore it to really be productive. I like Haskell a lot btw, just don't think it's very practical, and it's most important contributions to FP are already being adopted in other languages without the additional complexity
Can you recommend good ones? I've read a few and don't feel I can say what a monad is or provide an example when asked.
After you learn the math, that is, the algebraic structure that is called a monad (after, not before) you can watch a few YouTube videos and read some tutorials, until you find the wavy-handy explanation that makes more intuitive sense to you, personally.
I've heard 'Professor Frisbee's Mostly Adequate Guide to Functional Programming' is ok, but I'm looking at the section on monads and the monad laws aren't even mentioned. Which is a huge red flag for me, because without the laws it isn't a monad and you can get really strange behavior if you use it like that. I would avoid reading that book
People write these tutorials because they want to improve their portfolio to further their career, but they often don't even understand it yet -- a perfect example of a perverse incentive.
An example is the guy who wrote "You Don't Know Js" [1]. All of these are completely wrong statements:
- "But what I will say is that a monad is basically a value type."
- "A monad is a data structure. It's a type."
- "Actually, a monad isn't a single data type, it's really more like a related collection of data types. It's kind of an interface that's implemented differently depending on the needs of different values. Each implementation is a different type of monad."
- Says "methods" a bunch of times, there are no methods involved with monads in any way, it's FP
- His example in "Just a Monad" isn't a monad
- "Actually, the Maybe monad is a particular pairing of two other simpler monads: Just and Nothing"
- "Many implementations of a JavaScript Maybe monad include a check (usually in map(..)) to see if the value is null/undefined, and skipping the behavior if so" - that makes it not a monad, it violates the laws. Java's Optional type isn't a monad for similar reasons
- "But... that approach to Maybe is not a pure monad." - there's no pure/impure monads, it's either a monad or it isn't
- "The core spirit of a Monad says that it must be valid for all values and cannot do any inspection of the value, at all -- not even a null check. So those other implementations are cutting corners for the sake of convenience. It's not a huge deal," - It is a huge deal, a whole lot of abstractions are built on top of monads, if it doesn't satisfy the laws exactly then you'll be entering a world of pain you really wish you didn't
I stopped reading the rest but you get the point. You don't want to end up in a situation where you have to unlearn a bunch of this stuff. Btw the guy who wrote the Professor Frisbee book wrote the foreword in this book, so you can see why a lot of this stuff raises red flags for experienced FPers. My suggestion is to read fantasy land and ask questions on an FP channel
[1] https://github.com/getify/Functional-Light-JS/blob/master/ma...
A lot of languages support custom operators, but some really abuse the hell out of them. Googling for <%-/\-%> is very difficult.
So, first of all, I didn't know about this site, and actually it could have helped. I wish it was mentioned early enough (e.g. when first operators are introduced?) in the tutorial I was reading (Learn You Some H.? Not sure, don't remember now.)
Secondly however, I see it still doesn't mention how to spell the operator. Though I suppose in this particular case "fmap operator" could be acceptable?...
edit: Eh: see for example '>>=' and '>>'. Based on the docs, I could only try to call them both "compose", but they need some differentiation in my mind...
You can also lookup a type signature and Hoogle will give you all functions for that type signature. For example, there is only one total function `(a -> b) -> [a] -> [b]` (map) and if you search that Hoogle will show you map, accordingly: https://www.haskell.org/hoogle/?hoogle=%28a+-%3E+b%29+-%3E+%...
Honestly Hoogle for Haskell is better than Google for other languages for finding things.
EDIT: Oh, you can also click to go to the operator docs. For the case of <$>, the docs would tell you that it's an fmap synonym.
If that was your problem, it might be easiest to start by doing things in the REPL (GHCi) where you don't need to be doing I/O, and only start writing standalone Haskell programs once you're a bit more comfortable with the language. But I'm just guessing - maybe you found some other aspect to be a barrier?
People where talking about profunctor optics, monads and lenses, stuff I never heard of.
I find this harder in Haskell than other languages, because I find it harder to progress slowly. In most languages, step one for a beginner is to just hack something together, maybe even using direct for or while loops, switch statements, and the like. Then you can go back and figure out what the language gives you to express what you've done in a better way. Then you can iterate on that basic process, moving up the levels of abstraction, often finding at various points that you didn't need to write any of the code you wrote because a library exists that does the same thing if you call it in the right way. By the time you're reading about the library, you understand the contours of the problem it solves, because you've already done a worse job of solving those problems yourself. I've always had trouble injecting myself into the right point of this step-wise procedure in Haskell, and instead feeling like I need to do a bunch of research on the right ways to do things in order to make any forward progress.
I don't have a good answer, because I wouldn't want to stop building Haskell frameworks that way. But I do agree it's a problem.
The way people talk about them often feels to me like they are language constructs.
I have observed a similar effect that it seems like plenty of people come from an imperative language to OCaml and stay in OCaml longer than say, Haskell. Although I'm not sure why that is but maybe they are much like you and tried Haskell first?
I had the impression the FP hype started with Haskell and so I tried it, alter people started talking about OCaml, so I gave FP another try and liked it.
I've since gone back to Haskell and am finally enjoying it... but I credit OCaml with getting me to a place where I could enjoy Haskell the second time around.
I think it comes down to visual cues. Haskell eschews syntactic sugar and I personally find it hard to read the structure of expression. I found ML to be more explicit.
That and the community around Haskell really loves... clever... constructions. And its type system is more expressive but also complex from a mental model POV.
One of the reasons I'm interested in fb's reasonml dialect of ocaml is that I stumbled a bit going from plan ml (meta-language) to ocaml. That said, I think ocaml too is less complex than haskell. But more so ml.
I tried Haskell and PureScript and didn't understand a thing.
I tried OCaml and Reason and it felt rather easy to learn.