- My coeffects page (http://tomasp.net/coeffects) is an implementation of a simple ML-like language with coeffect type system. It was written using FunScript, which is a precursor of Fable - Fable improved many things, but this was over a year ago when it was not around yet.
- The Gamma (https://thegamma.net) is a web-based language for doing simple data science work and the compiler for that is written all in Fable. It works perfectly and integrates neatly with things like virtual-dom (source code is on GitHub https://github.com/the-gamma/thegamma-script)
For example, it takes around 20~80ms to compile a single file for BuckleScript, while Fable would talk 10x more to compile.
Its generated code is pretty but its performance is not very good, see this issue (https://github.com/fable-compiler/Fable/issues/646) "this can make a difference in speed of up to about six or seven times for tight loop code using tuples, records, lists, unions, etc.(compared with BuckleScript)"
But Fable is a nice project, JavaScript platform is large enough to have both :-)
That said, I think doing a fair comparison is going to be difficult. Although OCaml and F# share the same background, I think the OCaml and F# communities care about quite different things - and this can be seen in the difference between BuckleScript and Fable. OCaml compiler is very fast and produces efficient code and so it feels reasonable to expect the same for BuckleScript. F# is often slower, but people tend to care a lot about making interop nice. You can see this with the React bindings and Elmish tooling.
Those different goals are exactly the reason why there is room for both. I think Fable vs. BuckleScript mirror the philosophy of F# vs. OCaml with respect to .NET and native.
It's able to self-host as well. Check it out at http://fable.io/repl
F# also runs on .NET Core, which is cross-platform and comes with a good CLI. Documented, too: https://docs.microsoft.com/en-us/dotnet/articles/fsharp/tuto...
* My earliest memories of attempting to use Ocaml was pasting something directly from a beginner's tutorial into ocamli and getting a baffling error message. I think it had to do with use of double semicolons vs single semicolons. Yet that wasn't mentioned in the entire tutorial.
It also improves error messages and tooling. It has something akin to JSX built into the lang.
I do think Reason fix up a few of these ancient and partially crumbled stone walls making the ocaml landscape easier to criss-cross for a new generation of programmers.
Such as?
What's wrong with the OCaml syntax? It's much more clean than say scala's one, it's indentation insensitive, and a' list feels more relevant than the list<'T>
The one that bugs me the most is nested match expressions, which often need to be wrapped in parenthesis.
Overall, it's not a terrible syntax, but it feels a lot like someone just invented things along the way as they needed them, without a cohesive plan. Lots of pragmatic but visually ugly choices.
I also take issue with the tooling; things like error messages, or just the antiquated feel of the CLI tools. For example, having a REPL without built-in readline support (rlwrap to the rescue) in this day and age is not acceptable.
Could you show an example, I don't get it?
>The expression termination issue (";;")
Strange, I've never used ";;" in my code, only in repl.
>Operators not being overloaded is annoying, although there's a valid argument for explicitness.
Overloading is harmful. It's definitely the wrong way to do ad-hoc polymorphism, and OCaml have a polymorphic comparison operators, which brought so much headache. Type classes or modular implicits are the right way to do ad-hoc. Looking forward to see modular implicits in OCaml [1].
>For example, having a REPL without built-in readline support (rlwrap to the rescue)
What do you mean by "readline" support?
>The way argumentless functions must be declared with "function".
function is just a sugar for fun+match, what does it have to do with argumentlessness?
let foo : unit -> unit = <code>
let foo = function
| <pattern match stuff>
let foo = (function () -> <code>)
let foo = (fun () -> <code>)
I'm not an expert, but I guess this awkwardness comes from OCaml not having a dedicated function-declaration syntax; so if you do: let foo = do_stuff + 42;
...then you're obviously just defining a variable, which is evaluated right away. Which means that the only way to define a "procedure"-type function that takes zero arguments is the above.> What do you mean by "readline" support?
Readline is a library that adds a line editor to a REPL. It adds keyboard shortcuts (arrow keys etc.), history, autocompletion, and so on. Unlike almost every single REPL out there (Python, Ruby, Haskell, etc.), OCaml doesn't come with built-in support, as far as I've been able to determine. You have to run "rlwrap ocaml" to get Readline into your REPL.
let foo () = <code>There is a great advanced REPL for OCaml if you need something beyond simple stuff: