Hacker News new | comments | ask | show | jobs | submit login
Reason: A new interface to OCaml (facebook.github.io)
603 points by clayallsopp on May 17, 2016 | hide | past | web | favorite | 287 comments

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

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

Thanks for the thoughts. I would definitely not call Reason a new language, but rather a new interface to an existing language that is already great. Not all languages make it easy to provide such an interface, but OCaml did, and the timing made sense.

I like the syntax cleanups. What's the advantage of using the existing OCaml toolchain over using an LLVM backend? Expediency and interop with Facebook's other OCaml libraries? From what I have read, the OCaml compiler only does basic optimizations and the runtime has poor multithreading support.

Facebook has many projects that are already written in OCaml, and Reason provides a path forward for seamlessly, and incrementally moving projects over to the new syntax/style.

Feel free to take a look at some Reason in the wild, used inside of the Infer project at Facebook:


Apart from that, although syntax is the "user interface" to a language, and user interfaces are very important, there really is so much to a language beyond the syntax. I see Reason's syntax as a way to make the really good parts of OCaml exposed to a wider audience, while making existing OCaml developers more productive in their editors.

Some things you might appreciate about OCaml's core language (which Reason provides a new interface to):

- World class pattern matching.

- Excellent type inference.

- Bare metal compilation without a VM, but alternatively the ability to compile into JS.

- Great predictable performance, even without a ton of performance optimizations (because the runtime is so simple), but take a look at 4.03 which includes a new F-lambda optimization pass. Even without F-lambda the perf is competitive with other systems languages, and F-lambda buys you another good 10-30% reduction in CPU or so.

- Multicore support is progressing. Here's a PR from today to add multicore support to the native backend (https://github.com/ocamllabs/ocaml-multicore/pull/47)

Cool. Thanks for the background. I'll take a look at the Infer code. :)

It's important to realise that an LLVM backend is not a panacea -- the OCaml native code generator is highly optimised for the calling conventions and OCaml GC already. LLVM's IR doesn't quite track values at the same abstraction level as OCaml so some features such as exceptions become very expensive if mapped onto LLVM without changes to the IR.

Another major recent advance in OCaml 4.03 (released last month) is the flambda middle layer -- basically an epic inlining and allocation elision pass. See https://blogs.janestreet.com/flambda/ for more on it, but it's already giving 10-20% performance improvement on real world code.

Multicore is also coming soon -- see https://ocaml.io/w/Multicore for a summary of activity there.

LLVM may be better at generating opcodes, but a lot of things are happening between syntax and opcodes, especially type inference, type checking and inlining (including cross module and now cross functors).

Actually, if ocaml "optimized" compiler have shown anything, it's that micro optimizing instructions and register allocation is not as important as once believed. Indeed, for long amongst "sophisticated languages" Ocaml "optimized compiler" was renowned at the same time for the speed of generated code and for the simplicity of its code generation pass, lacking many advanced features found in ghc for instance.

reason : ocaml :: lfe : erlang might be an apter comparison. it adds a new syntax parser, but not a new language. from their docs:

> The OCaml compiler is organized into several stages, which are exposed as libraries. Reason replaces part of the compiler toolchain with a completely new syntax parser that is more approachable, while still fully compatible with the rest of the compiler. Reason also implements a new source printer which integrates into your IDE and the new custom REPL.

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.

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.

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.

Have you ever tried the Jane Street standard libraries?

yeah, but it's not the standard library. this is my problem. what about compatibility with the other tools/libs?

I think for the most part the community is standardizing on using Core as though it was the standard. As an example: Real World OCaml, for instance, assumes Core is installed (note: I believe it is coauthored by one of the Jane Street employees).

A similar language might be Haxe, which can target C++, Java, C#, PHP, JavaScript, Python, Lua, and Neko languages, and make use of the tooling/build chain for those languages.

So you can abstract the syntax from the runtime, but the semantics are often different per target - e.g. accessing the filesystem in Node.js will be different to C++, due to the non-blocking I/O mechanism.

