There’s also ReScript, which is a very similar alternate syntax which sort of split off from the ReasonML community in a confusing and complicated sequence of events which is frustrating to try to follow for someone who was just interested in the programming language and tooling: https://rescript-lang.org/blog/bucklescript-is-rebranding
One thing I don't like about this is that they've replaced:
> let x = 1 in
with
> let x = 1;
In plain OCaml you only use semicolons on lines that evaluate to unit, so they're a clear indicator that you've done something with side effects. ReasonML loses this useful visual distinction in order to look more like JavaScript.
Would be interesting to see a something that updated some ocaml quirks, but stayed true to the spirit of the syntax. Ie comments and multiply but not ;
Now though... Who cares about either of the Re* languages?
Rescript allows me to write Javascript in a sound type system, while remaining very close to how you would write code in Javascript.
Rescript to me feels like Typescript + a very prescriptive linting system which prevents a lot of problems, and since the linting system wouldn't let you do certain things, might as well get rid of them from the Type checker, this results in a much faster compiler.
[1, 2; 3, 4]
is a list of tuples, of type (int * int) list, equivalent to [(1, 2); (3, 4)] match a, b with
| 1, 2 -> x
| _ -> yI like Editions because of the cultural consequences, Rust's community assumes they can fix things and so they set out with that goal, even in cases where Editions won't quite do it - while the C++ community tends to accept the state of the language as a static fact and just "take it". But this sort of thing isn't about the cultural effects, it's a direct technical achievement.
If OCaml had Editions, it could say OK, that syntax was a bit rubbish, here's 2023 syntax which fixes two things everybody hated, get back to us over the next few years and we'll decide if there are further changes needed. Without losing all existing OCaml software or demanding expensive rewrites.
Even better, changes of the sort in Editions are mechanical. It can take a bit of creative work to do it nicely but the transformations can be automated, so people who have "old OCaml" and wish they had "new OCaml" can push a button and get on with their day. Having both this and the feature which keeps old code working unchanged, add up to an experience where the community can move forward, on syntax at least, and not be trapped with yesterday's mistakes.
It actually makes the learning easier. Now that I know the story why, I have memorized how elements are seperated in OCaml for probably the rest of my life. I just need to remember the story.
Plus not reusing symbols for multiple syntactic purposes actually fits nicely into the general Ocaml philosophy. Plus is makes my complexity-hating, minimalist heart happy.
Though I am at that point in my life where I don't really care about syntax that much to begin with. Yes syntactic complexity matters. How fast it can be parsed, how easy macros are implemented, these things can matter but the actual syntax: boring. White-space sensitive or not, curly braces or begin/end and all that stuff is so dull. I am happy with whatever.
Of course, there are few situations that require any particular language.
People are of course free to use the newest languages with the shiniest syntax (and many do), it's just that they pay the price by using untested, unproven languages when they could have been using ones which have been battle-tested in production for literally decades.
retry(Seq(1.second, 2.second, 3.second)) {
// some action that can fail
}
This still requires the braces as of right now. I think the syntax changes will just confuse more people than it helps, at least for the time being.you can also use import language.experimental.fewerBraces with nightly builds to write code like this
List(1,2,3).map: c => ...
> You can probably use () instead
I would rather not as using braces for the final argument has been the Scala idiom for a long time now.
def retry[A](backoffSeconds: Seq[Int])(action: => A): A
In this case you can't just define a 'val action = ...' because you don't want it to be run immediately, you want to run it inside the 'retry' method only. You could define it as a 'def' but then you're just introducing two different delayed evaluation concepts into this small piece of code. The cleanest way is to just directly pass in the action and Scala ensures it is delayed evaluation thanks to the CBN parameter type: retry(Seq(1, 2, 3)) {
println("Trying")
}