[fine] Notes on patterns
This commit is contained in:
parent
deed9d9a45
commit
e0721d09fc
1 changed files with 72 additions and 0 deletions
|
|
@ -40,6 +40,78 @@ immediately following the `new` keyword is always a type expression,
|
||||||
so we know that e.g. `<` or whatever means "generic type parameter"
|
so we know that e.g. `<` or whatever means "generic type parameter"
|
||||||
and not "less than".
|
and not "less than".
|
||||||
|
|
||||||
|
## Patterns and Alternate Types
|
||||||
|
|
||||||
|
Instead of `enums` or inheritance, we're using an alternate type like
|
||||||
|
in Typescript, with `or` between types. See the `alternates.fine` test
|
||||||
|
for a work-up of the types and syntax and whatnot. I think it works
|
||||||
|
pretty well.
|
||||||
|
|
||||||
|
Actually using alternate types involves pattern matching, either one
|
||||||
|
at a time, with the `is` operator, or in bulk, with the `match`
|
||||||
|
expression. `match` can check for completeness, but `if/is` cannot.
|
||||||
|
|
||||||
|
Patterns are VERY simple, and are explicitly *not* destructuring right
|
||||||
|
now. (Destructuring brings up a whole lot of complexity that I don't
|
||||||
|
want to deal with.)
|
||||||
|
|
||||||
|
Patterns are basically:
|
||||||
|
|
||||||
|
```
|
||||||
|
(identifier ":")? type_expression ("and" <expression>)?
|
||||||
|
```
|
||||||
|
|
||||||
|
The identifier at the front represents a binding of the value being
|
||||||
|
considered as if it were of the same type as the type expression; the
|
||||||
|
identifier is in scope for the optional predicate after the "and" and
|
||||||
|
so you can use it as if it were the type because, well, that part of
|
||||||
|
the pattern already matched.
|
||||||
|
|
||||||
|
As a special case, the identifier is *also* in scope for the body of
|
||||||
|
an `if` expression when an `is` expression is used as the condition.
|
||||||
|
|
||||||
|
```
|
||||||
|
if b is c:Foo {
|
||||||
|
result = result + c.a; // c should still be in scope!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`match` is the multi-value pattern matching expression, like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
match b {
|
||||||
|
c:Foo -> c.a,
|
||||||
|
_ -> 0,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The special pattern `_` always evaluates to true.
|
||||||
|
|
||||||
|
Note that unlike rust we do not allow variable binding, e.g., in rust you can write:
|
||||||
|
|
||||||
|
```
|
||||||
|
match b {
|
||||||
|
d -> ...,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
but in fine you need to write:
|
||||||
|
|
||||||
|
```
|
||||||
|
match b {
|
||||||
|
d:_ -> ...,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The reason is that the rust version is ambiguous: if `d` matches some
|
||||||
|
value already in scope (e.g., an `enum` arm) then the arm is matching
|
||||||
|
if b == d, but if `d` is unbound then `d` becomes a variable
|
||||||
|
declaration. This is a spooky action-at-a-distance and I don't approve
|
||||||
|
of it.
|
||||||
|
|
||||||
|
|
||||||
|
# Complete Garbage
|
||||||
|
|
||||||
## Lambdas/Closures/Anonymous Functions
|
## Lambdas/Closures/Anonymous Functions
|
||||||
|
|
||||||
Looking for a syntax here; I want to keep `fun` as a declaration like
|
Looking for a syntax here; I want to keep `fun` as a declaration like
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue