Hacker News new | ask | show | jobs
by chunkyslink 2985 days ago
Could someone please explain what this could be used for ?
6 comments

Instead of using if or switch statements to compute a value, you can use a prettier interface.

So this:

  function getStatus(status) {
    if (status === 200){
      return "Success";
    } else if (status === 401){
      return "Fail!";
    }
  }

  var myString = getStatus(response.status);
Now becomes this:

  var myString = match (status) {
    {200} => "Success",
    {401} => "Fail!"
  }
More like:

  var myString = match (status) {
    200 => "Success",
    401 => "Fail!"
  }
Smooshes the evaluation of an object that can be many different shapes into an easy to understand operation.

I think the HTTP response is a great example. It can have many status codes which can determine how you want to proceed with that response. If you've worked with handling HTTP responses, you've most likely implemented some version of a 'match' operation before.

Is not `switch` enough for this?
It's more concise than switch, as well as more powerful (can destructure objects). You can't set things equal to the result of a switch. I find the pattern very convenient.

  let day;
  switch (date) {
      case 1:
          day = "mon";
          break;
      case 2:
          day = "tues";
          break;
      default:
          day = "wed";
          break;
vs

  let day = match(date) {
      1 => 'mon',
      2 => 'tues'
  }
In fairness I think that would look a bit more like this:

    const getDate = (date) => {
      switch (date) {
        case 1:
          return 'mon'

        case 2:
          return 'tues'

        default:
          return 'wed'
      }
    }

    let date = getDate(1)
Which is, of course, still less terse. What I normally use when I have cases like this is an object-as-a-map. IE:

    const dates = {
      1: 'mon',
      2: 'tues'
    }

    let day = dates[3] || 'wed';
By the way, I don't think it is a good idea to write a function as a constant. Please compare this

    function getDate(date) { .. } 
to this:

    const getDate = (date) => { ... } 
The first version is more readable. We instantly see that it is a function and in a second case it looks like a constant at first. Also without the equal and arrow sign it looks simpler.
Life is more fun with fat arrows sometimes

    new Promise(function (resolve, reject) {
        methodOne(data, function (error, response) {
            if (erorr) {
                reject(error);
            } else {
                resolve(response);
            }
        })
    })
vs

    new Promise((resolve, reject) => methodOne(data, (error, response) => error ? reject(error) : resolve(response)));
But function getDate(date) is hoisted. The const version isn't.
From looking at the proposal, there are substantial differences. The biggest is that switch is an equality test on a single value, while pattern matching as proposed allows matching on multiple properties of an object, as well as conditional clauses.

I need to look at it more closely, as some languages have matching be an expression, rather than a statement or block like the conventional switch.

It doesn't add something that you can't already do- tcomb and other libraries offer functions that mimic it- but it changes the way you can express certain ideas without needing them, in a way that is already familiar from other languages.

EDIT: yes, it does look like an expression, which means it can be used in many more places than a standard switch.

> Smooshes the evaluation

I see what you did there...

Pattern matching is very common in ML languages and is a core part of Rust.

As another commenter said, it's like conditionals on steroids.

Pattern matching can be quite powerful, e.g. in C# (which I wish was more indepth / more featured, it still feels a bit immature :( )

```

    switch(foo)
    {
       case TextBox t:
          Console.Writeline(t.Text);
          break;
       case TextBox when t.Text = "Bob":
          Console.WriteLine("Hello Bob");
          break;
       case Combobox c:
          Console.WriteLine($"{c.SelectedItem}");
          break;
       case null:
          Console.WriteLine("Ooops, null!");
          break;
       case int i when i == 5:
          Console.WriteLine("got an int, and it was 5!");
          break;
       case default:
           // handle the default case.
           break;
     }
```

IN languages like F#, pattern matching can compile time check you have covered all bases as well.

e.g, this won't build

````

    type VariableResult =
      | E of string
      | V of string

    let result = V "variable"

    match result with
      | E e -> printf "was error"
```

As i haven't told it how to handle the V case for that discriminated union. So you get nice compile time checking.

Ugh, how do you format code?

> Pattern matching can be quite powerful, e.g. in C# (which I wish was more indepth / more featured, it still feels a bit immature :( )

C# doesn't really deserve the name of pattern matching, just a type-based switch (with guards), you can't match on values let alone destructure them.

> Ugh, how do you format code?

4 spaces indent.

Basically simplifying and shortening a ton of common patterns of code, very similarly to how the new-ish destructuring syntax did a few years ago.
So, there are example use cases in the proposal [1]. I think it's meant to standardize how we handle conditional inputs or shapes of inputs (some people use if statements, some switch, and others store it all in an object and use keys).

1. https://github.com/tc39/proposal-pattern-matching#motivating...