Update spec.md
This commit is contained in:
198
spec.md
198
spec.md
@@ -409,28 +409,85 @@ Give fuzzy-matched suggestions for at the following things:
|
|||||||
## Store as much debug in fromation as possible until type checking is done
|
## Store as much debug in fromation as possible until type checking is done
|
||||||
|
|
||||||
|
|
||||||
|
# Compilation units
|
||||||
|
|
||||||
|
Each file is a "compilation unit"
|
||||||
|
|
||||||
|
When compiling a compilation unit, the following inputs have to be provided:
|
||||||
|
- any amount of files containing signatures of exported definitions.
|
||||||
|
only definitions of the compilation unit that are in one of the signature files will get exported.
|
||||||
|
- any amount of other files containing imported definitions
|
||||||
|
|
||||||
|
Note that there is no practical difference between signature and source files.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Example</summary>
|
||||||
|
|
||||||
|
Export signature file `List.li`:
|
||||||
|
```
|
||||||
|
type List[t] = 'End | 'Cons {head:t, tail:List[t]}
|
||||||
|
|
||||||
|
# not providing a function body makes it a function signature definition
|
||||||
|
def [t] `a++b`(a: List[t], b: List[t]) -> List[t]
|
||||||
|
```
|
||||||
|
|
||||||
|
Import signature file `Option.li`:
|
||||||
|
```
|
||||||
|
type Option[t] = 'None | 'Some t
|
||||||
|
```
|
||||||
|
|
||||||
|
Compilation unit `List.lu`:
|
||||||
|
```
|
||||||
|
def [t] `a++b`(a: List[t], b: List[t]) -> List[t] {
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
# Syntax
|
# Syntax
|
||||||
Note that the order of syntax cases matter!
|
Note that the order of syntax cases matter!
|
||||||
```
|
```
|
||||||
Identifier = { (* ( a-z | A-Z | 0-9 | _ | - | . | # ) TODO: cvt to ebnf *) };
|
Identifier = { (* ( a-z | A-Z | 0-9 | _ | - | . | # ) TODO: cvt to ebnf *) };
|
||||||
|
|
||||||
Partial Type = '?', Identifier;
|
Partial Type = '?', Identifier;
|
||||||
Union Type Case = '\'', Identifier, [ Type (*default to Unit*) ];
|
Union Type Case = '\'', Identifier, [ Type (*default to Unit*) ];
|
||||||
Union Type = Union Type Case, { '|', Union Type Case};
|
Union Type = Union Type Case, { '|', Union Type Case};
|
||||||
Record Type Field = Identifier, ':', Type;
|
Record Type Field = Identifier, ':', Type;
|
||||||
Record Type = '{', [Record Type Field, {',' Record Type Field }], [ '...', Partial Type ], '}';
|
Record Type = '{', [Record Type Field, {',' Record Type Field }], [ '...', Partial Type ], '}';
|
||||||
Type = Partial Type | Identifier | Union Type | Record Type | TODO;
|
With Type = 'with', Identifier, {',', Identifier}, ':', Type;
|
||||||
|
Recursive Type = '&', Identifier, Type;
|
||||||
|
Nested Type = '(', Type, ')';
|
||||||
|
Multi Arg Type = '[', Type, {',', Type} ']', Type;
|
||||||
|
Auto Type = '_'; (* this only works as return type of signatures of func def, that also contain the impl *)
|
||||||
|
Type Part = Auto Type | Identifier | Partial Type | Union Type | Record Type | With Type | Recursive Type | Nested Type;
|
||||||
|
Type = {Type Part (* args *)}, Type Part;
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# OLD SPECIFICATION STARTING HERE
|
# OLD SPECIFICATION STARTING HERE
|
||||||
## automatic return types
|
|
||||||
```
|
|
||||||
def add(a: Num, b: Num) -> _ {
|
|
||||||
a + b
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## pattern matching
|
## pattern matching
|
||||||
```
|
```
|
||||||
type Option[t] = 'None | 'Some t
|
type Option[t] = 'None | 'Some t
|
||||||
@@ -462,121 +519,7 @@ def example(li: List[Char]) -> {t:Token,rem:List[Char]} {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## recursive data types
|
|
||||||
```
|
|
||||||
type List[t] = 'End | 'Cons {head:t, tail:List[t]}
|
|
||||||
# now you might notice an issue with this
|
|
||||||
# `type` defines non-distinct type alisases
|
|
||||||
# so what is the type of this...
|
|
||||||
# Introducing: type self references
|
|
||||||
# the above example is the same as this:
|
|
||||||
type List[t] = &a ('End | 'Cons {head:t, tail:a})
|
|
||||||
|
|
||||||
# example 2:
|
|
||||||
# a List[List[t]] is just:
|
|
||||||
&b ('End | 'Cons {head: &a ('End | 'Cons {head:t, tail:a}), tail: b})
|
|
||||||
```
|
|
||||||
|
|
||||||
Infinitely sized types are not allowed:
|
|
||||||
```
|
|
||||||
&a {x:Num, y:a}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, infinite types without size *are* allowed:
|
|
||||||
```
|
|
||||||
&a {x:a}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is *not* allowed:
|
|
||||||
```
|
|
||||||
&a a
|
|
||||||
```
|
|
||||||
|
|
||||||
## module system
|
|
||||||
Each file is a "compilation unit"
|
|
||||||
|
|
||||||
When compiling a compilation unit, the following inputs have to be provided:
|
|
||||||
- any amount of files containing signatures of exported definitions.
|
|
||||||
only definitions of the compilation unit that are in one of the signature files will get exported.
|
|
||||||
- any amount of other files containing imported definitions
|
|
||||||
|
|
||||||
Note that there is no practical difference between signature and source files.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
Export signature file `List.li`:
|
|
||||||
```
|
|
||||||
type List[t] = 'End | 'Cons {head:t, tail:List[t]}
|
|
||||||
|
|
||||||
# not providing a function body makes it a function signature definition
|
|
||||||
def [t] `a++b`(a: List[t], b: List[t]) -> List[t]
|
|
||||||
|
|
||||||
def [t] Match.`a++b`(
|
|
||||||
value: List[t],
|
|
||||||
l: List[t],
|
|
||||||
r: MatchUtil.Var[List[t]]
|
|
||||||
) -> Option[{ r: List[t] }]
|
|
||||||
```
|
|
||||||
|
|
||||||
Import signature file `Option.li`:
|
|
||||||
```
|
|
||||||
type Option[t] = 'None | 'Some t
|
|
||||||
```
|
|
||||||
|
|
||||||
Compilation unit `List.lu`:
|
|
||||||
```
|
|
||||||
def [t] `a++b`(a: List[t], b: List[t]) -> List[t] {
|
|
||||||
# ...
|
|
||||||
}
|
|
||||||
|
|
||||||
def [t] Match.`a++b`(
|
|
||||||
value: List[t],
|
|
||||||
l: List[t],
|
|
||||||
r: MatchUtil.Var[List[t]]
|
|
||||||
) -> Option[{ r: List[t] }] {
|
|
||||||
# ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
Each compilation unit gets compiled to implementation-specific bytecode.
|
|
||||||
|
|
||||||
Templated functions can only be compiled partially during a compilation unit. This will impact compile speeds.
|
|
||||||
|
|
||||||
Avoid templated functions wherever possible.
|
|
||||||
|
|
||||||
## Hide record fields in module signatures
|
|
||||||
Signatue:
|
|
||||||
```
|
|
||||||
type User = {name: List[Char], ...}
|
|
||||||
# the ... is used to indicate that this is a partial type definition
|
|
||||||
# User, as given here, can not be constructed, but name can be accessed
|
|
||||||
```
|
|
||||||
Compilation unit:
|
|
||||||
```
|
|
||||||
type User = {name: List[Char], password: List[Char]}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Hide union variants in module signatures
|
|
||||||
Signature:
|
|
||||||
```
|
|
||||||
type DType = 'Int | 'UInt | 'Byte | ...
|
|
||||||
# users of this can never do exhaustive pattern matching on this
|
|
||||||
```
|
|
||||||
Compilation unit:
|
|
||||||
```
|
|
||||||
type DType = 'Int | 'UInt | 'Byte
|
|
||||||
# this compilation unit can actually do exhaustive pattern matching on this
|
|
||||||
```
|
|
||||||
|
|
||||||
## Note on hidden union variants / record fields
|
|
||||||
To make these work, the following is legal:
|
|
||||||
```
|
|
||||||
def example() -> 'Int | 'UInt | ...
|
|
||||||
|
|
||||||
def example() -> 'Int | 'UInt | 'Byte | 'Char {
|
|
||||||
# ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Extensible unions
|
## Extensible unions
|
||||||
```
|
```
|
||||||
@@ -589,17 +532,6 @@ extend Plan with 'WritelnPlan Unit
|
|||||||
# can only pattern match with the imported extensions
|
# can only pattern match with the imported extensions
|
||||||
```
|
```
|
||||||
|
|
||||||
## Any type
|
|
||||||
in the stdlib:
|
|
||||||
```
|
|
||||||
extensible union Any
|
|
||||||
|
|
||||||
type Any.LambdaCalc = 'Apply {fn: Any.LambdaCalc, arg: Any.LambdaCalc}
|
|
||||||
| 'Scope {idx: Uint}
|
|
||||||
| 'Abstr {inner: Any.LambdaCalc}
|
|
||||||
def Any.toLambda(a: Any) -> Any.LambdaCalc
|
|
||||||
```
|
|
||||||
It gets automatically extended with every type ever used.
|
|
||||||
|
|
||||||
## Lenses
|
## Lenses
|
||||||
In the stdlib:
|
In the stdlib:
|
||||||
|
Reference in New Issue
Block a user