| Love this comment; reminds me of what I thought when I first encountered pattern matching. a. Yup, that's what it's called in OCaml, Scala, F#, etc. Might be a little confusing at first, but it's all about finding a "match" for your value, which is different from a guard in an "if" or a "switch". In an "if", you need to provide a boolean (or a value coercible to a boolean). In a "switch" you don't provide the boolean, but under the hood the switch is just iterating through and comparing your value to all cases: it computes the boolean for you by testing if two values are equal. Finding a "match" is different, because you're not comparing values, you're also comparing structure. So for example you can do things like match (v) {
case { x, y: 3 } => ...
case { y: 3, contents: { name: 'Foo', error }} => ...
case { x, y } => ...
} And it wont just compare "v" against all cases, do a deep comparison, check the existance of certain keys and bind variables as necessary so you can use them on `...`. b. More so than "returning a value" I like to think of it as "resolves to a value". Thinking of it as "returning" can be confusing since it might make it sound too much like a function. Switch/if are statements. They control flow, and ask the computer to do something. Another statement is assignment; `var a = 0;` "does" something, but it doesn't represent a value. Expressions like `3 + 2 + x`, `f(x)/2`, and `match({x:3}) {...}` represent a value that hasn't been computed, and then resolve to one. c. This is why I prefer to think of it as an expression: cause expressions resolve to values. Function calls are expressions too! d. If you're in a function, all expressions support recursion since you can mix them up. A e. Awesome. f. I think that's on purpose, because in a way each case acts a bit like a funciton. You can define "arguments" in it that get bound to values, and they resolve to another value. |
Switch can also be implemented as a jump table in some cases.