`>=` for optional arguments result in a "greater or equal" ligature
Arguments of parameterized types, e.g., ~label=option<string>=? have >= in them, and that unfortunately results in a ligature in the fonts that support them. Probably some cases when those ligatures are displayed should be considered bugs (e.g., in VS Code with the new plugin > and = are different tokens), but I don't think it possible to fix it in all the places.
So my question is: can we do something about the syntax itself? For the case of option, it would be nice to have some sugar (why do we need an explicit option?), but that wouldn't solve array<int> or Foo.Bar.t<float>. Could we have, e.g.:
let make = (~stats?=array<int>) => ...
Hmm, yes, this is an unfortunate side-effect and has been raised a couple of times. Do you have a screenshot of the ligature in VSCode? Not sure if this is gonna be easy to fix…
Sure, there you are. PragmataPro:

Iosevka:

The funny/silly thing is that the VS Code's token inspector reports different scopes for the tokens, and different colors, but in fact, only the second color is used for the ligature in Pragmata, while in Iosevka different colors are used for different parts of the ligature :thinking:
But like I said, even if the most popular editor somehow gets fixed, the problem will still remain in git diffs, git clients, and so on and so forth.
A simple solution could be having spaces around =, like they do in TypeScript: lastName = "Smith".
Then again, the TS crowd doesn't usually use something like lastName?: string = "Smith", it's either lastName?: string or lastName = "Smith" (in which case string is derived). And now that I think of it, isn't ? enough? We could have, e.g.:
~href?,
~target?: target,
~size?: size,
or
~href: ?,
~target: ?target,
~size: ?size,
Of course, you know the problem way better than I do, so I'll let you judge if it's a good idea or whether it is feasible at all.
I think adding a space is the best solution. It can probably be fixed in the vscode extension, but a space would make it work everywhere (including vim/terminal etc.).
Well, adding a space kinda makes sense semantically. There's no reason a default value (even if in the case of =? the value is an implicit None) should be closer to the type than the type is to the argument name.
I can confirm this is an issue in Jetbrains Mono (which is what I now use) and Fira Code
it would be nice to have some sugar (why do we need an explicit option?)
You need it when you annotate the implementation only, because at the implementation level the compiler treats an optional argument as an argument of type 'option of something'. But if you annotate the interface, you don't need the option type, because at the interface level (to the outside world) it's exposed an an optional argument:
module M: {
let f: (~x: string=?, unit) => string
} = {
let f = (~x=?, ()) => Belt.Option.getWithDefault(x, "")
}
because at the implementation level the compiler treats an optional argument as an argument of type 'option of something'
Thanks for the insight. Makes sense. But what if there was some sugar that would allow the compiler to threat x: string=? or ?x: string or whatever as x: option<string>=??
I mean, yeah, annotating interfaces could solve this problem today, but adding interfaces to React components just adds some noise and friction, while the benefits of data hiding, etc. are minimal, in most cases.
There are several good reasons to use interfaces even with React components, but I don't want to veer this issue too much off-topic. Ping me on the forum if you're interested, I can give you more details.
I just found this was raised in the vscode extension repo rescript-lang/rescript-vscode#35 and it's actually a vscode bug: microsoft/vscode#111945
I'm all for fixing it in VS Code, but even then it will still linger everywhere there's no tokenization, e.g., in terminals, in various git clients, etc.
The rescript-lang/syntax repo is obsolete and will be archived soon. If this issue is still relevant, please reopen in the compiler repo (https://github.com/rescript-lang/rescript-compiler) or comment here to ask for it to be moved. Thank you for your contributions.