syntax icon indicating copy to clipboard operation
syntax copied to clipboard

`>=` for optional arguments result in a "greater or equal" ligature

Open hoichi opened this issue 4 years ago • 11 comments

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

hoichi avatar Jan 02 '21 12:01 hoichi

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…

IwanKaramazow avatar Jan 02 '21 12:01 IwanKaramazow

Sure, there you are. PragmataPro: image

Iosevka: image

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.

hoichi avatar Jan 02 '21 21:01 hoichi

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.

hoichi avatar Jan 02 '21 22:01 hoichi

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

jfrolich avatar Jan 04 '21 03:01 jfrolich

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.

hoichi avatar Jan 04 '21 12:01 hoichi

I can confirm this is an issue in Jetbrains Mono (which is what I now use) and Fira Code

TheSpyder avatar Feb 17 '21 20:02 TheSpyder

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, "")
}

yawaramin avatar Feb 26 '21 06:02 yawaramin

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.

hoichi avatar Feb 26 '21 09:02 hoichi

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.

yawaramin avatar Feb 26 '21 16:02 yawaramin

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

TheSpyder avatar Mar 05 '21 01:03 TheSpyder

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.

hoichi avatar Mar 08 '21 15:03 hoichi

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.

stale[bot] avatar May 28 '23 23:05 stale[bot]