
Reason: A new interface to OCaml - clayallsopp
http://facebook.github.io/reason/
======
Cyph0n
This looks very interesting. I've always had OCaml in mind but never actually
got around to using it in a project. Facebook could have done a better job
describing what exactly this is, but they do provide a good overview at the
end of the page (strangely!) [1].

In summary, Reason [2] is a new language (correction: interface to OCaml) that
shares a part of the OCaml compiler toolchain and runtime. I don't know of any
language that uses a similar approach, that is, plugging into an existing
compiler toolchain. I guess a reasonable yet inaccurate analogy would be
Reason -> OCaml is like Elixir -> Erlang or Clojure -> Java.

I hope Reason can provide OCaml with the extra push needed to bring it into
the mainstream PL space and more widespread adoption.

[1]: [http://facebook.github.io/reason/#how-reason-
works](http://facebook.github.io/reason/#how-reason-works)

[2]: [https://github.com/facebook/reason](https://github.com/facebook/reason)

~~~
Gonzih
I always liked ML family PLs, but my problem with OCaml is lack of good
stdlib. This is why I never invested a lot of time in to it sadly. Reasons
looks like a more solid out of the box ocaml distribution which I actually
like a lot. Will play with it.

~~~
jordwalke
Glad to hear it! We've also tossed around the idea of having a precompiled
standard lib come with it upon installation. We're certainly not looking to
_increase_ the number of standard libraries, when there's already so many to
choose from, but including/pre-building/curating is certainly within the
scope.

~~~
davidpelaez
This would be so interesting! I don't know any other language that has made
this before. But if the intention is to increase the reach of OCaml then if
sound like a great plan.

------
mhd
I hope this doesn't sound like trolling, but JavaScript's syntax is now a
selling point? I kinda-sorta get the reason why people want an actual
JavaScript _stack_ on the backend, but I never heard that syntax/semantics
brought people from e.g. Rails to Node.

Sure, OCaml isn't even the nicest syntax in the ML family, but I'm not sure
whether that's worth it, especially considering that almost any "X-like"
language often turns out to be an Uncanny Valley for "X" programmers -- close
enough to make some frustrating errors.

~~~
jordwalke
Jordan here (I work on Reason)

I've mentioned elsewhere that the primary goal for now was to get the tooling
automated as much as possible, so that when we receive common feedback, we can
adapt to that feedback and trivially migrate people's code forward.

I don't think JavaScript's syntax is a selling point and I am someone with a
lot of JavaScript experience. I also don't think that OCaml's syntax today is
a selling point, and I have a bit of OCaml experience. Both of these syntaxes
have evolved over time, working within that limited precious syntactic real
estate, trying so very hard to maintain compatibility with decisions made
decades ago. Reason's approach is totally different in that it knows we won't
get it right on the first shot so it puts into place the tooling for upgrading
and beautifying as we learn lessons and take feedback from the community. It
places the syntax closer to the user, even if only conceptually.

That being said, the current syntax is not intended to be a JavaScript clone
by any means. It actually started in the opposite manner - by taking the top
15 complaints about OCaml's syntax, by experienced OCaml programmers (not JS
programmers) and fixing them. There were a couple of things that didn't really
matter (such as how you express comments) that were just changed to be more
familiar because, well.. simply they don't matter, and even experienced OCaml
developers want the largest possible set of people to be able to read their
code as long as that comes with little other tradeoffs.

~~~
LeonidasXIV
I am not a fan of introducing curly brackets in a similar way I am not a fan
of curly-bracketisms in F#, it makes for a clumsy noise to a relative
distraction-free language like OCaml. It feels like trying to get Algol-family
programmers on board, whereas OCaml users have been using ( and ) as well as
begin/end since a long time.

But an advantage I see with the new comment syntax is that there are is that
there is no ambiguity what the hell (*) is. At least this.

~~~
smoothdeveloper
Curious what are the curly-bracketisms in F#?

~~~
kirse
Expressions of various kinds - Async, seq, query, etc; record type
"constructors"... that's all I can think of off the top of my head.

F# in general is a beautiful language though, I can't say I've ever thought
about the "curly bracketisms" personally because I'm too busy being excited
about how much fun it is to write over C#.

------
e_d_g_a_r
I for one welcome the syntax. I run the OCaml meetup in Silicon Valley and
syntax is definitely an issue for newcomers. This makes it easier for other
programmers to instantly just jump into OCaml/ML rather than ask about what is
`in` or what is `let foo = function`, etc etc.

EDIT: Hosting a Meetup this friday at 6pm in San Francisco about Reason and
how to instantly start using it, [http://www.meetup.com/sv-
ocaml/events/231198788/](http://www.meetup.com/sv-ocaml/events/231198788/)

~~~
weberc2
This definitely makes me feel more warmly toward OCaml. Syntax has kept me
away in the past. It's silly, but it's really hard to evaluate a language if
you can't read the examples.

~~~
tom_mellior
> It's silly, but it's really hard to evaluate a language if you can't read
> the examples.

No, this is not a silly notion. But I don't think the difference Reason makes
is as big as you think. I mean, I don't really believe that you can read this:

    
    
      let foo = if (cond) { x } else { y };
      foo + 1
    

but not this:

    
    
      let foo = if cond then x else y
      in
      foo + 1

~~~
ngrilly
The 'in' is what makes it difficult to understand for someone not familiar
with OCaml syntax and semantics. Reason makes it easier.

~~~
tom_mellior
I've heard that said, but I don't see how it's a big deal. OK, the very first
example introducing let bindings would have to come with a sentence like "the
'in' part of 'let ... in' means 'in' just like in English: 'let' the binding
be valid 'in' what follows". You don't _have_ to define a whole new syntax
where a single sentence in a language tutorial might be enough.

But I admit that I probably can't fully appreciate whether this is really
difficult for someone used to JavaScript.

~~~
jordwalke
Except when you're in the top level - in which case you don't use `in`. Oh,
and don't forget all the nuance of interleaving imperative commands. I'm an
experienced OCaml dev and this trips me up (the "ml compared" section of the
docs lists some common pitfalls that Reason resolves).

~~~
tom_mellior
Ah, but here you seem to be talking about when to _write_ 'in'. _Reading_ it
is much simpler: Just ignore that it's there, and voilà, you're set.

(I'm an experienced OCaml dev and := versus <\- trips me up from time to time
when choosing which one to write, but not when reading code.)

------
jameshart
Wonder if this project has anything to do with Eric Lippert's move to Facebook
([https://ericlippert.com/2016/02/08/facebook/](https://ericlippert.com/2016/02/08/facebook/)
\- Eric has also been producing a series of blog posts implementing a
Z-Machine interpreter in OCaml to run mini-Zork on, starting here:
[https://ericlippert.com/2016/02/01/west-of-
house/](https://ericlippert.com/2016/02/01/west-of-house/)). Eric was on the
C# compiler team at Microsoft and previously worked on JScript.

~~~
zem
damn, i recently started writing a z machine interpreter in ocaml, and now i
both really want to read those posts and really don't want to be influenced by
lippert's design decisions before i've at least gotten my own project solidly
underway.

~~~
lmm
It's always better to know about the design decisions others have taken. If
they faced the same choices you did, you can know their view on the tradeoffs
(and experiences with their choice) and choose the same way as they did or
choose differently, but either way you make your choice with a little more
knowledge. If they come up with an idea you didn't even think of, surely you
want to know about it, even if you aren't actually going to use it.

~~~
zem
if i were doing it as something intended for serious use, i'd definitely want
to see how lippert did it. but the point of doing this (other than the whole
rite-of-passage aspect of writing a z machine :)) is the challenge of
designing and implementing it from scratch, and hopefully as cleanly and
compactly as possible. if i read lippert's blog and he came up with an idea i
didn't think of _after_ i had already solved it some other, potentially worse
way, i'd be delighted to see that it could be done better. if i see his
solution to some piece that i haven't even implemented yet it would just tempt
me to simply adopt his solution.

------
civilian
I know that it's common to have namespace collisions, but their logo is _so_
similar to Reason magazine's. [https://reason.com/](https://reason.com/)

~~~
kaushiks
There's also a DAW called Reason:
[https://en.wikipedia.org/wiki/Reason_%28software%29](https://en.wikipedia.org/wiki/Reason_%28software%29)

~~~
inopinatus
... and the Neal Stephenson fan in me was just a smidgen disappointed that
this was not the introduction of a hypervelocity flechette gatling railgun.

------
avsm
There's a screencast fresh off the presses on the info page at
[https://ocaml.io/w/Blog:News/A_new_Reason_for_OCaml](https://ocaml.io/w/Blog:News/A_new_Reason_for_OCaml)

I'm finally going to switch away from my ancient nvi setup and use Atom
instead! MirageOS recently moved all our libraries over to using the new PPX
extension point mechanism in OCaml instead of the Camlp4 extensible grammar.
This means that MirageOS libraries should be compatible with Reason out of the
box -- so it'll be possible to build unikernels from a slick editor interface
quite soon hopefully!

~~~
testcross
Is nuclide good enough? A few weeks ago, a lof of merlin features were still
missing. As was the auto-indentation.

~~~
jordwalke
The Atom Reason plugin uses Nuclide's system for error rendering (in the
diagnostics bar), and type hints. But the actual logic for integrating with
Merlin has been completely rewritten in Reason itself, and compiled from
Reason into JS to run as an Atom plugin. So there are still merlin features
missing because the Atom plugin is relatively young, but if you want to help
us implement the missing features, it can be a fun way to try Reason itself
(compiling to JS).

~~~
testcross
I love the fact that ocaml compiling to js allows us to configure tools like
Atom. I will have a look at the plugin. Thanks for the informations :)

~~~
jordwalke
Yeah, if you peak inside the source code, you'll see we've implemented a
`Reason` binding to the `Atom` JS plugin API.

------
MichaelGG
I started off a bit skeptical with the <\- renaming to =. Mutability should be
rare enough that <\- makes things stand out. But apart from that I think I
rather like this syntax, on the whole. Not a fan of semicolons. It also makes
me appreciate F#'s #light syntax (now its default). Using whitespace really
clarifies stuff, and there's always in and ; for fallback.

What's OCaml's status with multithreading? Are there any proposals for more
flexible operators, so there doesn't need to be different operators for
different numerics? (F# solves this by allowing inlined functions.)

~~~
jordwalke
I suspect the syntax of `<-` (or lack thereof) will be a common topic of
discussion. Let's see how various audiences respond to this change and then
discuss if we'd like to restore `<-` for mutation. Personally, I don't use a
ton of mutations in my code so I have less at stake and if there's anything we
can do to appeal to a wider audience, I'm inclined to give it a shot.

~~~
ufo
Maybe I'm too used to Ocaml to comment but I think using `=` for mutation is a
bit misleading because it might make it appear that `x.mutablefield = bla` and
`let x = bla` are the same thing, which is the case for typical imperative
languages (but definitely not for Ocaml).

BTW, one thing that I do find awkward about Ocaml's syntax is the difference
between := and <-. Dunno if its possible to unify them in a sane manner
though.

~~~
int_19h
F# doesn't unify them, but it makes := largely redundant by letting you do
"let mutable ...", and then assign to it with "<-" \- so you simply don't need
to use refs if you just need some mutable data (you still need them if you
want to have a closure mutate something it closed over).

~~~
latkin
`ref` and `mutable` were unified in F# 4.0. You no longer need to use a `ref`
when closing over a mutable value, you can use `let mutable` in all cases and
the compiler will figure it out for you. The generated code is the same as
before, it's just that there's a unified syntax now.

There is an optional warning one can enable which emits when a `let mutable`
is converted to a `ref` behind the scenes - for those who want to by hyper-
aware of hidden allocations.

------
alex_muscar
Nice to see that OCaml is getting so much love at facebook. Unfortunately,
adding a new syntax that's almost OCaml, but not quite, doesn't seem like such
a great idea. While it might make the language accessible to more people, it
runs the risk of fragmenting the community.

I know syntax is subjective, but some of the choices seem a bit odd. For
example, declaring variants and using their constructors looks like Haskell,
but the semantics is still OCaml. In Haskell, constructors are first order so
they can be passed as functions, and partially applied. It makes sense that
their declaration and use looks like function declaration and function calls.
In OCaml they are not first class, that is, you can't pass the as arguments,
or partially apply them. That's why it makes sense for the declaration to look
like a tuple, and the use to look like a function applied to a tuple--well,
somewhat, you can still argue that it's still confusing because you might
expect to be able to apply the constructor to a tuple variable, but well, such
is life :). Unless constructors are first class in Reason--it doesn't look
like it from a quick scan through the docs--this particular syntactic
difference is of dubious value, and, worse, it can be misleading to newcomers.

Also, changing `match` to `switch` seems gratuitous as well, and it also loses
some of the meaning of the original. i.e. "I want to match this value against
this set of patterns".

Finally, I know that using `begin` and `end` for blocks is verbose and Pascal-
ish--which people seem to hate for some reason--but using { } for scopes looks
out of place, and leads to awkward cases like this:

    
    
        try { ... } { | Exn => ... };
    

I don't mean for this to sound ranty, or like I'm picking on Reason. I think
it's good that facebook is tryiog to spice things up in the OCaml community.

~~~
jordwalke
> In OCaml they are not first class, that is, you can't pass the as arguments,
> or partially apply them. That's why it makes sense for the declaration to
> look like a tuple, and the use to look like a function applied to a tuple--
> well, somewhat, you can still argue that it's still confusing because you
> might expect to be able to apply the constructor to a tuple variable, but
> well, such is life

If I understand what you're saying, you provided a reason why variant
arguments should not look like function application (because they have
different semantics than function application), and then in the same paragraph
suggested that variant arguments should have tuple syntax, while admitting
that they don't actually have tuple semantics either.

The truth is that variant arguments in `Reason` actually do _not_ have
function application syntax - note the distinguishing, leading capitalized
letter on the variant. Sure, they share the fact that arguments are specified
via a space separated list, but function application doesn't have a monopoly
on the syntactic pattern of things separated by spaces. The argument quickly
breaks down.

~~~
alex_muscar
I didn't say constructor arguments don't have tuple semantics :). In OCaml
tuples are a "unit", i.e. you can't use (,) as an operator. In that sense they
match with the constructor semantics: it needs all its arguments at once. It's
the constructors not being functions that I was complaining about. Also, I'd
say that capitalisation alone is not enough to compensate for constructors
looking like they're curried functions. But that's just a matter of taste.

------
greyhat
The slowness in Firefox appears to be solely due to this:

    
    
      @media (min-width: 1180px) {
        body:not(.no-literate) .content-root {
          background-color: #fdfcfc;
          -webkit-box-shadow: inset 780px 0 #fff, inset 781px 0 #e7e7e7, inset 790px 0 3px -10px rgba(0,0,0,0.05);
          box-shadow: inset 780px 0 #fff, inset 781px 0 #e7e7e7, inset 790px 0 3px -10px rgba(0,0,0,0.05);
        }
      }
    

Removing it in the Firefox style editor restores normal performance.

Edit: And they have commented out the box-shadow! Hah.

~~~
KaoruAoiShiho
I've been dealing with this lag in firefox for the past 6 or 7 years. It's
hilarious to me that they still haven't fixed it. Just one of the reasons I've
been extremely negative on firefox.

~~~
greyhat
This is the first time I've seen something like this. I use Firefox full time
for development and personal use and do a lot of front-end work. ¯\\_(ツ)_/¯

------
TY
Ok, it might be the end of the day for me and I'm denser than usual, but I
can't understand what is this? Ocaml to JS transpiler?

Checked this out, but the reason still eludes me:
[https://ocaml.io/w/Blog:News/A_new_Reason_for_OCaml](https://ocaml.io/w/Blog:News/A_new_Reason_for_OCaml)
(pun intended)

~~~
emerongi
I feel like FB needed it and also released it to the public, but outside of
FB, there's little Reason to use it.

~~~
zem
it's a really well-thought-out set of improvements to the ocaml syntax, done
by people who actually seem to appreciate MLish syntax for the most part
(rather than trying to get it to look more like C for its own sake, a la
mythryl)

------
chenglou
I've worked on the Atom plugin for this, itself written in Reason and compiled
to JS using js_of_ocaml:
[https://github.com/facebook/reason/tree/7f3b09a75cacf828dd6b...](https://github.com/facebook/reason/tree/7f3b09a75cacf828dd6be23c89a53a8a85d89912/editorSupport/atom-
reason).

Having worked with Reason, JavaScript, and the bridge between the two, most of
my errors seem to fall on the JavaScript side. So I guess the type system's
indeed working =).

------
hellodevnull
Site doesn't load in Firefox. Works in Chrome.

~~~
jodah
Incredible, but you are correct. Pegs 1 CPU in FF and while it loads, it
barely scrolls.

~~~
jordwalke
Pretty sure it was the gif. I've disabled it. Could you try again?

~~~
dmm
It's still hanging firefox for me. You can install firefox and try it
yourself: [https://getfirefox.com](https://getfirefox.com)

------
mseri
I love OCaml, but that's a really nice reshape of OCaml syntax! And apparently
things will be interoperable. I am really curious to see where it goes.

EDIT: and they want to use and maintain compatibility with ppx. Great news

~~~
jordwalke
Interop with OCaml is perfect and should remain so. ppx should work (modulo
issues that we're not aware of).

You can even upgrade your existing OCaml source code to be in the Reason style
by using the versatile `refmt` program that is included.

~~~
mseri
Thanks. I am definitely going to play with it!

------
haches
If you'd like to play with Reason you can do it online here:

[https://codeboard.io/projects/17520?view=2.1](https://codeboard.io/projects/17520?view=2.1)

Of course, you can also create your own Reason projects.

------
ipsum2
Looking at
[http://facebook.github.io/reason/mlCompared.html](http://facebook.github.io/reason/mlCompared.html)
it looks like regular OCaml, with a sprinkling of JS syntax.

~~~
jordwalke
For now, that's somewhat accurate. If you check out the JS comparison page,
you might say it looks like JS with OCaml's influence.

The point of the syntax toolchain is actually not to get it right on the first
try but to make something viable that is easier to learn/read, avoid bike-
shedding, and put all the right tooling in place so that we can very
seamlessly upgrade after taking in feedback. It's pretty liberating to know
you have that ability to move forward rapidly and automate all of the
upgrades.

------
Paul_S
Website fries the CPU (FF).

~~~
jordwalke
Sounds like FF can't handle gifs, but Chrome/Safari do a good job. I've
disabled the gif on the main page just to be friendly to FF while I figure out
a better approach. Thanks for the report.

~~~
Paul_S
I can run the Unreal engine, use google maps but not view your website. I'm
not convinced Firefox is at fault here.

Is there any interactive functionality that your website offers that would
justify extraordinary demands or does it simply display some text and images?

~~~
jordwalke
It turns out it was the drop shadows, and only were an issue in Firefox. I
don't know what to make of the fact that we can run Unreal but we can't render
drop shadows performantly. Maybe we should build web pages using WebGL.

~~~
technomancy
Normally the easy answer is to turn off Javascript, but in this case it makes
the whole thing completely fail to render. For a site that's just showing you
some text.

Some days you just can't win.

------
nikolay
Nice, but I always wonder why function is abbreviated as the longer unambigous
fun and not just fn?!

~~~
jordwalke
Jordan here (I work on Reason):

I agree with you but one benefit of `fun` is that it aligns better with
multiples of two spaces. It's important when lists end up wrapping:

    
    
        /* Nice multiple of two spaces */
        fun myFun
            xyz
            abc => {
          doSomeThings(xyz, abc);
        };
    
        /* yikes, only one horizontal space between
         * doSomething and abc on the line above */
        fn myFun
           xyz
           abc => {
          doSomeThings(xyz, abc);
        };
    
    

I'm obviously no stranger to bike-shedding!

~~~
nikolay
Not a good enough reason, sorry! With syntax coloring, it's less irrelevant as
well.

~~~
jordwalke
When we start talking about syntax coloring, you know we're just one step
closer to actually debating the color of a literal bike-shed!

Jokes aside, what would your highlighting do in this case?

~~~
nikolay
It would make the function name stand out from the parameters. Again, to pick
one unintuitive abbrevation, just because it's a 3-letter one like let, it's
just not serious! Make all be 3:

    
    
        type -> typ
        switch -> swi
        if -> iff
        else -> els
        in -> inn
        downto -> dow
        module -> mod
    

Call you language 3-letter reason. You see how it ridiculous it gets? You
can't make all keywords be 3-letter and if people care about alignment, they
can further align, but most don't care as much as you think!

~~~
jordwalke
It doesn't have to be three letters, keywords can be odd numbers and achieve a
similar effect - also, we likely _will_ use the `mod` keyword instead of
`module` fwiw.

~~~
nikolay
That would be another poor choice as "mod" is used as "modulo" \- there's no
need to abbreviate "long" words like "module", because they are not used so
often and bringing ugliness and confusion just to save a couple of characters
per file is not worthy!

In this case, you don't even need the "fun" keyword as syntax-wise, "=>" alone
can be used like in other languages as (parameter1, parameter2) => parameter1
+ parameter2, for example - it's obvious enough without having to prefix with
anything!

Anyway, I see that you want to be "different" in hopes to be "better", but,
indeed, you're just "weird", instead.

"+." for float addition, "^" for concatenation, etc.

"(" <val> ":" <type> ")" instead of the shorter and more readable <val> "as"
<type>.

For example, why did you choose "mutable" and not "mut"? See, your language is
full of inconsistencies, it's not well-thought, it's not intuitive! For
example, you chose "rec", which usually means "record" for "recursive"! In
your "for"-loop, you have just "to", not "upto", but then "downto"! A good
choice borrowed by some old languages would be to use the optional "by"
<step>, which defaults to +1, but in a case of a "downto", would be -1, and
thus giving you a more powerful loop!

~~~
jordwalke
You don't know of any other languages that use `mod` to represent "module"?
Say, perhaps, the one you just advocated for in another thread?

And there _are_ in fact issues with using x => y syntax for lambdas without a
leading fun/fn keyword:

let x = (this, is, a, really, long, thing ) => 10;

\- In that example it's not possible to tell if the leading ( is the start of
a pattern for the sake of lambda, or a tuple. This happens with ES6 today as
well (destructured record argument). It's not just a matter of human
readability, it's a matter of building an efficient parser.

\- The (x : y) syntax for type annotations is not new or weird to many people.
That's the syntax used by ML, OCaml, and JS (Flow).

\- We're likely going to swap some operators for string concat, so that it
would be the more common ++ operator.

\- The rest of the observations are good and we should address them soon.

~~~
nikolay
I know Rust uses "mod", but Rust is consistent and predictable - it also uses
"mut" unlike in Reason.

Regarding ":" to denote type - I like it and it's widely used across various
language, but not enforced with parentheses for typecasting.

------
akhilcacharya
Do want to learn this - does anybody know any interesting projects that can
take advantage of the OCaml ecosystem and functional aspects?

~~~
kcsrk
How about building functional operating systems and unikernels:
[https://mirage.io/](https://mirage.io/). Since Reason is fully compatible
with OCaml, you can build your own Reason unikernels on top of MirageOS
libraries. Here is a list of mirage OS pioneer projects:
[https://github.com/mirage/mirage-www/wiki/Pioneer-
Projects](https://github.com/mirage/mirage-www/wiki/Pioneer-Projects)

------
cwyers
I really wish they'd taken the pipeline (|>) operator from F#, if they were
going to rework OCaml.

~~~
thedufer
As others have noted, the pipeline operator already exists in OCaml. And even
if it didn't, you can define it pretty easily:

    
    
        let (|>) x f = f x

~~~
LeonidasXIV
Can be shortened to

    
    
        let (|>) x f = "%apply"
    

which utilises some language magic and is probably faster.

~~~
thedufer
At risk of being pedantic, that's actually shorter. It also doesn't work, at
least on the version of OCaml I'm familiar with. In order to invoke that
particular bit of "language magic", you'd have to declare it external and
explicitly give its type:

    
    
        external (|>) : 'a -> ('a -> 'b) -> 'b = "%revapply"
    

Also, `%apply` is usually the `@@` operator. For `|>`, one would expect
`%revapply`.

------
grhmc
I'm seeing "BUILD SYSTEMS RAPIDL" over here on Linux.

~~~
jordwalke
Thanks there's some strange font rendering issues. Will fix! edit: now fixed.

------
robohamburger
I took ocaml for a spin a couple months ago and compared to more recently
created languages it seems a bit crufty.

If they can simplify the build system to be on par with something like cargo
that would be swell.

Also: having rust style traits or haskell classes would be amazing. Also
macros that aren't obscure and hard to use compiler plugins please :)

Hopefully it ends up being more than just questionable sugar around ocaml and
actually adds some sorely needed language features.

~~~
nv-vn
Try out the OASIS build system. It's very similar to Cargo/Cabal (although
it's separate from the package manager) in that you basically declare what
you're working with and it does all the building for you. It's super simple to
use and is good enough for 95% of use cases. As for traits/type classes, this
is in development with the modular-implicits (experimental) fork of the
compiler. It's highly likely that some form of this will make it into the
language soon, but for now you can already start playing around with it if you
want. It's super cool because it uses the module system to express type
classes/traits rather than adding more parts to the language.

~~~
pathsjs
I tried it. I found no easy way to have dependencies isolated per project. Any
suggestions?

------
honua
What problems would be well solved by Reason/OCaml?

~~~
jordwalke
For now:

\- Teaching new programmers how to use ML, and OCaml in particular.

\- Keeping consistent formatting rules among a large team or project and
automating that within your editor.

\- Benefiting from the comprehensive pattern matching checks provided by the
OCaml compiler.

\- Benefiting from faster compile times of `ocamlc`, or faster native
execution time of `ocamlopt`.

\- Benefiting from Merlin, and the new version of Merlin with support for
Reason - I cannot overstate how important Merlin is to my daily development.

Soon:

\- Having conventions for forming namespaces within packages.

\- Making it easier to share and connect many small packages into a a larger
application, and develop those packages locally.

\- Having "just works" support for the REPL, so that it's one fast command to
start the REPL with all your dependencies loaded and autocomplete would just
work.

\- Having a "just works" debugger loader that maps all of your source files
and compiled artifacts so you can instantly start debugging your app.

~~~
e12e
Interesting project. Ever since being exposed to a bit of Standard ML (which
never had much of a "real-world" standard library, as far as I could figure
out), I always _wanted_ to like OCaml, but couldn't quite get over the odd
syntax.

It's been a while, but taking a look at this comparison of SML and OCaml
again:

[http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html](http://www.mpi-
sws.org/~rossberg/sml-vs-ocaml.html)

It feels a bit like you've landed in some strange neither-or space for Reason?
I'm not sure if it would make sense to bend OCaml into being a subset of SML
or not (I know there are some differences, just not sure how much those
require different syntax, or if they do) - but did you consider moving more
toward SML?

I can see the reasoning between going from <> to != and <\- to = (there are
more programming languages, and more programmers now, than ever before, and
whatever the merits of using = for comparison, almost all other languages in
common use now have it as an assignment operator (even if it is still a source
of bugs a la: "if(a=0) ...")).

It's exiting times with Elixir and Lisp Flavoured Erlang for Erlang, and now
Reason for OCaml (and to some extent various dialects, languages and DSLs for
Javascript, like typescript, coffee script and JSX for React).

~~~
jordwalke
> other languages in common use now have it as an assignment operator (even if
> it is still a source of bugs a la: "if(a=0) ...")).

Which with OCaml, is not an issue thanks to the decent type system!

I agree with you - there is something to be said for just not going against
the grain where you can tolerate it. I ask myself, "Are semicolons really the
hill I want to die on?".

------
bjz_
Would be nice to see modular implicits like those that are being proposed for
OCaml. It's a shame to not have any form of ad-hoc polymorphism.

~~~
jordwalke
What cheng said, but we could also make sure that the syntax for modular
implicits plays very nicely with the rest of the grammar. With Reason we can
rethink the grammar holistically instead of having to find room in it for new
features. The hard part is in the actualy implementation of Modular Implicits,
but that's currently being handled by skilled professionals and Reason will be
able to use them.

~~~
bjz_
Ah, woops - didn't realise that Reason was such a thin syntactic layer over
the semantics of OCaml. That approach makes sense then.

~~~
jordwalke
Yes, I'd describe it as being "non-invasive". It means we get the benefit of
literally every feature implemented in the core of the language (multicore,
F-lambda, modular implicits, ppx attributes), but can decouple the process of
deliberating over how this is presented to the user, and (not to beat a dead
horse) but we don't even have to worry about getting it right on the first
try! Now that I've embraced this as the new "normal" way, I couldn't imagine
having to design a syntax and stress over having to determining the exact
_permanent_ concrete syntax that needs to live _virtually forever_ without
knowing which other language features will be added later.

------
oblio
Has anyone here built something say, over 10k lines in Ocaml? How is the
development experience? IDEs, debuggers, linters, deployment, etc.

~~~
LeonidasXIV
I was working on a 30kloc compiler written in OCaml:

\- No IDE, I was happily using Vim but many of my coworkers were using Emacs.
What helped a lot was Merlin, so I could print the types of the identifiers.
This was much more useful than any REPL or IDE I have ever used.

\- Debuggers: didn't use much, ocamldebug was an okay experience at best

\- Linters: did not use. Most of the LOC were simple enough to just be
obvious.

\- Deployment: it was a Makefile which took about a minute to build the
compiler from scratch. I guess that by using a proper OCaml build system we
could've sped things up by requiring less recompilation but it was fine. In
the end a binary fell out and could be used however.

I liked the development experience a lot, once it compiled it was reasonably
clear that it would work as expected, expanding the compiler was very nice
since every time I added a new variant, the compiler complained where I need
to add code and then it just worked. We had the advantage that we already had
our own mini standard library, so most missing utility functions were already
in place when I joined.

~~~
eru
> \- Linters: did not use. Most of the LOC were simple enough to just be
> obvious.

I imagine an hlint like linter might be useful, and could give you information
about common programming patterns. (Ie hlint tells you when you could be using
foldr instead of an explicit recursion.)

------
incepted
Interesting but since they are designing a revised syntax, I wish they had got
rid of Ocaml's semi colon. These stand out in 2016.

~~~
jordwalke
See the FAQ, as this is a fairly anticipated question. There's some benefits
to having _some_ token to separate let bindings and statements, so that the
grammar is unambiguous, and it doesn't matter too much which token is used
(monkey emoji anyone?) However, I think it may be possible to eliminate
delimiters altogether eventually. Because we have the `refmt` program which
can convert and beautify between two arbitrary versions of the syntax, we'll
be able to automatically upgrade your code if we do find a way to eliminate
delimiters unambiguously. Stay tuned.

~~~
evincarofautumn
It would be good to look at the F# spec for a description of their existing
indentation & semicolon elision rules. In practice I’ve found them nice to
work with, although they sometimes require excessive indentation.

~~~
jordwalke
Thanks evincarofautumn! I'll take a look.

------
konschubert
> A new, developer experience for rapidly building fast, safe systems.

The comma placement suggests that developer is an adjective for experience.

~~~
jordwalke
Fixed, thank you @konschubert.

------
swuecho
Do it provide a usable standard lib? If so, I may try to use it in side
project.

~~~
kcsrk
There is the small standard library that ships with the compiler. And then
there are more extensive ones such as Batteries and Core. It is easy to
generate docs in Reason syntax from OCaml projects using `redoc` tool. Here is
Reason docs for:

\- OCaml compiler's stdlib:
[http://kcsrk.info/reason_stdlib_docs/index.html](http://kcsrk.info/reason_stdlib_docs/index.html)

\- Batteries:
[http://kcsrk.info/reason_batteries_docs/index.html](http://kcsrk.info/reason_batteries_docs/index.html)

------
SwellJoe
So, I know OCaml is impressively fast. And, I know OCaml is impressively terse
("concise" may be a more positive term). But, I wonder what would make one
choose OCaml (or a variant of it like this) over some of the other new or old
languages that exhibit some excellent characteristics for modern systems. In
particular, a convincing concurrency story seems mandatory. I don't know
enough to know if OCaml (or this variant) has a convincing concurrency story,
and nothing on the front page of website tells me.

So, why do I want to learn this, rather than, say, Go or Elixir?

~~~
rixed
Because ocaml type system is state of the art unlike go or elixir.

Also, what's a convincing concurrency story? Does multiprogramming count?

~~~
ngrilly
A convincing concurrency story is the one offered by the two languages you
mentioned: Go (with memory sharing, which is an advantage or a drawback
depending on your goals), and Elixir (no memory sharing between lightweight
processes).

A version of OCaml offering a similar "concurrency story" would have a lot of
appeal.

~~~
rixed
Those are just techniques, other techniques achieve the same goal, such as
multiprogramming, which I think is better that's why I asked.

But if you want POSIX threads and lightweight threads for the sake of it, then
there are several lightweight threads libraries for ocaml (LWT being the most
common one). POSIX threads you have to do from C though.

------
ubertaco
As excited as I was to see a big new thing in OCaml-land, I have to say my
excitement died down as I read on.

I don't really see most of the changes as improvements.

Having a different, explicitly-noticeable syntax for mutable updates is nice,
because it calls out mutability (which should be used sparingly).

I don't see extra braces as necessarily an improvement, given that OCaml's
local scopes are already quite unambiguous thanks to "let ... in". On that
note, Removing "in" and just going with semicolons removes another "smelly-
code-callout" by making it less obvious what's imperative and what's
functional.

I actually _don 't_ like ambiguity between type annotation and value
assignment in my records. It's clear in current OCaml that {a: int} is a type
declaration and {a = 1} is a value declaration/assignment. Moving to colons-
for-record-values is at best a bikesheddy, backwards-incompatible change for
change's sake, and at worst a breaking-change way of code less clear.

Speaking of making code less clear, how is "int list list" not clear? It's an
int-list list. As in, a list of int-lists. So of course it should parse as
"(int list) list". Why change to backwards annotations? Just to prevent
existing code from working as-is, and making people used to reading ML spend
extra brain cycles on remembering that your types read the opposite way?

And they make a _huge_ deal out of their type for tuples being "(a, b)"
instead of "(a * b)". Yeah, okay, I get it. It's not _that_ big a deal, since
people are used to reading product types as, well, products.

The other thing that seems weird to me is the need to change to a "fat arrow"
instead of a "skinny arrow", again for no real reason. In fact, it just makes
it more likely that you'll confuse it with a comparison operator. Nobody tries
to type ">-", but people try to type ">=" all the time. You're just switching
for the sake of switching, and it's not an improvement.

Their example code of their replacement for match...with is especially
egregious. If you showed me the OCaml snippet and the Reason snippet
unlabelled, I would think that the OCaml snippet is the new-and-improved
version, since it's much more compact, much less noisy, and reads more like
what it's trying to do ("match my_variable with either SomeValue x or
SomeOtherValue y").

Another thing they make a lot of noise about is requiring fewer parens in some
places. But then, they also require more parens in other places. So...okay? I
guess? Not really a win.

And why rename equality operators? Are you really going to tell me that people
_prefer_ that their languages have "==="?

~~~
wtetzner
Yeah, I kinda feel like this whole project is pointless. As many warts as
OCaml's syntax has, for the most part I actually like it.

It seems like Reason is solving a non-problem. When I first went to the
webpage, and saw "Build Systems Rapidly", I thought maybe it was a new build
system for OCaml. I was hoping it would be a Cargo-style build system/package
manager for OCaml.

~~~
jordwalke
"As many warts as OCaml's syntax has, for the most part I actually like it."

This is for those people who do not like OCaml because of those warts. If you
are one who is already sold on OCaml, it's very easy to forget how many there
really are.

Regarding "Build Systems Rapidly": Please hang in there and stay tuned. The
syntax is there to help people learn ML rapidly. The Merlin integration and
syntax formatting tooling is there to help people become productive rapidly
inside their editors. Next, we have specified a workflow for actually building
systems rapidly (as in compiling large projects with namespacing rules).

Instead of our previous approach where we just drop a more polished project
with many of the goals accomplished, this kind of project benefits from
expertise that is distributed across the entire industry and for that, it's
better to be open earlier. I hope you can appreciate and encourage this kind
of openness.

~~~
eru
I'm looking forward to having an OCaml version that looks more like Haskell.
:)

~~~
jordwalke
To start, we have "fixed" type parameter application syntax. (Most people see
this as a win and now matches Haskell IIRC). Some have requested ability for
type annotation ayntax to be above the value it annotates.

~~~
eru
By the way, do you even need to work towards _one_ better syntax? Seems like
you should be able to support mostly whatever syntax the user wants? (Within
reason.)

------
xvilka
It would be nice if they'll make it work on Windows platforms. There is
already an issue for that[1]. It also depends from the Windows support in
OCaml itself and opam[2].

[1]
[https://github.com/facebook/reason/issues/470](https://github.com/facebook/reason/issues/470)

[2]
[https://github.com/ocaml/opam/issues/2191](https://github.com/ocaml/opam/issues/2191)

~~~
xvilka
There is some work is done for opam
[https://github.com/dra27/opam/commits/windows](https://github.com/dra27/opam/commits/windows)

------
johnhenry
Wondering how, or even if, this compares to elm? [http://elm-
lang.org/](http://elm-lang.org/)

------
yegle
This is the new low of search engine unfriendly :-(

~~~
eru
Just look for "Reason OCaml".

------
mark_l_watson
Reason looks interesting. I have had a 5 year run of alternating between
really liking Haskell, and sometime thinking that my own development process
was too slow using Haskell. I am putting Reason on my try-it list.

Documentation suggestion: add examples for string manipulation.

------
cm3
I miss dead code elimination the most, especially when building code that uses
Core.

~~~
mseri
It's coming with flambda. Am I wrong?

~~~
cm3
Not that I'm aware of.

Edit: flambda has been released in 4.03 and I'm using it but utop is 17MB, so
I doubt proper dead code elimination is part of flambda.

~~~
mseri
Sorry, what I meant is that I remember having read somewhere that dead code
elimination, or some sort of, will be one of the optimization coming in the
future due to the introduction of flambda. When I go back home I will try to
find a reference, I might recall wrongly

~~~
cm3
You're probably right that it was mentioned on Jane Street's blog that flambda
will enable such optimizations. I recall one of the ocamlc devs saying that
real dead code elimination is planned but not available yet.

------
breatheoften
Is Facebook using mirage or similar ocaml unikernel tool chain? Is part of the
goal of reason to make a more approachable syntax available for authoring code
that will run inside next-generation containers?

~~~
nv-vn
From what I can gather, it should work independently from the Mirage
toolchain, but will remain compatible with all current OCaml tooling, so using
Mirage tools will work as well.

------
partiallypro
Does anyone Else's Firefox absolutely slow to a crawl on this page?

Edit: just doesn't load at all on Edge. Does load in Chrome/Opera and
surprisingly IE 12 but doesn't load the logo's font.

------
zem
i noticed this in the examples:

    
    
        | List p (List p2 (List p3 rest)) => false  /* 3+ */
    

has the regular list destructuring in pattern match syntax been removed?
that's pretty sad, if so - lists _are_ the default data structure in ocaml,
and it's worth retaining some special syntax for cons especially in pattern
matches.

~~~
ufo
For me the odd bit is that they called the constructor List instead of Cons.

~~~
jordwalke
Thanks for the feedback. We can change it to `Cons`, but I was assuming that
anyone who knew what `Cons` was, would know what `List` meant, but not
everyone who understood what `List` meant, would know/recall what `Cons`
meant.

------
stuartaxelowen
Can we please keep using parens for function invocation? Leaving them out
hurts readability.

~~~
bjz_
The difference between curried langs like OCaml and Haskell and languages like
Ruby and Elixir are that the leaving out of parens actually _means_ something,
ie. all functions take one argument. If you wanted parens whilst maintaining
the same semantics, you would end up having to do write: `add(2)(3)`

~~~
stuartaxelowen
Indeed, but leaving out the parens makes more work for humans. What does `a b
c` mean? `a(b)(c)`? `a(b(c))`? If the only thing that is gained by leaving out
the parens is brevity, I don't think its worth it.

~~~
evincarofautumn
It’s no different than having to know the associativity of an operator. Does
“a - b - c” mean “(a - b) - c” or “a - (b - c)”? The former, for no reason
other than a long history of convention. Same goes for function application.
And you could make the same argument about languages that require parentheses
for function calls: what does “a(b)(c)” mean? “(a(b))(c)” or “a((b)(c))”?

What’s gained is that the syntax mirrors the semantics. If you have a function
“f : int -> bool -> int”, then “f 5” has type “bool -> int” and “f 5 true” has
type “int”. It’s not like in Forth where you can’t tell from the syntax how
many arguments a function takes.

That said, I do think right-associative function application may be more
intuitive—I like having it in Perl, for example.

~~~
eru
You get right-associative function application (in Haskell) by putting $ in
between your functions.

(And if you are using composition instead, it associates in both directions.)

------
elcapitan
Is there an overview in which regard this differs from "classical" Ocaml?

------
querulous
if this had come out five years ago i'd probably be all over it, but i think
i'd rather just use rust at this point. different syntax but better safety and
it's not like the ocaml ecosystem has a lot to offer

------
andrew_wc_brown
Everything reads like double talk. Not sure what I would want to use this for.

------
intrasight
Pretty disappointed that they'd release something that butchers Firefox.

------
molotok
Fry Firefox RAPID.

------
aerovistae
BUILD SYSTEMS RAPID

------
fixxer
Why rtop?

~~~
thedufer
It's just OCaml's repl with the parser replaced. OCaml's repl is called utop.
It stands for Universal TOPlevel.

------
ulber
This page is completely unusable due to lag. From the other comments it seems
this is FF specific. One would think FB would have the resources to test new
pages at least on common browsers before publishing.

Edit: The fix came quickly though.

~~~
jordwalke
Thanks, we're looking into how to fix the perf in FF. Meanwhile, it works on
my tiny mobile cell phone.

~~~
saticmotion
Disabling the box shadow on .content-root fixes the performance bug (FF46.0).

~~~
jordwalke
We just discovered the same by disabling the media query which handles the
shadow. Thank you very much for investigating.

~~~
SilasX
Seems to work fine on FF (46) now, thanks.

------
zump
Facebook just won't let OCaml die.

~~~
fixxer
Neither will Jane Street.

~~~
zump
What is Jane Street's yearly profit?

~~~
fixxer
You tell me.

------
carapace
Another site that is useless with JS disabled. Nice work.

------
ClosureChain
I wonder if the people at Propellerheads will sue Facebook for using the name
of their software
[https://www.propellerheads.se/reason](https://www.propellerheads.se/reason)

------
devit
It seems to me that Rust would be pretty much strictly better than this.

In particular Rust has similar syntax, seems to have all Reason's features
plus the linear types and regions/borrowing that allow memory and concurrency
safety while still being able to mutate memory and not being forced to use GC.

They are aware of Rust since they cite it in their page, so I wonder why they
decided to create this instead of using Rust.

It would be nice if they explained this in the FAQ.

I guess it might be useful if you have an OCaml codebase to interface with but
don't already know OCaml, but given the relative obscurity of OCaml that seems
a pretty narrow use (and also Facebook isn't known to make extensive use of
it, afaik).

~~~
andrewchambers
Both garbage collected languages and rust offer memory safety, rust just
trades better performance for a more complicated borrow system.

Use rust when you need the performance. Use a GC'd language like reason when
you want less things to reason about.

~~~
wtetzner
> rust just trades better performance for a more complicated borrow system.

I would say Rust trades more predictable performance for a more complicated
borrow system.

~~~
chrismorgan
Rust’s borrow system is actually not the key part; if it were just that, then
yes, it would be purely a complication performance would be the only important
part about it when comparing it with garbage collection. No: the key part is
the ownership model, that an object is owned in precisely one location.
Borrowing sits on top of and fits into that, not the other way round.

The ownership model is the part that I don't myself yearning for in other
languages I work in such as Python and JavaScript.

