Open bvssvni opened 7 years ago
An array pattern fails if it does not match exactly:
x := [1, 2, 3]
if [a, b] ?= x {
// never runs because the number of items are not the same
...
}
To match against an array with a tail, add , ..
at the end:
x := [1, 2, 3]
if [a, b, ..] ?= x {
// runs because a tail is allowed
...
}
To bind against the tail, use ..<name>
. This does a shallow clone of the items, inheriting the lifetime of the array.
x := [1, 2, 3]
if [_, _, ..a] ?= x {
println(a) // prints `[3]`
}
Can also put the tail before the items:
x := [1, 2, 3]
if [..a, b] ?= x {
println(a) // prints `[1, 2]`
println(b) // prints `3`
}
In general, one can put items before and after the tail. The tail can be empty, so the following runs:
x := [1, 2, 3, 4]
if [a, b, ..c, d, e] ?= x {
println(c) // prints `[]`
}
Rules for the array tail:
An array pattern fails if it does not match exactly:
x := {a: 1, b: 2, c: 3}
if {a: a, b: b} ?= x {
// never runs because there are other items
...
}
To match against an object with extra items, add , ..
at the end:
x := {a: 1, b: 2, c: 3}
if {a: a, b: b, ..} ?= x {
// runs because extra items are allowed
...
}
One can also use same name for the variable as for the key:
x := {a: 1, b: 2, c: 3}
if {a, b, c} ?= x {
...
}
To bind against the extra items (the object tail), use ..<name>
. This does a shallow clone of the items, inheriting the lifetime of the object.
x := {a: 1, b: 2, c: 3}
if {a: _, b: _, ..xc} ?= x {
println(xc) // prints `{c: 3}`
}
Rules for the object tail:
vec4
Can be used with :=
if there are no constants in the pattern, which makes the type checker checks the type of the right expression is a vec4
.
A vec4
pattern succeeds even when there are more non-zero components than in the pattern:
x := (1, 2, 3)
(a, b) := x
To match against zero, use 0
s:
x := (1, 2, 3)
if (a, b, 0, 0) ?= x {
// never runs because `z` is non-zero
...
}
Swizzling pattern tells where to put components in created vectors:
x := (1, 2, 3, 4)
(yx a, x b, w c) := x
println(a) // prints `(2, 1)`
println(b) // prints `(3, 0)`
println(c) // prints `(0, 0, 0, 4)`
Rules for swizzling pattern:
(xx a,) := v
gives an errorAn link pattern fails if it does not match exactly:
x := link {1 2 3}
if link {a b} ?= x {
// never runs because the number of items are not the same
...
}
To match against a link with a tail, add , ..
at the end:
x := link {1 2 3}
if link {a b ..} ?= x {
// runs because a tail is allowed
...
}
To bind against the tail, use ..<name>
.
x := link {1 2 3"rd"}
if link {_ _ ..a} ?= x {
println(a) // prints `3rd`
}
Can also put the tail before the items:
x := link {1","2 3}
if link {..a b} ?= x {
println(a) // prints `1,2`
println(b) // prints `3`
}
In general, one can put items before and after the tail. The tail can be empty, so the following runs:
x := link {1 2 3 4}
if link {a b ..c d e} ?= x {
println(c) // prints ``
}
Rules for the link tail:
When matching against a constant, both run-time type and equality is checked.
true
/false
0
/1
/... (other numbers)"hello"
(other strings)#ff0000
(other HTML hex colors)Put a ?
in front of the expression to check for equality:
a := 1
x := [1, 2]
if [?a, b] ?= x {
...
}
This also works well with grab expressions in closures:
fn foo(a: f64) -> \([f64]) -> bool {
return \(x) = if [?grab a, ..] ?= x { true } else { false }
}
A string can be matched against a regular expression. More discussion https://github.com/PistonDevelopers/dyon/issues/284
Related to https://github.com/PistonDevelopers/dyon/issues/304
Idea taken from https://github.com/PistonDevelopers/dyon/issues/359, but might be useful in general.
The idea is to add pattern matching to Dyon, a bit similar to Rust. Since Dyon is dynamically typed there is a
?=
operator instead of:=
.The
?=
operator checks the run-time type at run-time and reports an error if it is wrong. The type checker checks the static types and reports an error if the code never gets called.If pattern
The
?=
operator can be used withif
:Try pattern
It can also be used directly in a function that returns
err
:The following code gives an error because it is exhaustive:
Match pattern
A
match
expression similar to Rust:The
match
requires_
or a variable since it can not be exhaustively checked.Type is checked on all arms like with an if-expression.