Change tuple typing syntax #600

Merged
zxq9 merged 3 commits from github/fork/radrow/tuple-type into master 2019-08-05 16:13:31 +09:00
zxq9 commented 2019-07-22 21:52:37 +09:00 (Migrated from gitlab.com)

Created by: radrow

Motivation

Previously the syntax for tuple types was identical to tuple values:

x : () // unit
y : (int) // actually an int, not a tuple
z : (int, string) // pair

Problem with this notation is that it is shared with multi argument function domain which causes

f : (int, int) => int

to mean both a function that takes two ints as an argument and a function that takes a single pair of ints. Our parser forbids ambiguous parsing results and takes strategy to parse domain as a tuple and turn it into an argument list which makes having a tuple or unit as the only argument impossible. Tricks like ((int, int)) => int do not work, because ((int, int)) is parsed literally as (int, int) which is treated at first as a tuple and then...

%% TODO: not nice
fun_domain({tuple_t, _, Args}) -> Args;
fun_domain(T)                  -> [T].

as a list of args.

Disability to express some types beside just being not nice can lead to further problems, for instance in #108 where the compiler expects programmer to explicitly specify the desired type.

Syntax changes

This PR solves this problem by introducing new syntax for typing tuples:

x : unit
y : (int) // still regular int
z : (int * int)
w : int * int // parentheses are optional

Now, ('a * 'b) => 'a is clearly different from ('a, 'b) => 'c, same for unit => 'a and () => 'a.

The x * y syntax has priority between lambda and type application / bytes notation, so 'a * 'b => 'c means ('a * 'b) => 'c.

This notation is mainly inspired by SML language which uses same syntax for unit and non-zero tuples. Sophia is said to belong to ML-family, so this update makes some sense in this context. Also, Cartesian product is commonly encoded this way, so the change shouldn't bring a lot of confusion.

*Created by: radrow* ## Motivation Previously the syntax for tuple types was identical to tuple values: ```pascal x : () // unit y : (int) // actually an int, not a tuple z : (int, string) // pair ``` Problem with this notation is that it is shared with multi argument function domain which causes ```pascal f : (int, int) => int ``` to mean both a function that takes two ints as an argument **and** a function that takes a single _pair_ of ints. Our parser forbids ambiguous parsing results and takes strategy to parse domain as a tuple and turn it into an argument list which makes having a tuple or unit as the only argument impossible. Tricks like `((int, int)) => int` do not work, because `((int, int))` is parsed literally as `(int, int)` which is treated at first as a tuple and then... ```erlang %% TODO: not nice fun_domain({tuple_t, _, Args}) -> Args; fun_domain(T) -> [T]. ``` as a list of args. Disability to express some types beside just being not nice can lead to further problems, for instance in #108 where the compiler expects programmer to explicitly specify the desired type. ## Syntax changes This PR solves this problem by introducing new syntax for typing tuples: ``` x : unit y : (int) // still regular int z : (int * int) w : int * int // parentheses are optional ``` Now, `('a * 'b) => 'a` is clearly different from `('a, 'b) => 'c`, same for `unit => 'a` and `() => 'a`. The `x * y` syntax has priority between lambda and type application / bytes notation, so `'a * 'b => 'c` means `('a * 'b) => 'c`. This notation is mainly inspired by SML language which uses same syntax for `unit` and non-zero tuples. Sophia is said to belong to ML-family, so this update makes some sense in this context. Also, Cartesian product is commonly encoded this way, so the change shouldn't bring a lot of confusion.
zxq9 commented 2019-07-22 21:52:51 +09:00 (Migrated from gitlab.com)

Created by: radrow

cc @hanssv @UlfNorell

*Created by: radrow* cc @hanssv @UlfNorell
zxq9 commented 2019-07-22 22:23:09 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

Double parens? Should probably be

        _ -> [$(,lists:join(" * ", Ts),$)]
*Created by: UlfNorell* Double parens? Should probably be ```suggestion:-0+0 _ -> [$(,lists:join(" * ", Ts),$)] ```
zxq9 commented 2019-07-29 18:01:15 +09:00 (Migrated from gitlab.com)

Created by: radrow

I was not aware about this dollar notation. Sure

*Created by: radrow* I was not aware about this dollar notation. Sure
zxq9 commented 2019-08-02 15:33:02 +09:00 (Migrated from gitlab.com)

Created by: UlfNorell

Review: Approved

*Created by: UlfNorell* **Review:** Approved
zxq9 commented 2019-08-05 16:12:54 +09:00 (Migrated from gitlab.com)

Created by: hanssv

Review: Approved

👍

*Created by: hanssv* **Review:** Approved 👍
zxq9 commented 2019-08-05 16:13:31 +09:00 (Migrated from gitlab.com)

Merged by: UlfNorell at 2019-08-05 07:13:31 UTC

*Merged by: UlfNorell at 2019-08-05 07:13:31 UTC*
Sign in to join this conversation.
No description provided.