Update spec.md

This commit is contained in:
2025-09-12 10:12:15 +02:00
parent 0d3305f68d
commit d3d8d9a3cc

59
spec.md
View File

@@ -1,7 +1,7 @@
## Arithmetic ## Arithmetic
``` ```
1.2 * 4 + 1 1.2 * 4 + 1
(* result: 5.8 *) # result: 5.8
``` ```
## Few types to learn ## Few types to learn
@@ -21,7 +21,7 @@ Advanced (uncommon) types:
## Functions ## Functions
``` ```
def msg(username: List[Char]) : List[Char] { def msg(username: List[Char]) : List[Char] {
"Hello, " ++ username ++ "!" (* last expr is returned *) "Hello, " ++ username ++ "!" # last expr is returned
} }
def main() { def main() {
@@ -33,7 +33,7 @@ main()
## Simple, forward type-inference ## Simple, forward type-inference
``` ```
def zero () : Flt32 { def zero () : Flt32 {
3.1 (* error: got Num, but expected F32 *) 3.1 # error: got Num, but expected F32
} }
``` ```
@@ -46,8 +46,8 @@ let passw = "1234"
## Mutability only via `ref` ## Mutability only via `ref`
``` ```
let value = Cell.from(1) let value = Cell.from(1)
print(Num.to_str(!value)) (* !cell "observes" the cell *) print(Num.to_str(!value)) # !cell "observes" the cell
value := 2 (* `:=` mutates the cell *) value := 2 # `:=` mutates the cell
print(Num.to_str(!value)) print(Num.to_str(!value))
``` ```
@@ -66,7 +66,7 @@ all operators:
## non-nominal struct types ## non-nominal struct types
``` ```
(* `type` creates a non-distinct type alias *) # `type` creates a non-distinct type alias
type User = { name: List[Char] } type User = { name: List[Char] }
type DbUser = { name: List[Char], pass: List[Char] } type DbUser = { name: List[Char], pass: List[Char] }
@@ -80,54 +80,55 @@ def example2() : {name: List[Char], pass: List[Char]} {
} }
def example3() : User { def example3() : User {
example2() (* {name:.., pass:...} can automatically decay to {name:...} *) example2() # {name:.., pass:...} can automatically decay to {name:...}
} }
``` ```
## mixed-tagged union types ## mixed-tagged union types
``` ```
type Option[t] = type Option[t] =
'Err Unit (* Unit that has tag enum 'Err *) 'Err Unit # Unit that has tag enum 'Err
| t (* has no tag *) | t # has no tag
(* the tags of unions are weakly attached to the types, but won't decay unless they have to *) # the tags of unions are weakly attached to the types, but won't decay unless they have to *)
def example(n: Num) : Num { def example(n: Num) : Num {
let x = 'MyTag n (* type of x is 'MyTag Num *) let x = 'MyTag n # type of x is 'MyTag Num
x (* tag gets removed because target type is Num *) x # tag gets removed because target type is Num
} }
def example2(n: Num) : Option[Num] { def example2(n: Num) : Option[Num] {
n (* this works, because the `t` is not tagged in option *) n # this works, because the `t` is not tagged in option
} }
def example3-invalid() : Option[Num] { def example3-invalid() : Option[Num] {
Unit (* error: can't convert type `Unit` into type `'Err Unit | t` Unit # error: can't convert type `Unit` into type `'Err Unit | t`
* Either label the expression with 'Err, # Either label the expression with 'Err,
* or change the return type to Option[Unit] *) # or change the return type to Option[Unit]
} }
def exampe4(): Option[Num] { def exampe4(): Option[Num] {
'Err Unit 'Err Unit
(* type of this expression is: `'Err Unit` *) # type of this expression is: `'Err Unit`
(* enums can automatically cast, if all the cases from the source enum also exists in the target enum, # enums can automatically cast, if all the cases from the source enum also exists in the target enum,
* which they do here: `'Err Unit` is a case in `'Err Unit | Num` *) # which they do here: `'Err Unit` is a case in `'Err Unit | Num`
} }
def example5-error(): Option[Num] { def example5-error(): Option[Num] {
let x = ( 'Err Unit ) :: Option[Unit] let x = ( 'Err Unit ) :: Option[Unit]
x x
(* error: can't convert type `'Err Unit | Unit` into type `'Err Unit | Num` # error: can't convert type `'Err Unit | Unit` into type `'Err Unit | Num`
* The case `Unit` does not exist in the target `'Err Unit | Num` *) # The case `Unit` does not exist in the target `'Err Unit | Num`
} }
def example6-error(): Option[Unit] { def example6-error(): Option[Unit] {
let x = 'Error Unit let x = 'Error Unit
x x
(* in this case, the enum tag does not decay, like in `example`, # in this case, the enum tag does not decay, like in `example`,
* because we are casting to an enum *) # because we are casting to an enum
(* error: can't convert type `'Error Unit` into type `'Err Unit | Num``
* 1st possible solution: manually cast to just `Unit` (via `expr :: Unit`), so that it can convert to the second case of the target # error: can't convert type `'Error Unit` into type `'Err Unit | Num``
* 2nd possible solution: pattern match against the enum, to rename the tag from 'Error to 'Err *) # 1st possible solution: manually cast to just `Unit` (via `expr :: Unit`), so that it can convert to the second case of the target
# 2nd possible solution: pattern match against the enum, to rename the tag from 'Error to 'Err
} }
``` ```
@@ -136,11 +137,11 @@ def example6-error(): Option[Unit] {
type Option[t] = 'None | 'Some t type Option[t] = 'None | 'Some t
def [t] Match.`a++b`( def [t] Match.`a++b`(
(* matching against this value *) # matching against this value
value: List[t], value: List[t],
(* left hand side of operator *) # left hand side of operator
l: List[t], l: List[t],
(* right hand side of operator *) # right hand side of operator
r: MatchUtil.Var[List[t]] r: MatchUtil.Var[List[t]]
) -> Option[{ r: List[t] }] { ) -> Option[{ r: List[t] }] {
match List.remove_prefix(l, 'from value) { match List.remove_prefix(l, 'from value) {