As an aside, the Haxe compiler is written in OCaml. I think there'd be a delicious juxtaposition if it was re-written in Reason. Writing Reason to generate OCaml to create Haxe to generate Java to generate bytecode...

> As an aside, the Haxe compiler is written in OCaml. I think there'd be a delicious juxtaposition if it was re-written in Reason. Writing Reason to generate OCaml to create Haxe to generate Java to generate bytecode...

It should be easy to convert the Haxe compiler into Reason with refmt. Maybe unless if it's using camlp4 syntax extension... But I guess you could add a camlp4 pass before running refmt.

Ah, I forgot about Haxe. Someone correct me if I'm wrong, but isn't Haxe essentially a transpiler with its own stdlib? I think Reason is different is that it explicitly integrates into the OCaml build process.

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.

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.

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.

Curious what are the curly-bracketisms in F#?

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#.

The top complain I've heard about syntax is that too many people focus on it ;-p

Maybe that's because it's the first and only thing one can see and therefore it's cheap to have an opinion? Or is it because too many professionals are used to languages which are little more than a syntax on top of a toy evaluator?

When I first try ocaml long ago, I though overcoming the syntax would be a huge challenge (especially since I was using lisp at the time). Surprisingly, I got used to it after the first night, and even started to like it. Just a single data point of course, but it seems useful to warn new programmers that your first impressions on the syntax of a language are just that. Also, your estimation of the time that would be required to learn a new language based on how easily you can parse the syntax at first sight is completely wrong. It took me longer to understand some error messages that the compiler threw at me long after I though I could "speak ocaml" than to build an initial understanding of the syntax (roughly 2 hours).

All of the above, of course, is just a disgruntled and grumpy way to say: despite we all know we don't care about the syntax of any language once we know it, it's still an overly important factor to drive a language adoption (or, in the case of ocaml, disaffection). Therefore, let's hope this new "revised syntax" will help many more programmers discover more sophisticated languages than the industry standards!

> I don't think JavaScript's syntax is a selling point

Under "Why OCaml?" on the Reason page, it states, "OCaml has a very mature (and still growing) ecosystem for targeting browser and JavaScript environments with a focus on language interoperability and integration with existing JavaScript code," and "Reason‘s non-invasive approach to the OCaml compiler allows Reason code to take advantage of all of the existing OCaml compiler optimizations/backends such as ... and even JavaScript compilation."

It seems like what's being said is that one of the main goals for Reason is to integrate with JavaScript, and it would seem to make sense instead of changing between language syntaxes, you'd want more in common between them, so it makes sense why they are similar. I'm confused as to why you seem to be trying to distance Reason and OCaml from JavaScript, when it definitely seems like the similarity with and integration with JavaScript would be a driving factor in Reason's development now, even if maybe it wasn't in the beginning.

Reason seems really cool, btw.

