rescript-lang.org icon indicating copy to clipboard operation
rescript-lang.org copied to clipboard

Doc: add parenthesis aroud type signatures, for clarity.

Open redbar0n opened this issue 2 years ago • 5 comments

To clear up confusion around operator precedence. Coming from JS/TS, the syntax was really confusing. It looked like 'string => string = "dirname"' was a function that took in a string and in its body assigned 'dirname' to a string. Which didn't make sense (but hey, it's a new language, so maybe there is some magic there, I thought). But now, it should look more trivial and unscary. Like variable type annotations in TS. It makes it clearer that it is the ReScript variable dirname which is actually assigned the string 'dirname'.

redbar0n avatar Jan 27 '22 13:01 redbar0n

Our convention for writing docs is mostly using the formatted version of the code.

If you reformat your version, it will drop the parentheses again, so I am not sure if it's a good idea to provide an example that could potentially change on any reformat operation.

ryyppy avatar Feb 04 '22 13:02 ryyppy

I would do it, nonetheless. Because when the reformatting will drop it, then the user will already have learnt the semantics. It could alternatively be pointed out in the docs that normally the convention is to leave them out.

redbar0n avatar Feb 04 '22 14:02 redbar0n

Another thing to consider is if the code formatting convention should be a little more explicit and actually include the parentheses. It would be ever so slightly more to type, but it would be in line with the principle of favoring explicity over implicity.

redbar0n avatar Feb 04 '22 14:02 redbar0n

Another thing to consider is if the code formatting convention should be a little more explicit and actually include the parentheses

I think we are getting in bikeshed territory here, and can't really tell which version is "more readable". The external syntax is quite extra-ordinary, and something a user has to learn anyways.

From a TS perspective, adding parenthesis doesn't help much, because function type syntax is very different. For example, a let statement with explicit type annotation would look like this:

let foo: (a:string) => string = (str) => {return str}

They also don't use any wrapping parenthesis there?

It could alternatively be pointed out in the docs that normally the convention is to leave them out.

Extra sentences like this cause a lot of noise, and it would break consistency with the rest of all our docs that don't follow the () wrapping convention. Not sure if I like that too much, but I am also not sure what others say.

ryyppy avatar Feb 04 '22 16:02 ryyppy

They also don't use any wrapping parenthesis there?

True. But, imho, that reads horrible. Compare:

// (1)
let foo: (a:string) => string = (str) => { return str }

// (2)
let foo: ((a:string) => string) = (str) => { return str }

With (1) then I get confused by the operator precedence. When reading LTR it looks like let foo: (a:string) => string makes sense on its own, due to the uncanny valley to the common plain JS syntax: let foo = (thing) => thing. But when visually scanning (1) from LTR, then the = suddenly comes and invalidates that perception, and I have to start all over. So I start to just frantically scan such lines for the = at first, because it will determine how I have to interpret the rest of the line. I'm not the only one who finds this confusing. The fact that such TypeScript syntax annotations gets into the code and makes it harder to read, was one of my initial motivations for avoiding TypeScript in the first place. ReScript's full inference promises to reduce/eliminate that, so I could read the typed code as delightfully as reading dynamic code.

On having parentheses in the docs:

Extra sentences like this cause a lot of noise, and it would break consistency with the rest of all our docs that don't follow the () wrapping convention.

Then I would consistently add parentheses in the rest of the docs.

It relieves some uncertainty at a critical point of onboarding. It would be comparable to writing docs with semicolons, but the compiler stripping them out later on (you'd then get an "oh, that's nice, I don't even have to write that"). (Which would have made sense, if semicolon-free JS hadn't been so prevalent.) Because then people might have become uncertain how a compiler would divide up code without semicolons.

FWIW, a simple set of parentheses would have saved a newcomer like me a good while of confusion and googling, at least. Newcomers like me perceive bindings as one of the main barriers to adoption, and naturally look to investigate them first. So, imho, bindings shouldn't feel scary or magical.

redbar0n avatar Feb 04 '22 17:02 redbar0n

I will close this PR for now since all ReScript formatted code will omit the parenthesis, and we prefer consistency over subjectively easier to read bindings just for the docs. It's quite laborious changing all the existing instances within the docs, and then I'd need to instruct every contributor to go through this arbitrary format, while everyone will submit ReScript formatted code, which is unnecessary friction for contributors and maintainers.

If you feel strongly about the way ReScript prints type signatures, please elevate this discussion to the syntax parser / printer itself: https://github.com/rescript-lang/syntax

Given the printer gets adapted, we'll be happy to reformat all codesnippets to the new format.

ryyppy avatar Dec 07 '22 07:12 ryyppy