Functional Pattern Matching for a function.
Basically an idea that we can declare a function multiple times passing arguments (or matching argument) as parameters, and getting different statements depending on that parameter.
In General this might just look like a syntax sugar for an if
statement or a switch
case
, but that could be much more.
I'd think this would be a great functional addition to the functional arrow functions, partial-applications, do blocks, or pipeline-operators.
Lets look at the most basic example a fibonacci sequence:
Let look at the ways we can define it, starting from the most reasonable lines of code to least code possible.
Switch case, an overkill imo.
function fibonacci(n) {
switch(n) {
case 0:
case 1:
return 1
default:
return (fibonacci(n-1) + fibonacci(n-2))
}
}
Here we cant check for negative value and write something like case n >= 2
Lets look at most basic way to do this correctly
function fibonacci(n) {
if(n == 0 || n == 1) {
return 1
} else {
return (fibonacci(n-1) + fibonacci(n-2))
}
}
I think we can improve on this function though, lets make it functional and readable
const fibonacci= (n) => {
if(n == 0 || n == 1)
return 1
else
return (fibonacci(n-1) + fibonacci(n-2))
}
I personally think this looks nice, functional and readable.
Lets try to create such a function with minimal code possible
let fib = n => n <= 1 ? 1 : fib(n-1) + fib(n-2)
Do you think thats readable?
Well I might write some ninja code here and there and not care if a other developers can read it, but imagine you see => n <=
, my initial reaction would be Hey that's a smiley face
Proposal
Ability to define a function with arguments rather than parameters
So let me show you how i think this function should look and maybe some variations.
example 1 with const
const fib = 0 => 1
const fib = 1 => 1
const fib = n => fib(n-1) + fib(n-2)
Yes, this will throw an exeption atm, but maybe we can have a special word like async
?
example 1 with pat
pat fib = 0 => 1
pat fib = 1 => 1
pat fib = n => fib(n-1) + fib(n-2)
pat
being shorthand for pattern
Both exmaples 1 and 2 would yeild something like
const fib(n) {
if(n === 0) { return 1 }
if(n === 1) { return 1 }
return fib(n-1) + fib(n-2)
}
Where the last line return woud be the actual statement that wasn't matched, and everything that did goes on top.
Or some other type of syntax feature like new TC39 proposal pipes?
const fib = n =>
|> 0 = 1
|> 1 = 1
|> n = fib(n-1) + fib(n-2)
This still does not fix a problem with negative numbers....
We can improve on this feature with some matching for example:
const fib = n =>
|> n <= 1 = 1
|> n >= 2 = fib(n-1) + fib(n-2)
I think this is quite readable and really functional. And just imagine what can we do if this could be combined with pipeline-operator
and partial-application
proposals...
Further reading and insporation
Haskell Patterns Tutorial
Haskell Pattern matching stackoverflow
Syntax in function (learn you haskell)
What Do you think? Is this is readable? How can this be impoved? Are there similar features like that in F#
or Elixir
?