I personally think that JavaScript is one of the most meaningful and important languages that exists today. This needn't imply that JavaScript's syntax, or its semantics are to be emulated (though we're seeing a bunch of welcome improvements in recent versions of JS). The thing I like most about JavaScript is that it allows anyone, anywhere to easily deploy and share code with anyone anywhere.

So I hope this helps explains why many people feel that compiling to JS is important, even if the syntax/semantics of JS are not equally sought after by those same people.

At the same time, we can't overlook that JavaScript has become one of the most popular languages today. If that were the case thirty years ago, I'm sure the syntax for the ML family would have taken that into account somehow, at least to convey the parts of the two languages that actually are similar - even if only for things as simple as comments. So at least in this V0.0.1 of Reason, some of the things that just don't matter tend to look like things that are familiar to a larger set of people.

I think you've picked up on what looks like an inconsistency in messaging so thanks for pointing it out. I can't speak for everyone else who works on Reason, but I see the two major components (compiling to, and resembling) JavaScript to be largely independent. We can want to compile to JavaScript for totally different reasons than we want some pieces of the grammar to resemble JavaScript and I believe that is the case here. The pieces that currently resemble JavaScript are that way simply because those pieces don't matter too much and why not just be familiar? There are certain syntax features of JS that members of the JS community would tell you were mistakes, and we're not looking to recreate them just for the sake of being like JS.

It's great to learn about the process. Sounds amazing. I agree that JS syntax is not a selling point, from what I read the approachability of a wider audience is. However I agree that care should be taken not to fall to easily in stripping away most of the ML interesting things and end up with everything looking the same. Go, Rust, Swift, JS it's all about the same. For different languages their "user interface" is extremely similar. I think that with your proposals you have shown a great suitability to discover the balance between being different and being accesible, I don't think they have to be opposed as many language designers seem to be convinced.

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/

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.

People like to say that syntax doesn't matter and over the long term maybe it doesn't but anything that detracts from learning a language does matter and sometimes syntax is exactly that needless barrier.

IMHO `let in` has more to do with semantics than syntax. `let a = b;` doesn’t mean the same as `let a = b in …`. It’s like `def` vs. `let` in Clojure. Outside of this specific case I agree OCaml doesn’t have an easy syntax; I have to re-learn some parts of it every time I need to write in that language.

> 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
  foo + 1

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

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.

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).

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.)

Of course, once you know what 'in' means, it's easy to read, but you have to learn it, and get used to it. I've teached programming to students in finance, and this learnt me how much I underestimated the impact small things like that can have on the learning curve (and the motivation).

Yeah, I don't know what doesn't read easily about "let x = 3 in x - 1" -- it is straightforward: x is equal to 3 in the expression "x - 1".

Hmm, the new if syntax really feels like a step backwards. (But I can see why they chose it: the C-like syntax here isn't too much of a burden, and is familiar to a lot of programmers already.)

Will you stream or record the session?

Probably not, sorry.

I presume your phrasing is referencing http://knowyourmeme.com/memes/i-for-one-welcome-our-new-inse... except that you actually do welcome the syntax, right?

Wonder if this project has anything to do with Eric Lippert's move to 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/). Eric was on the C# compiler team at Microsoft and previously worked on JScript.

His moving to facebook explains why he didn't do the zork interpreter in F#.

Not sure why the Reason syntax isn't more like F# though.

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.

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.

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.

I know that it's common to have namespace collisions, but their logo is so similar to Reason magazine's. https://reason.com/

There's also a DAW called Reason: https://en.wikipedia.org/wiki/Reason_%28software%29

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

Similar to the point that I'm sure it is a subconscious plagiarism. In other words, the person who created the logo had seen Reason magazine's and unintentionally channeled it when creating the new one.

You mean 'un-reasonably' similar ?

It's also about as similar to the common representation of ruthenium on the periodic table.

There's a screencast fresh off the presses on the info page at 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!

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

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).

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 :)

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

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.)

Multicore support is progressing nicely. Only earlier today I made a PR for adding nativecode compilation for multicore: https://github.com/ocamllabs/ocaml-multicore/pull/47. A lot more information about the multicore OCaml project can be found here: https://ocaml.io/w/Multicore

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.

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.

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).

