What I like about it from a learning perspective is that it makes a transition into functional programming much simpler than it would be with Haskell, where you have to completely change the way you program from the very beginning.
https://github.com/ocramz/xeno/blob/master/src/Xeno/DOM.hs
I would be interested in an analysis of this code from anyone who actually does know Haskell in case I'm misreading it.
From a nontechnical perspective, some changes in the Haskell community and ecosystem also turned me off on it starting around 2011, and I find the ocaml one to be a bit more up my alley.
Good idea to learn both, anyway :-P
Edit: compilation speed too, huge difference
begin ... end
It's ugly and stands out in its awkwardness, almost as if by design, with the compiler saying: "I will let you do this, but do think about it some more and try and come up with something more elegant."
Probably anyone who's interested here knows, but it may be appropriate to point out that you are using the word 'strict' in two different senses, first in the informal sense of being restrictive, and second in the formal sense of strict evaluation (which is why it makes sense to say that OCaml is less strict, and yet strict by default).
Disclaimer: I've written far more OCaml code than Haskell, so maybe my opinion may be biased.
[1] http://keleshev.com/composable-error-handling-in-ocaml
[2] https://victor.darvariu.me/jekyll/update/2018/06/19/ppx-tuto...
This course is for teaching students who know how to program but are new to functional paradigm. The way I understand the above is that OCaml is impure, so it's easier to have some parts in imperative style to get unstuck and move forward at first. That may reduce frustration for some students. Then over time, as the functional approach sinks in, you move to a purer style (with sometimes imperative parts, but well encapsulated). Haskell would be more like "let's jump at the deep end of the functional pool" --- which can work for some too.
I think where ReasonML/OCaml wins hands-down is its compiler. Bucklescript (and I've heard similar things about other compilers, but can't vouch for it) is lightning quick, and the community has gone leaps and bounds to make it super easy to bootstrap (including with create-react-app). GHC can do amazing things but it's not the fastest out there, and the compiler for the JS backend is abysmally slow. The code Bucklescript produces is very high quality and performant. The library ecosystem is reasonably strong and I expect (but haven't done much testing) that because of the strictness and relative simplicity of the language, library code would tend to be pretty performant and easy to use. I've never found myself in OCaml wondering what string type I should use, or attempting to parse some absurdly complex type hierarchy in a library.
I think for a frontend project, to most programmers I would recommend ReasonML. For one thing, I think even most without experience with FP would find ReasonML to be a giant improvement over Flow (which infuriates me as a type checker), and it doesn't take a ton of time to learn. ReasonReact is a pretty sweet library and I prefer it to React even setting aside language choice. Compared to Haskell, its strictness means it doesn't require a special runtime, generate slow/impenetrable code, or hog tons of resources -- all things that are issues in frontend Haskell. For those who really want to use Haskell on the frontend I'd recommend PureScript instead (also you get the bonus of a kickass record system).
For backend, I think OCaml will get you up and running sooner, but in the long run you're going to find yourself missing the type system and language features Haskell has. GHC's speed on the backend is tolerable (especially if you use nix), and I think Haskell is competitive in performance to OCaml (perhaps better with optimization). Most importantly, I think Haskell is second to none when it comes to correct implementations of business types and logic, creating powerful and reliable abstractions, and eliminating boilerplate, and I think that forms a greater advantage in backend code.
EDIT: this turned into quite the essay...
Our lucky day :)
Was there a reason you didn't go the Haskell -> Js route? Less mature but benefits of keeping the same language would have trumped the downsides? Besides compilation speed you mentioned...
I'd love to hear more on the compile to Js scene from someone experienced like you. Do you have a 'weblog'?
Edit: Have you tried Scala.js by any chance?
Let GHC do what it does best; run it on the server.
Scala.js is amazing, but it lacks lazy loading mechanism popular in TypeScript/JavaScript ecosystem -- basically you can't create a set of "tiny" modules (since the Scala compiler + standard lib are integral to each exported module), so you wind up creating a single "app.js" that contains the world (or perhaps 2 modules, one for the frontend and another for the backend).
It works but it's not ideal -- would be amazing to be able to mixin a standalone scala compiler + standard lib module that lazy loaded modules could depend on.
Pardon me for wading through your history but you seem to have used Buckle script too- and claim that it has insane compilation speed and tiny Js size - (which would translate to a one time perf gain in download/parse/exec). How is the performance difference over the course of application? Would you still use Scala.Js if you didn't use Scala on the back end?
Also, why not create multiple scala-Js projects to do what you're looking to do? You'll have to fight SBT but if you die you're a martyr and if you survive you get to fight it another day...
That won't help. Scala.js banks heavily on whole program optimization to reduce the size of emitted Javascript. Two independent Scala.js modules will contain redundant code including likely upwards of 100kb of Scala standard library (collections, futures, etc.)
There is an issue about webpack-style code splitting support for Scala.js somewhere on github, and Sebastien said it's doable with the current architecture, so we'll likely get that eventually, but it's not there yet.
I do love working with Scala.js - great language and great interop with JS.
I touched on this a bit, but the main thing is the compiler experience. I've written apps in Haskell compiled to JS before; specifically I was using Miso. While I very much enjoy writing Haskell -- that part was great -- the compiler is very slow, the binary is huge, and the generated code is completely incomprehensible. There are a few other disadvantages, such as runtime bulk, speed, laziness and the multitude of string types as well. Bucklescript is _so_ much faster than ghcjs and the tooling fits neatly into an established workflow (i.e. webpack, create-react-app etc). It compiles almost as fast as ES6, it has a built in code formatter, it supports JSX natively, etc.
That, plus I had been curious about trying OCaml for a while and I figured why not.
I think overall it needs more development, in particular in regards to UX and integrating into a modern development workflow. I'm excited to see its progress :)
Have you ever considered js_of_ocaml (https://github.com/ocsigen/js_of_ocaml)? What were your reasons for choosing ReasonML?
Could you elaborate? Ocaml has monads? Do you mean convenient do-notation for monads, or something else?
In general, I've found programming with monads in Ocaml far less pleasant than Haskell, owing to the lack of overloading. The module implementation of monads requires you to functorise your code and apply a functor for every monad you want, while in Haskell I just (>>=) and the type system figures out what I meant. The verbosity makes me want to avoid them entirely.
The only other popular functional programming language I've seen which has a proper zoo of monads is Scala, which, I think by no coincidence, supports implicits and supports higher-kinding without having to functorise.
No, OCaml really isn't a language where things move forward; quite the opposite.
Also, if you had actually written any Haskell code you'd know it's not about eliminating any side effects, it's about denoting them in the type system. Your comment reeks of someone who hasn't actually used either of these languages.