Reason - general function syntax discussion

As this is a general discussion on Reason syntax, and whether it should be more javascript-like. I am expressing my opinion on the Reason syntax.

Telling me to use oCaml syntax instead is not the point of this discussion.

I just really don’t understand why it needs to look like Javascript. As someone trying to find a better alternative to Javascript, the syntax makes me feel like I’m moving sideways rather than forward.

I’ve seen in other posts that the Reason team has said that they are making these choices based on their target audience feedback. But where are you getting this feedback. Just from within facebook?

Edit: To be more specific about syntax, I really just distaste the use of semicolons and unnecessary parenthesis. Otherwise the syntax is quite clear and readable. I know there was feedback given from oCaml community on pain-points in the language. Was the JS community asked the same?

Also, last night trying to use Reason for the first time, I tried to use create-reason-react-app, and I could not easily get a working dev server going. I think this is a much bigger barrier to entry than syntax!

Why not? It is a general syntax discussion.

It would be great if you could post some details about this, I’m sure people would like to help you out and identify problems with the create-reason-react-app.

1 Like

I’m both hopeful and apprehensive of the new syntax.

If it looks more like Javascript, then getting programmers from ALGOL-style syntax on-board becomes easier. A lot of trade-offs would be worth it if we can finally take Typed FP to the masses.

On the other side I’ve come to like function application using spaces and ease of partial application in the current syntax.

But it is all speculation till I can work with it in a reasonably sized codebase. Has anyone here been able to try it yet? If there an easy way to refmt and back between the syntaxes, I’d love to give it a go on my project.

refmt has --print flag to determine the output format (re or ml). You can do refmt foo.ml (re is default) and refmt foo.re --print ml. I tried refmt foo.ml --print ml but it’s a bit unsatisfactory… breaks indentations and removes new lines last I used it.

Thanks Bobby. I was however looking for converting between the proposed and existing Reason syntaxes themselves. I’ll ask on Discord and update here.

It’s a discussion on Reason syntax. I thought the people behind Reason wanted to hear feedback from JS devs to try and make it more approachable.

From the original post:

But it seems like whenever someone gives their feedback they are met with a defensive answer. How is telling me to use oCaml instead supposed to make me think they are taking anyone’s feedback into consideration.

There is already an issue here: Trouble "Getting Started" with crra · Issue #47 · knowbody/crra · GitHub

The preference on syntax is all just subjective to the individual developer. So all I can do is give my feedback from my perspective while the project is still young. But as I said, it sounds like it falls on deaf ears.

To me it sounds like the same mistake is being that was made with Javascript originally. Making it appeal to Java developers at the sake of developer ergonomics. Years later we are still paying for that mistake.

1 Like

First off I’m really happy that you’re expressing your opinion about Javascript. Thanks for doing so.

You’re definitely not the only one dislike its syntax, and there are many other people who are ok with it too.

I would love to know where that data’s coming from. What are people complaining about specifically?

Yaron didn’t mean what he said in an aggressive way, i think it was more of a lighthearted comment. Reason is merely a syntax and below are all of the benefits of OCaml.

This feedback has been coming from many discussions like those with mostly people outside FB actually. Reason went open source pretty early on to open the door to that conversation.

Thanks for specifying, this is helpful. Those are have been very tough tradeoffs that we made because of parsing challenges. I could point you to issues on the Reason repository discussing the tradeoffs between consistency and ambiguity (difficulty of parsing). @jordwalke Do you know of a link to a discussion we had about this? (it might be spread among many issues now that I think about it).

Really sorry about that, I think your problem’s fixed by now but we’ll make sure to point people to tools that are working :stuck_out_tongue:

We’re all ears, I promise.

Considering you said right above that “preference on syntax is all just subjective” how can you make a case for JS making an objective mistake by looking like Java? What developer ergonomics are we sacrificing for looking like JS?
Do you have a specific language that you really look up to in terms of developer ergonomics?

Thanks for responding, I really do appreciate it. I would say that this discussion somewhat devolved quickly simply because my original post was not met with constructive answers. I know it was not aggressive, but still not helpful at all.

That is why expressed that my feedback and others fall on deaf ears.

I thought that was a generally understood consensus. Why else was coffeescript created and widely used?

So there is nothing that can be done to remove semicolons from the language? Sorry, I haven’t used oCaml, but my understanding, is that the semicolons replace “in”. But the “in” is not used on every line, while in Reason every statement ends with a semicolon. I’d rather have an occasional in than having to make sure to end every statement with a semicolon. Or am I misunderstanding? I and many others have stopped using semicolons in javascript. How do you think those of us will React when now we must go back to semicolons within Reason. Well like me, with mild frustration. (It’s really hard to avoid puns with these FB library names. :smiley: )

I’m not quite following here. But I was simply pointing out the parallel between the two projects where choices were made primarily for developer adoption rather than developer experience.

Reason has so much going for it. We can use the same language to write programs for browser, server, and native clients! What other language can do that? Oh. Well javascript can…

I want a syntax that was designed for a functional first language, not for an imperative language.

But maybe we have different goals.

Anyway, I think others with much more experience and much smarter than I have already expressed their opinions with specific issues to the new syntax. I don’t think most of their concerns have been addressed on here.

1 Like

Hello,