`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.

If there is one single thing from F# I would like to have in OCaml it is the whitespace syntax. I can write nice OCaml, but I often need to exploit corners in the grammar and cheating around with precedence and @@ to get my code to not be full of clumsy parens, anonymous functions etc.

I loved so much significant whitespaces when I discovered them in Python! Since then, a few years have passed, and I've come to the conclusion that significant whitespaces are a mistake: they make automatic code formatting difficult or impossible (gofmt, refmt, etc.), they make sharing code snippets by chat or email error prone, they make automated code generation error prone too. Please don't add them.

This is not correct. You can still auto format just fine. It won't change indentation obviously, since that would change the meaning of the program. What problems do you have in mind?

I'm also very skeptical that they make sharing code difficult. Any indentation issues will be readily apparent in a compiled language.[1] Plus I doubt this is a serious issue in the first place. And certainly it doesn't outweigh the massive gain in the main activity: reading and writing code.

1: Sure there's always a few counter examples. But in general this isn't an issue. Just like inferring function types. It's rare to have a true mistake end up changing things but simultaneously compile fine.

You're right about auto-formatting being possible with significant whitespaces... but:

When you copy-paste a block of code in another block of code, with significant whitespace you have to correctly reindenting everything very carefully, while with explicit blocks you can let an automatic formatter do the work.

When you copy-paste a block of code in chat/email/comment, it is sometimes difficult to preserve significant whitespaces. For example, I've seen a lot of blog comments "eat" the white spaces at the beginning of each line (example: https://unspecified.wordpress.com/2011/10/18/why-pythons-whi...)

It can be difficult to fix code incorrectly mixing spaces and tabs (especially for beginners).

Rob Pike wrote on this topic:

> Some observers objected to Go's C-like block structure with braces, preferring the use of spaces for indentation, in the style of Python or Haskell. However, we have had extensive experience tracking down build and test failures caused by cross-language builds where a Python snippet embedded in another language, for instance through a SWIG invocation, is subtly and invisibly broken by a change in the indentation of the surrounding code. Our position is therefore that, although spaces for indentation is nice for small programs, it doesn't scale well, and the bigger and more heterogeneous the code base, the more trouble it can cause. It is better to forgo convenience for safety and dependability, so Go has brace-bounded blocks.

Source: https://talks.golang.org/2012/splash.article

Without examples it's hard to say. Python isn't static, and it's type system isn't as capable as MLs.

I'm entirely unconcerned about random formatting systems destroying whitespace. Some eat angle brackets. Maybe I'm not copy+pasting enough. I find "for beginners" to not be useful as a measure of anything - anything can be said to be confusing for beginners. But I can see how people might come to a different opinion.

Haskell doesn't nearly has as much of a problem with copy-and-pasting from websites as Python have. (But in Haskell the significant indentation is much more optional.)

> When you copy-paste a block of code in another block of code, with significant whitespace you have to correctly reindenting everything very carefully, while with explicit blocks you can let an automatic formatter do the work.

I've heard this argument a lot, but how often does it happen to copy paste extensive parts from web sites? Some short bits, yes, but longer parts with blocks? Almost never, since I always have to rewrite them to fit my variable names etc, so might as well make sure the formatting is right.

I've been programming in Python for about 10 years and still love it.

Yeah, I feel the same way about <-, but it's interesting to know that Elm did the same thing, so it isn't a random change.

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.

> 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.

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.

> 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.

But I guess in Reason they could be first class. All it takes is to interpret an occurrence of an n-ary constructor


  (fun a1 ... an => Foo a1 ... an)

Yes, that is do-able, if they want to make this change.

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.

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.

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. ¯\_(ツ)_/¯

Not a great solution but I got a bookmarklet that removed any fancy css rule (shadow, alpha, ...).

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 (pun intended)

Think of Reason like "CoffeeScript for OCaml"—a nicer surface syntax for the same underlying language. With CoffeeScript, it's a nicer JS. With Reason, it's a nicer OCaml.

OCaml can also be compiled to JavaScript, like pretty much every language can these days.

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

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)

It plugs into the existing OCaml compiler toolchain [1], which is quite smart. So it's basically an interface to OCaml that shares the stability and features of the OCaml compiler and runtime.

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

I would rather say it's OCaml with a different syntax than a 'standalone language'.

Thought it was mostly summed up in the first paragraph... "Reason is a new approachable interface to the OCaml language, with the long-term goal of improving the developer experience by providing a functional syntax and toolchain for writing, building and sharing code quickly and easily."

I think the question was, what's the relationship between Reason and JavaScript?

It is a new syntax for OCaml but OCaml can compile to JS really well so Reason can too.

OCaml can be compiled to JavaScript. Therefore, so can Reason.

Looks like their plan is to reuse the ocaml compiler backends that output javascript; but it doesn't sound like they're doing anything explicit to promote Reason -> Javascript compilation.

Well, if you ignore the red button that runs you through comparisons of different Javascript syntax to the equivalent Reason syntax, then sure, they aren't doing anything explicit...

That's a comparison of syntax, which has nothing to do with compiling to Javascript.

Whether they have an intermediate step that is OCaml or not is irrelevant. Most compilers have one of more intermediate representations between source and executable. I think providing a syntax comparison to Javascript right next to a syntax comparison to OCaml is a clear indication that they are marketing to Javascript programmers, and the only reason for that is if they intend thelanguage as a replacement or supplement to Javascript.

That may or may not seem relevant to you based on ciniglio comment, but I think it's on point if you follow the thread from it's source down.

In 2016, "marketing to JavaScript programmers" is pretty much the same thing as "marketing to programmers". Providing context that the vast majority of programmers will understand is helpful regardless of the compilation strategy. That being said, of course people want a language that can compile to JavaScript, and it's worth mentioning the expanding set of options for doing so. But the syntax comparison really would be worthwhile even if it weren't the case, if only to provide context to what is likely the largest developer community that exists today.

The same as the relationship between OCaml and JavaScript, plus some braces.

I think it's a new frontend for the OCaml compiler. Allowing reuse of the backend / similar semantics, but with different syntax.

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....

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 =).

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

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

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

It's still hanging firefox for me. You can install firefox and try it yourself: https://getfirefox.com

Looks like something related to repaints caused by a jquery scroll event http://i.imgur.com/mFL9ZYN.jpg

It's not the gifs it's the scroll event listener causing a redraw every time.

Could you possibly submit the gif in a bug to Mozilla? They’d want to fix that…

1 CPU still pegged on firefox.

But otherwise, Reason looks very cool. A nice mashup of technologies to create something that certainly looks more useful than the status quo. I hope this takes off, but I think the biggest challenge nowadays, even for good technology, is finding an audience amidst a plethora of choices. Technology, as always, is a popularity contest.

Just tried, it's still not working well.

edit: Fixed now.

Thanks for the (many) reports! It's been fixed for a while. No excuse for poor performance!

Nope. Site still completely saturates a core, but only during scroll, not during idle.

No problem here on FF 48.0a2

Having the same issue, it loads very weirdly.

I was able to load it on Firefox 46.0.1 but it pegged a core completely.

I was curious why it doesn't scroll. Barely works but gives a CPU spike and just jumps around between pages...

Chrome and Safari both worked for me. Common reports about Firefox, so I disabled the gif. Can you let me know if it works now?

Why does a text document describing a programming environment need to hijack scrolling at all?

it loads but the scrolling is at like 2 fps. thank god for reader view. ff46

Completely unuseable for me as well.

Same thing happened for the react native unveiling, Facebook dev don't seem to care about Firefox.

Here too, completley killed Firefox (FF46 on Win10) with an unresponsive browser window.

Works fine here (FF46 on Ubuntu without any special add-ons).

It loads for me but it's so slow it's unusable.

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

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.

Thanks. I am definitely going to play with it!

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


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

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

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.

Website fries the CPU (FF).

Same here. What a piece of shit the internet has become.

Man, I wish someone would release tools for building fast, safe systems so we could follow that model!

glad i'm not the only one thinking this.

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.

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?

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.

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.

He has an onscroll event that is causing a ton of redraws.

It also doesn't even open in Edge.

No problems here - Chrome, Mac.

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

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
        abc => {
      doSomeThings(xyz, abc);

    /* yikes, only one horizontal space between
     * doSomething and abc on the line above */
    fn myFun
       abc => {
      doSomeThings(xyz, abc);

I'm obviously no stranger to bike-shedding!

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

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?

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!

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.

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!

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.

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.

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

How about building functional operating systems and unikernels: 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

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

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

Can be shortened to

    let (|>) x f = "%apply"
which utilises some language magic and is probably faster.

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`.

