You're not alone in wanting pattern matching to be expression-based:

https://github.com/tc39/proposal-pattern-matching/issues/116

-----

Isiah Meadows
[email protected]
www.isiahmeadows.com

-----

Isiah Meadows
[email protected]
www.isiahmeadows.com


On Tue, Feb 26, 2019 at 1:34 PM David Koblas <[email protected]> wrote:
>
> Jordan,
>
> Thanks for taking time to read and provide thoughts.
>
> I just back and re-read the pattern matching proposal and it still fails on 
> the basic requirement of being an Expression not a Statement.  The problem 
> that I see and want to address is the need to have something that removes the 
> need to chain trinary expressions together to have an Expression.
>
> This is unmaintainable --
>
>     const x = v === 'foo' ? 1 : v === 'bar' ? 3 : v === 'baz' ? 6 : 99;
>
> This is maintainable, but is less than ideal:
>
>    let x;
>
>    switch (v) {
>    case "foo":
>      x = 1;
>      break;
>    case "bar":
>      x = 3;
>      break;
>    case "baz":
>      x = 6;
>      break;
>    default:
>      x = 99;
>      break;
>    }
>
> Pattern matching does shorten the code, but you have a weird default case and 
> also still end up with a loose variable and since pattern matching is a 
> statement you still have a initially undefined variable.
>
>    let x;
>
>    case (v) {
>      when "foo" -> x = 1;
>      when "bar" -> x = 3;
>      when "baz" -> x = 6;
>      when v -> x = 99;
>    }
>
> Let's try do expressions, I'll leave people's thoughts to themselves.
>
>    const x = do {
>      if (v === "foo") { 1; }
>      else if (v === "bar") { 3; }
>      else if (v === "baz") { 6; }
>      else { 99; }
>    }
>
> Or as another do expression variant:
>
>    const x = do {
>      switch (v) {
>        case "foo": 1; break;
>        case "bar": 3; break;
>        case "baz": 6; break;
>        default: 99; break;
>      }
>    }
>
> And as I'm thinking about switch expressions:
>
>    const x = switch (v) {
>      case "foo" => 1;
>      case "bar" => 3;
>      case "baz" => 6;
>      default => 99;
>    }
>
> What I really like is that it preserves all of the normal JavaScript syntax 
> with the small change that a switch is allowed in an expression provided that 
> all of the cases evaluate to expressions hence the use of the '=>' as an 
> indicator.  Fundamentally this is a very basic concept where you have a state 
> machine and need it switch based on the current state and evaluate to the new 
> state.
>
>    const nextState = switch (currentState) {
>       case ... =>
>    }
>
>
>
> On 2/25/19 4:00 PM, Jordan Harband wrote:
>
> Pattern Matching is still at stage 1; so there's not really any permanent 
> decisions that have been made - the repo theoretically should contain 
> rationales for decisions up to this point.
>
> I can speak for myself (as "not a champion" of that proposal, just a fan) 
> that any similarity to the reviled and terrible `switch` is something I'll be 
> pushing back against - I want a replacement that lacks the footguns and 
> pitfalls of `switch`, and that is easily teachable and googleable as a 
> different, distinct thing.
>
> On Mon, Feb 25, 2019 at 12:42 PM David Koblas <[email protected]> wrote:
>>
>> Jordan,
>>
>> One question that I have lingering from pattern matching is why is the 
>> syntax so different?  IMHO it is still a switch statement with a variation 
>> of the match on the case rather than a whole new construct.
>>
>> Is there somewhere I can find a bit of discussion about the history of the 
>> syntax decisions?
>>
>> --David
>>
>>
>> On Feb 25, 2019, at 12:33 PM, Jordan Harband <[email protected]> wrote:
>>
>> Additionally, https://github.com/tc39/proposal-pattern-matching - switch 
>> statements are something I hope we'll soon be able to relegate to the 
>> dustbin of history.
>>
>> On Mon, Feb 25, 2019 at 6:01 AM David Koblas <[email protected]> wrote:
>>>
>>> I quite aware that it’s covered in do expressions. Personally I find do 
>>> expressions non-JavaScript in style and it’s also not necessarily going to 
>>> make it into the language.
>>>
>>> Hence why I wanted to put out there the idea of switch expressions.
>>>
>>> --David
>>>
>>>
>>> On Feb 25, 2019, at 5:28 AM, N. Oxer <[email protected]> wrote:
>>>
>>> Hi,
>>>
>>> This would be covered by do expressions. You could just do:
>>>
>>> ```js
>>> const category = do {
>>>   switch (...) {
>>>     ...
>>>   };
>>> };
>>> ```
>>>
>>> On Sun, Feb 24, 2019 at 10:42 AM David Koblas <[email protected]> wrote:
>>>>
>>>> After looking at a bunch of code in our system noted that there are many
>>>> cases where our code base has a pattern similar to this:
>>>>
>>>>      let category = data.category;
>>>>
>>>>      if (category === undefined) {
>>>>        // Even if Tax is not enabled, we have defaults for incomeCode
>>>>        switch (session.merchant.settings.tax.incomeCode) {
>>>>          case TaxIncomeCode.RENTS_14:
>>>>            category = PaymentCategory.RENT;
>>>>            break;
>>>>          case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>>            category = PaymentCategory.SERVICES;
>>>>            break;
>>>>          case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>>            category = PaymentCategory.SERVICES;
>>>>            break;
>>>>        }
>>>>      }
>>>>
>>>> I also bumped into a block of go code that also implemented similar
>>>> patterns, which really demonstrated to me that there while you could go
>>>> crazy with triary nesting there should be a better way.  Looked at the
>>>> pattern matching proposal and while could possibly help looked like it
>>>> was overkill for the typical use case that I'm seeing. The most relevant
>>>> example I noted was switch expressions from Java.  When applied to this
>>>> problem really create a simple result:
>>>>
>>>>      const category = data.category || switch (setting.incomeCode) {
>>>>        case TaxIncomeCode.RENTS_14 => PaymentCategory.RENT;
>>>>        case TaxIncomeCode.ROYALTIES_COPYRIGHTS_12 =>
>>>> PaymentCategory.ROYALTIES;
>>>>        case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17 =>
>>>> PaymentCategory.SERVICES;
>>>>        default => PaymentCategory.OTHER;
>>>>      }
>>>>
>>>> Note; the instead of using the '->' as Java, continue to use => and with
>>>> the understanding that the right hand side is fundamentally function.
>>>> So similar things to this are natural, note this proposal should remove
>>>> "fall through" breaks and allow for multiple cases as such.
>>>>
>>>>      const quarter = switch (foo) {
>>>>        case "Jan", "Feb", "Mar" => "Q1";
>>>>        case "Apr", "May", "Jun" => "Q2";
>>>>        case "Jul", "Aug", "Sep" => "Q3";
>>>>        case "Oct", "Nov", "Dec" => { return "Q4" };
>>>>        default => { throw new Error("Invalid Month") };
>>>>      }
>>>>
>>>> Also compared this to the do expression proposal, it also provides a
>>>> substantial simplification, but in a way that is more consistent with
>>>> the existing language.  In one of their examples they provide an example
>>>> of the Redux reducer
>>>> https://redux.js.org/basics/reducers#splitting-reducers -- this would be
>>>> a switch expression implementation.
>>>>
>>>>      function todoApp(state = initialState, action) => switch
>>>> (action.type) {
>>>>        case SET_VISIBILITY_FILTER => { ...state, visibilityFilter:
>>>> action.filter };
>>>>        case ADD_TODO => {
>>>>            ...state, todos: [
>>>>              ...state.todos,
>>>>              {
>>>>                text: action.text,
>>>>                completed: false
>>>>              }
>>>>            ]
>>>>          };
>>>>        case TOGGLE_TODO => {
>>>>            ...state,
>>>>            todos: state.todos.map((todo, index) => (index ===
>>>> action.index) ? { ...todo, completed: !todo.completed } : todo)
>>>>          };
>>>>        default => state;
>>>>      }
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> [email protected]
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [email protected]
>>> https://mail.mozilla.org/listinfo/es-discuss
>
> On 2/25/19 3:42 PM, David Koblas wrote:
>
> Jordan,
>
> One question that I have lingering from pattern matching is why is the syntax 
> so different?  IMHO it is still a switch statement with a variation of the 
> match on the case rather than a whole new construct.
>
> Is there somewhere I can find a bit of discussion about the history of the 
> syntax decisions?
>
> --David
>
>
> On Feb 25, 2019, at 12:33 PM, Jordan Harband <[email protected]> wrote:
>
> Additionally, https://github.com/tc39/proposal-pattern-matching - switch 
> statements are something I hope we'll soon be able to relegate to the dustbin 
> of history.
>
> On Mon, Feb 25, 2019 at 6:01 AM David Koblas <[email protected]> wrote:
>>
>> I quite aware that it’s covered in do expressions. Personally I find do 
>> expressions non-JavaScript in style and it’s also not necessarily going to 
>> make it into the language.
>>
>> Hence why I wanted to put out there the idea of switch expressions.
>>
>> --David
>>
>>
>> On Feb 25, 2019, at 5:28 AM, N. Oxer <[email protected]> wrote:
>>
>> Hi,
>>
>> This would be covered by do expressions. You could just do:
>>
>> ```js
>> const category = do {
>>   switch (...) {
>>     ...
>>   };
>> };
>> ```
>>
>> On Sun, Feb 24, 2019 at 10:42 AM David Koblas <[email protected]> wrote:
>>>
>>> After looking at a bunch of code in our system noted that there are many
>>> cases where our code base has a pattern similar to this:
>>>
>>>      let category = data.category;
>>>
>>>      if (category === undefined) {
>>>        // Even if Tax is not enabled, we have defaults for incomeCode
>>>        switch (session.merchant.settings.tax.incomeCode) {
>>>          case TaxIncomeCode.RENTS_14:
>>>            category = PaymentCategory.RENT;
>>>            break;
>>>          case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>            category = PaymentCategory.SERVICES;
>>>            break;
>>>          case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
>>>            category = PaymentCategory.SERVICES;
>>>            break;
>>>        }
>>>      }
>>>
>>> I also bumped into a block of go code that also implemented similar
>>> patterns, which really demonstrated to me that there while you could go
>>> crazy with triary nesting there should be a better way.  Looked at the
>>> pattern matching proposal and while could possibly help looked like it
>>> was overkill for the typical use case that I'm seeing. The most relevant
>>> example I noted was switch expressions from Java.  When applied to this
>>> problem really create a simple result:
>>>
>>>      const category = data.category || switch (setting.incomeCode) {
>>>        case TaxIncomeCode.RENTS_14 => PaymentCategory.RENT;
>>>        case TaxIncomeCode.ROYALTIES_COPYRIGHTS_12 =>
>>> PaymentCategory.ROYALTIES;
>>>        case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17 =>
>>> PaymentCategory.SERVICES;
>>>        default => PaymentCategory.OTHER;
>>>      }
>>>
>>> Note; the instead of using the '->' as Java, continue to use => and with
>>> the understanding that the right hand side is fundamentally function.
>>> So similar things to this are natural, note this proposal should remove
>>> "fall through" breaks and allow for multiple cases as such.
>>>
>>>      const quarter = switch (foo) {
>>>        case "Jan", "Feb", "Mar" => "Q1";
>>>        case "Apr", "May", "Jun" => "Q2";
>>>        case "Jul", "Aug", "Sep" => "Q3";
>>>        case "Oct", "Nov", "Dec" => { return "Q4" };
>>>        default => { throw new Error("Invalid Month") };
>>>      }
>>>
>>> Also compared this to the do expression proposal, it also provides a
>>> substantial simplification, but in a way that is more consistent with
>>> the existing language.  In one of their examples they provide an example
>>> of the Redux reducer
>>> https://redux.js.org/basics/reducers#splitting-reducers -- this would be
>>> a switch expression implementation.
>>>
>>>      function todoApp(state = initialState, action) => switch
>>> (action.type) {
>>>        case SET_VISIBILITY_FILTER => { ...state, visibilityFilter:
>>> action.filter };
>>>        case ADD_TODO => {
>>>            ...state, todos: [
>>>              ...state.todos,
>>>              {
>>>                text: action.text,
>>>                completed: false
>>>              }
>>>            ]
>>>          };
>>>        case TOGGLE_TODO => {
>>>            ...state,
>>>            todos: state.todos.map((todo, index) => (index ===
>>> action.index) ? { ...todo, completed: !todo.completed } : todo)
>>>          };
>>>        default => state;
>>>      }
>>>
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [email protected]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> _______________________________________________
>> es-discuss mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
>
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to