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.
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:
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.
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).
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).
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.)
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!
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).
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.
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.
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)
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."
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...
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.
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.
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.
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.
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.
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.
Thanks for finding that out. We (Firefox) fixed a box shadow performance bug [1] in Firefox 47, which will be released on June 7th. It looks like this site is hitting that perf bug.
Completed nuked FF for me and for what its worth it doesn't even load in Edge. Just throws up a "This page is having a problem loading" page. Works fine in IE 11...
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.
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.
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.
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.
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 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.
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).
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.
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
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.
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.
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.
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.)
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.
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'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. ¯\_(ツ)_/¯
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
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.
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.
293 comments
[ 3.1 ms ] story [ 274 ms ] threadEDIT: 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/
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:
but not this:But I admit that I probably can't fully appreciate whether this is really difficult for someone used to JavaScript.
(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.)
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!
edit: Fixed now.
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.
Is there any interactive functionality that your website offers that would justify extraordinary demands or does it simply display some text and images?
Some days you just can't win.
Checked this out, but the reason still eludes me: https://ocaml.io/w/Blog:News/A_new_Reason_for_OCaml (pun intended)
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.
[1]: http://facebook.github.io/reason/#how-reason-works
OCaml can also be compiled to JavaScript, like pretty much every language can these days.
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.
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.
Edit: The fix came quickly though.
Disclaimer: This post was written in Chrome.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1250947
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
Feel free to take a look at some Reason in the wild, used inside of the Infer project at Facebook:
https://github.com/facebook/infer/tree/master/infer/src/IR
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)
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.
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.
> 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.
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...
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.
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
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.
The rule isn't complicated - functions are left-associative. That's all you have to remember.
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.
(And if you are using composition instead, it associates in both directions.)
At this point it's worth reminding that ML syntax was originally designed to make programs more palatable to maths students...
Don't let my complains about syntax deter you, this looks like a very exciting project!
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.)
When so much of your code is function calls, all those commas and parenthesis start cluttering things.
Not sure why the Reason syntax isn't more like F# though.
EDIT: and they want to use and maintain compatibility with ppx. Great news
You can even upgrade your existing OCaml source code to be in the Reason style by using the versatile `refmt` program that is included.
Edit: And they have commented out the box-shadow! Hah.
The comma placement suggests that developer is an adjective for experience.