Skip to content

Commit

Permalink
Make "match" runnable
Browse files Browse the repository at this point in the history
  • Loading branch information
shaedrich authored May 24, 2024
1 parent 8306f56 commit 9e7d7f3
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 60 deletions.
21 changes: 13 additions & 8 deletions code-samples/match-captures.pony
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
fun f(x: (U32 | String | None)): String =>
match x
| None => "none"
| 2 => "two"
| 3 => "three"
| let u: U32 => "other integer"
| let s: String => s
end
actor Main
new create(env: Env) =>
env.out.print(f(2))
env.out.print(f(42))

fun f(x: (U32 | String | None)): String =>
match x
| None => "none"
| 2 => "two"
| 3 => "three"
| let u: U32 => "other integer"
| let s: String => s
end
25 changes: 15 additions & 10 deletions code-samples/match-guards.pony
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, _) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, let u: U32) if u > 14 => s + " other big integer"
| (let s: String, _) => s + " other small integer"
else
"something else"
end
actor Main
new create(env: Env) =>
env.out.print(f("one", 5))
env.out.print(f("two", 42))

fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, _) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, let u: U32) if u > 14 => s + " other big integer"
| (let s: String, _) => s + " other small integer"
else
"something else"
end
22 changes: 13 additions & 9 deletions code-samples/match-tuples-ignore-elements.pony
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, _) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, _) => s + " other integer"
else
"something else"
end
actor Main
new create(env: Env) =>
env.out.print(f("one", 42))

fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, _) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, _) => s + " other integer"
else
"something else"
end
22 changes: 13 additions & 9 deletions code-samples/match-tuples.pony
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, let u: U32) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, let u: U32) => s + " other integer"
else
"something else"
end
actor Main
new create(env: Env) =>
env.out.print(f("one", 2))

fun f(x: (String | None), y: U32): String =>
match (x, y)
| (None, let u: U32) => "none"
| (let s: String, 2) => s + " two"
| (let s: String, 3) => s + " three"
| (let s: String, let u: U32) => s + " other integer"
else
"something else"
end
23 changes: 14 additions & 9 deletions code-samples/match-type-and-value.pony
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
fun f(x: (U32 | String | None)): String =>
match x
| None => "none"
| 2 => "two"
| 3 => "three"
| "5" => "not four"
else
"something else"
end
actor Main
new create(env: Env) =>
env.out.print(f(2))
env.out.print(f(42))

fun f(x: (U32 | String | None)): String =>
match x
| None => "none"
| 2 => "two"
| 3 => "three"
| "5" => "not four"
else
"something else"
end
23 changes: 14 additions & 9 deletions code-samples/match-values.pony
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
fun f(x: U32): String =>
match x
| 1 => "one"
| 2 => "two"
| 3 => "three"
| 5 => "not four"
else
"something else"
end
actor Main
new create(env: Env) =>
env.out.print(f(2))
env.out.print(f(42))

fun f(x: U32): String =>
match x
| 1 => "one"
| 2 => "two"
| 3 => "three"
| 5 => "not four"
else
"something else"
end
12 changes: 6 additions & 6 deletions docs/expressions/match.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The compiler recognizes a match as exhaustive when the union of the types for al
The simplest match expression just matches on value.

```pony
--8<-- "match-values.pony"
--8<-- "match-values.pony:6:14"
```

For value matching the pattern is simply the value we want to match to, just like a C switch statement. The case with the same value as the operand wins and we use its expression.
Expand All @@ -53,7 +53,7 @@ The compiler calls the `eq()` function on the operand, passing the pattern as th
Matching on value is fine if the match operand and case patterns have all the same type. However, match can cope with multiple different types. Each case pattern is first checked to see if it is the same type as the runtime type of the operand. Only then will the values be compared.

```pony
--8<-- "match-type-and-value.pony"
--8<-- "match-type-and-value.pony:6:14"
```

In many languages using runtime type information is very expensive and so it is generally avoided whenever possible.
Expand All @@ -79,7 +79,7 @@ Sometimes you want to be able to match the type, for any value of that type. For
Captures look just like variable declarations within the pattern. Like normal variables, they can be declared as var or let. If you're not going to reassign them within the case expression it is good practice to use let.

```pony
--8<-- "match-captures.pony"
--8<-- "match-captures.pony:6:13"
```

__Can I omit the type from a capture, like I can from a local variable?__ Unfortunately no. Since we match on type and value the compiler has to know what type the pattern is, so it can't be inferred.
Expand All @@ -105,13 +105,13 @@ does not type check.
If you want to match on more than one operand at once then you can simply use a tuple. Cases will only match if __all__ the tuple elements match.

```pony
--8<-- "match-tuples.pony"
--8<-- "match-tuples.pony:5:13"
```

__Do I have to specify all the elements in a tuple?__ No, you don't. Any tuple elements in a pattern can be marked as "don't care" by using an underscore ('_'). The first and fourth cases in our example don't actually care about the U32 element, so we can ignore it.

```pony
--8<-- "match-tuples-ignore-elements.pony"
--8<-- "match-tuples-ignore-elements.pony:5:13"
```

## Guards
Expand All @@ -123,5 +123,5 @@ Guards are introduced with the `if` keyword (_was `where` until 0.2.1_).
A guard expression may use any captured variables from that case, which allows for handling ranges and complex functions.

```pony
--8<-- "match-guards.pony"
--8<-- "match-guards.pony:6:15"
```

0 comments on commit 9e7d7f3

Please sign in to comment.