-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Propose. * Little grammar error. * Semi-colons and language standardized indentations. * n) -> n.
- Loading branch information
1 parent
85b4d9a
commit 2b28353
Showing
1 changed file
with
82 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Leading `|` and `&` in types | ||
|
||
## Summary | ||
|
||
Allow the use of `|` and `&` without any types preceding them. | ||
|
||
## Motivation | ||
|
||
Occasionally, you will have many different types in a union or intersection type that exceeds a reasonable line limit and end up formatting it to avoid horizontal scrolling. Using the English alphabet as an example: | ||
|
||
```lua | ||
type EnglishAlphabet = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | ||
``` | ||
|
||
Or you might just format it for readability: | ||
|
||
```lua | ||
type EnglishAlphabet = never | ||
| "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | ||
| "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | ||
| "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | ||
| "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | ||
``` | ||
|
||
Currently, there are two solutions to effect it: | ||
|
||
1. Moving `=` to the next line | ||
2. Keep `=` on the line and add `never` if using `|`, or `unknown` if using `&` | ||
|
||
```lua | ||
-- 1) union: | ||
type Result<T, E> | ||
= { tag: "ok", value: T } | ||
| { tag: "err", error: E } | ||
|
||
-- 2) union: | ||
type Result<T, E> = never | ||
| { tag: "ok", value: T } | ||
| { tag: "err", error: E } | ||
|
||
-- 1) intersection: | ||
type MyOverloadedFunction | ||
= ((string) -> number) | ||
& ((number) -> string) | ||
|
||
-- 2) intersection: | ||
type MyOverloadedFunction = unknown | ||
& ((string) -> number) | ||
& ((number) -> string) | ||
``` | ||
|
||
OCaml and TypeScript supports this same syntax: | ||
|
||
```ocaml | ||
type 'a tree = | ||
| Leaf | ||
| Node of 'a tree * 'a * 'a tree;; | ||
``` | ||
|
||
```ts | ||
type Tree<T> = | ||
| { type: "leaf" } | ||
| { type: "node", left: Tree<T>, value: T, right: Tree<T> }; | ||
``` | ||
|
||
## Design | ||
|
||
This type becomes valid Luau syntax. | ||
|
||
```lua | ||
type Tree<T> = | ||
| { type: "leaf" } | ||
| { type: "node", left: Tree<T>, value: T, right: Tree<T> } | ||
``` | ||
|
||
## Drawbacks | ||
|
||
No drawbacks. The parser change is trivial. Instead of trying to parse a simple type and then calling `Parser::parseTypeSuffix`, simply sense whether the current lexeme is `|` or `&` and directly invoke `Parser::parseTypeSuffix` with `nullptr` for the first type and making sure that `nullptr` does not get pushed into the resulting vector. If the current lexeme is not `|` or `&`, then revert to current logic. | ||
|
||
## Alternatives | ||
|
||
Don't do this and accept one of the solutions already mentioned. |