The pipe operator's still there.

I've never written OCaml, just SML and F#, but I thought that OCaml didn't have the |> operator.

OCaml, like SML, have the syntax for defining their own operators. |> is defined, to my knowledge, both in the standard prelude and in core.

Since Ocaml 4 if I remember correctly

4.01 to be exact. Along with @@, which is kinda comparable to $ in Haskell.

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

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

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.

I agree on the build system and macros. As for traits/type classes, there's work being done on implicit modules to fill that role. [1]

[1] http://www.lpw25.net/ml2014.pdf

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.

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

What problems would be well solved by Reason/OCaml?

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.


- 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.

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:


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).

> 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?".

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.

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.

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

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.

Reason will have modular implicit. It's really just OCaml under the hood.

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

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.

> - 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.)

I haven't done anything ≥10k lines yet, but I do have a few projects between 1k and 5k lines that I've been working on and I've easily written 50k+ lines of OCaml in the past year. The development experience I've had is probably the best I've dealt with so far. There isn't a ton of infrastructure around the language, but everything that exists feels very high quality.There's no standard IDE really (although I did recently find OCamlEditor, which seems very nice and even runs on Windows!), but Merlin basically turns any compatible text editor into a full-fledged OCaml IDE (with features like quick-checking code, auto completion, linting, and automatic indentation/formatting). Honestly, debugging isn't something I've had to think of very often. The type system does a really good job of rejecting buggy programs, so whenever I write code it usually works as intended immediately (or I've made a small mistake that I'll notice pretty quickly).

