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
|
||||
|
||||
|
||||
# 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
|
||||
Note that the order of syntax cases matter!
|
||||
```
|
||||
Identifier = { (* ( a-z | A-Z | 0-9 | _ | - | . | # ) TODO: cvt to ebnf *) };
|
||||
|
||||
Partial Type = '?', Identifier;
|
||||
Union Type Case = '\'', Identifier, [ Type (*default to Unit*) ];
|
||||
Union Type = Union Type Case, { '|', Union Type Case};
|
||||
Record Type Field = Identifier, ':', 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
|
||||
## automatic return types
|
||||
```
|
||||
def add(a: Num, b: Num) -> _ {
|
||||
a + b
|
||||
}
|
||||
```
|
||||
|
||||
## pattern matching
|
||||
```
|
||||
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
|
||||
```
|
||||
@@ -589,17 +532,6 @@ extend Plan with 'WritelnPlan Unit
|
||||
# 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
|
||||
In the stdlib:
|
||||
|
Reference in New Issue
Block a user