# Function Pattern Matching

**URL:** <https://es.discourse.group/t/function-pattern-matching/1376>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [June 22, 2022, 11:11am UTC](https://es.discourse.group/t/function-pattern-matching/1376 "2022-06-22T11:11:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ColtHands](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/colthands/32/1411_2.png) [@ColtHands](https://es.discourse.group/u/ColtHands)\
**Post date:** [June 22, 2022, 11:11am UTC](https://es.discourse.group/t/function-pattern-matching/1376/1 "2022-06-22T11:11:28Z")

</div>

# **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:

![image](https://global.discourse-cdn.com/free1/uploads/es/original/2X/a/aad56aba6e4f8b9b0f4bd2dba2e5406a3354b342.png)

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.

```javascript
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

```javascript
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

```javascript
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

```javascript
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_

```javascript
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_

```javascript
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

```javascript
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?

```javascript
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:

```javascript
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](https://www.haskell.org/tutorial/patterns.html)  
[Haskell Pattern matching stackoverflow](https://stackoverflow.com/questions/2225774/haskell-pattern-matching-what-is-it)  
[Syntax in function (learn you haskell)](http://learnyouahaskell.com/syntax-in-functions)

What Do you think? Is this is readable? How can this be impoved? Are there similar features like that in `F#` or `Elixir`?

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [July 5, 2022, 9:40pm UTC](https://es.discourse.group/t/function-pattern-matching/1376/2 "2022-07-05T21:40:13Z")

</div>

Are you familiar with the existing stage 1 Pattern Matching proposal for JS? [GitHub - tc39/proposal-pattern-matching: Pattern matching syntax for ECMAScript](https://github.com/tc39/proposal-pattern-matching/)

---

<div class="post-metadata">

**Author:** ![ColtHands](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/colthands/32/1411_2.png) [@ColtHands](https://es.discourse.group/u/ColtHands)\
**Post date:** [July 6, 2022, 11:36am UTC](https://es.discourse.group/t/function-pattern-matching/1376/3 "2022-07-06T11:36:23Z")

</div>

Yes, this is somewhat different syntax approach for a same result.

Basically I've copied the idea from Haskell. It's a more functional approach.

Basically when you pass args as params function handles differently.

`const sum = (a,b) => a + b`

`const sum = (5,6) => "lol, this is not what you expected"`

The main idea is that Ive tried to make this approach more intuitive.

---

<div class="post-metadata">

**Author:** ![ColtHands](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/colthands/32/1411_2.png) [@ColtHands](https://es.discourse.group/u/ColtHands)\
**Post date:** [August 2, 2022, 6:09am UTC](https://es.discourse.group/t/function-pattern-matching/1376/4 "2022-08-02T06:09:56Z")

</div>

Yea, looking at this further, the match syntas solves the switch case problem, here i wanted to loose unnesessary syntax tohugh, with some sort of `do` block, mattern match syntax. This syntax is however is for functions specifically