There is no IDE. But you can use merlin, which is amazing. Debuggers are not very developed, neither are linters.

For me, the development experience is pretty good. But it takes some time to get used to this new world. Conventions are not the same.

Well, we have an excellent linter, it's called "The OCaml type checker". It even has customizable warnings for your coding style. ;)

I know the Haxe compiler is written in Ocaml, and that's a decent size open source project. I believe Facebook uses it for a number of their programming language related tools too. It seems to gave a sweet spot for writing language parsers and compilers.

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.

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.

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.

Thanks evincarofautumn! I'll take a look.

Why? It has more benefits that downsides.

I think the only complains we can do at the moment are the switch from '<-' to '=' for mutable records and from '->' to '=>' for functions. But we will see how it will evolve

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

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

Fixed, thank you @konschubert.

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

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

- Batteries: http://kcsrk.info/reason_batteries_docs/index.html

Batteries Included is another solution (which is more compatible with the thin included standard library): http://ocaml-batteries-team.github.io/batteries-included/hdo...

Jane Street's Core is probably what you're looking for.

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?

For concurrency I found this green thread implementation which uses libev or select for io:


Also, for parallelism, elsewhere in this thread this link was shared:


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

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

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.

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.

The ML family of languages have https://en.m.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_... which provide many benefits

Because Elixir doesn't target native code and Go type system is not much better than a safe C with interfaces and packages as addition.

OCaml is a much more modern language than Go.

Yes and no, depending on which aspect of the language you consider:

- Type system -> OCaml is more modern (despite being designed before Go)

- Concurrency, parallelism, garbage collector, tooling -> Go is more modern (Reason is improving the tooling with refmt for example; work is ongoing on parallelism)

Interesting. What's fancy about the Go garbage collector?

As far as I know, there is nothing fancy about it, except for the fact that a lot of work has been put into Go's garbage collector, especially in versions 1.5 and 1.6, with people working full-time on it.

Go easily achieves GC latencies well below 10 ms, even for programs using a large heap, without having to manually "tune" the GC.



Go 1.5 concurrent garbage collector pacing, https://docs.google.com/document/d/1wmjrocXIWTr1JxU-3EQBI6BK...

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 "==="?

> 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?

This is actually an improvement in my opinion. Reusing the syntax for function application in type application makes the language more uniform. It's even necessary with dependent types.