Just fyi the people in this forum and thread are not just Reason team members, there are diverse users of OCaml and Reason here chiming in with their (our) thoughts and advice. If you find some advice unsuitable please don’t take it as being ignored by the Reason team. They care a lot about user experience.

My personal intent here was to suggest to future readers that the existing OCaml syntax is a feasible syntax if you don’t want to deal with JavaScript syntax. You can choose to use Reason or stay with classic OCaml, with the former you will have some more input into the direction the syntax takes because the team has more flexibility; but you’ll still have to accept that the majority of users who provide feedback may want to take Reason in a more JavaScript-like direction.

With the latter you will find a more classical ML-style syntax that was designed from the ground up to emphasise partial application and clarity but has some quirks because the language designers struggled to maintain an unambiguous syntax even with new features being added over time (decades).

4 Likes

I’m actually pretty happy that Reason is going to switch to this syntax. In the current Reason syntax, there was a mix of Javascript/C-isms and improvements to the OCaml syntax that really appealed to me, such as reversing type parameter order. It made me constantly consider whether a switch to ReasonML was for me. Now that the syntax is moving all the way to Javascript-land, it has nothing with which to appeal to me, making the personal choice to stay away much easier.

6 Likes

New syntax just landed by the way https://news.ycombinator.com/item?id=15572827!

3 Likes

I personally tend to feel that the ReasonML project is a good thing for OCaml, because I do think that familiarity can strongly affect what languages programmers are willing to learn. I am happy using OCaml syntax, but when I think about recommending it to others, I feel that the traditional syntax will be an initial roadblock for some people. I also recognize that some things about traditional syntax that have puzzled me while learning (which I am still doing) might be clearer with Reason syntax. Whatever syntax I use, I appreciate all of the work that the ReasonML team and supporters have put into it.

All that said, I’m puzzled by one of the changes in the new syntax.

Old syntax:

let f x y => x + y

New syntax:

let f = (x, y) => x + y

I can understand why the parentheses-and-comma syntax for parameters makes sense–that’s what’s common in the world outside the ML/Haskell and Lisp domains. What is the purpose of the = sign, though? Shouldn’t arguments be next to the function name?

I assume that there is some reason (really, no pun) for putting a character between the function name and the arguments–something about parsing or ambiguity–but I can’t figure out what it is. Given the goal of having a syntax that is more comfortable to people used to Javascript, Java, etc., the = sign just seems weird. It adds a little wart, relative to what programmers are used to. So there must be a rationale for it.

Or here’s a thought: Is the idea that I’m supposed to read the function definition as grouped to the right, like

let f = ((x, y) => x + y)

? i.e. the => is an infix lambda (Lisp) or function (Javascript) or fun (OCaml) or fn (Clojure) or \ (Haskell)? That makes sense of the syntax, but to me it still seems like it’s going to confuse the folks that ReasonML syntax is supposed to attract. Latin-character languages read left to right. The prefix lambda operators make it clear that an anonymous function is beginning, so adding one of them at the beginning would help. Even requiring parentheses after the equals sign would help.

(The blog post introducing ReasonML 3 made a slightly disdainful comment about expected complaints about the new syntax. I know that every change in anything popular will bring complaints, and I support making improvements. Call this feedback, or call it simply a request for clarification, but it’s from a supporter of the ReasonML project. If the idea is that the ReasonML designers have no interest in what anyone else thinks, that could be a problem, but I assume that’s not the case. I am not against the BDFL-style model of language control, either–it’s a great model when it works.)

I guess it’s about uniformity, you define values and functions in the same way to emphasise that functions are also just values:

let x = 1;
let f = (x) => 1;

That said, I agree some syntax sugar for this would be great.

Hey! The biggest reason for that syntax change is exactly what you said about let f = ((x, y) => x + y).
There are two reason:

  • removes the distinction between anonymous lambda and named lambda, they’re the same syntax, which means it’s simpler
  • that’s a good way to make a Lambda in ES6 (with the right binding to this) so JS folks are familiar with it
2 Likes

ES6 let’s you make functions with just an arrow, and no function keyword? (If so, then OK, that’s good, though = (x, y) => will still look strange to e.g. a Java programmer.)

If there’s not going to be an initial function prefix, and let f = (x, y) => x + y is legal, my thought is that it should nevertheless be considered bad style to write the function on the rhs without parentheses.

Otherwise, I would think that a lot of casual readers of ReasonML code will be confused, and some who are legitimately interested will be puzzled by the weird syntax. If someone’s made a commitment to learn a language, they’ll figure it out, but before that point there may be people who won’t bother to try, given that there are so many alternatives, including whatever languages they’re using that are good enough.

let f = (x, y) => x + y still looks weird to me, even though I know how to interpret it now. I think that one of the benefits of ReasonML over OCaml is that with more required delimiters, you don’t have to add the scope in your head. (And one of the benefits of OCaml is there’s less clutter.) Without parentheses around the function, you have to do additional parsing in your head.

ES6 programmers are used to let f = (foo) => bar; by now. They’ve been doing it for a while. And OCaml programmers can, I think, understand it fairly easily too.

2 Likes

I guess my head is still in ES5. :slight_smile: I didn’t know this about ES6.

Another data point - That looks very similar to C# lambda syntax.

Since the introduction of lambda expressions in Java 8, it should actually be quite familiar. Java 8 has (a, b) -> a + b shorthand for lambdas (although assigning it to a variable would be tricky, you need to specify the Function type correctly).