A lot of the better changes reminds me of the revised syntax http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html

(why would you introduce the ternary operator when if-then-else is so much nicer to read?!)

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.

"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.

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

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.

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.)

> 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.

Wild guess: Due to moving to a brace syntax for blocks and '=' for assignments, they needed to move to colons to disambiguate something that already used braces and '='. That is, something like this:

  let x = ref 0;
  type record = { x: int };
  if (cond) { x = 1 } else { x = 2 }
might read either as creating a new record value or as writing throught the reference. (Again, just a guess.)

EDIT: All that said, I agree with you. OCaml's syntax is meh, but moving it closer to brace languages makes it worse, not better. Some of these changes actually move closer to Haskell (constructors without parens, yay!), and those are the changes I like.

It's important to use an incompatible dialect of every language and toolchain that your company uses. If you just use the vanilla project, the company might be tempted to adopt outside open source projects rather than reinventing the wheel in-house. This would be a terrible thing because it Wasn't Invented Here (tm). Also, new college graduates might not be appropriately awed by the pile of High Tech Stuff you show them on day 1, if just anyone else could use it outside the company.

For example, when you're using C++, be sure to rewrite the string and stream classes (like Folly does). This will ensure that you can't contribute anything back to the community, and they can't contribute to you. Be sure to use all the funny C++ features that haven't quite been standardized or supported correctly yet.

For OCaml, it's harder, since it doesn't have as many poorly designed and duplicative features. But with enough effort, you too can fix the "problem" of your code being similar to other people's code.

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

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

There is some work is done for opam https://github.com/dra27/opam/commits/windows

Wondering how, or even if, this compares to elm? http://elm-lang.org/

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

Just look for "Reason OCaml".

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.

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

It's coming with flambda. Am I wrong?

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.

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

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.

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?

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.

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.

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.

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

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.

No, the sugar's still there.

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

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)`

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.

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.

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.)

But it’s not `a b c`. Rather it’s something like `verb noun noun`. Which is much less ambiguous.

In a language with currying semantics [(((a(b))(c))(d)] the only logical explicit syntax sugar would be LISP-like, so (v n n), (v (v2 n)). That’s imo way worse — you end up with lots of useless junk)))))))) in anything non-trivial.

What about `verb noun verb noun`? Is the second verb a parameter or is it being invoked on the noun?

It's a parameter.

The rule isn't complicated - functions are left-associative. That's all you have to remember.

It would be `(a(b))(c)`. Interestingly, you're already leaving out parens for brevity.

More work for humans used to something else.

At this point it's worth reminding that ML syntax was originally designed to make programs more palatable to maths students...

Making function invocations with (foo x y) instead of foo(x,y) is pretty common in functional languages like Ocaml, LISP and Haskell.

When so much of your code is function calls, all those commas and parenthesis start cluttering things.

Please take a look at the FAQ which describes the best way to move forward with evolving the syntax. It helps to know your personal technical background and where you're coming from, as well. I do like your idea, but you can currently use parens - it's just that they aren't required by the parser when the argument is clearly one item (like an integer constant etc). Then at that point, it's just a matter of configuring the source formatter to always include them.

My background is in Python, Scala, Java, C, and Ruby. My reaction is based on the monstrous DSLs I've seen in Scala and Ruby (because the language lets them), where the clever syntax actually hid the important features of the interface. Every time you get to "wait what is this actually doing" and you have to learn another tiny language instead of just writing functions that return a `Future[HttpResponse]` and be done with it.

Don't let my complains about syntax deter you, this looks like a very exciting project!

That's a valid complaint for new untested syntax that people came up with yesterday.

The paren-less function invocation has been around and tried for ages in the ML-family.

(The main downside is that variadic functions are hard to express this way. For fixed arity this is a clear win, also makes partial application nicer to read.)

Thanks stuartaxelowen, the feedback is actually really valuable one way or another.

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

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

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

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

Fry Firefox RAPID.


Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact