Naveen,

Thanks for your observation.  The example that I gave might have been too simplistic, here's a more complete example:

```

switch (animal) { case Animal.DOG, Animal.CAT => { // larger block expression // which spans multiple lines return "dry food"; } case Animal.TIGER, Animal.LION, Animal.CHEETA => { // larger block expression // which spans multiple lines return "fresh meat"; } case Animal.ELEPHANT => "hay"; default => { throw new Error("Unsupported Animal"); }; }

```

While you give examples that would totally work.  Things that bother me about the approach are, when taken to something more complex than a quick value for value switch you end up with something that looks like this.

```

    function houseAnimal() {        // larger block expression        // which spans multiple lines        return "dry food";    }    function wildCatFood() {      // larger block expression      // which spans multiple lines      return "fresh meat";    }    const cases = {      [Animal.DOG]: houseAnimal,      [Animal.CAT]: houseAnimal,      [Animal.LION]: wildCatFood,      [Animal.TIGER]: wildCatFood,      [Animal.CHEETA]: wildCatFood,    }    const food = cases[animal] ? cases[animal]() : (() => {throw new Error("Unsuppored Animal")})();

```

As we all know once any language reaches a basic level of functionality anything is possible.  What I think is that JavaScript would benefit by having a cleaner approach.

On 2/28/19 4:37 AM, Naveen Chawla wrote:
Isn't the best existing pattern an object literal?

const
    cases =
        {
             foo: ()=>1,
             bar: ()=>3,
             baz: ()=>6
        }
    ,
    x =
        cases[v] ?
            cases[v]() :
            99
;

What does any proposal have that is better than this? With optional chaining feature:

const
    x =
        {
             foo: ()=>1,
             bar: ()=>3,
             baz: ()=>6
        }[v]?.()
        ||
        99
;

Do let me know your thoughts guys


On Thu, 28 Feb 2019 at 06:04 kai zhu <kaizhu...@gmail.com <mailto:kaizhu...@gmail.com>> wrote:

    This is unmaintainable --

        const x = v === 'foo' ? 1 : v === 'bar' ? 3 : v === 'baz' ? 6
    : 99;

    i feel proposed switch-expressions are no more
    readable/maintainable than ternary-operators, if you follow
    jslint's style-guide.  i'll like to see more convincing
    evidence/use-case that they are better:

    ```javascript
    /*jslint*/
    "use strict";
    const v = "foo";
    const x = (
        v === "foo"
        ? 1
        : v === "bar"
        ? 3
        : v === "baz"
        ? 6
        : 99
    );
    ```

    here's another example from real-world production-code, where
    switch-expressions probably wouldn't help:

    ```javascript
    $ node -e '
    /*jslint devel*/
    "use strict";
    function renderRecent(date) {
    /*
     * this function will render <date> to "xxx ago"
     */
      date = Math.ceil((Date.now() - new Date(date).getTime()) *
    0.0001) * 10;
      return (
          !Number.isFinite(date)
          ? ""
          : date < 60
          ? date + " sec ago"
          : date < 3600
          ? Math.round(date / 60) + " min ago"
          : date < 86400
          ? Math.round(date / 3600) + " hr ago"
          : date < 129600
          ? "1 day ago"
          : Math.round(date / 86400) + " days ago"
      );
    }

    console.log(renderRecent(new Date().toISOString())); // "0 sec ago"
    console.log(renderRecent("2019-02-28T05:32:00Z")); // "10 sec ago"
    console.log(renderRecent("2019-02-28T05:27:30Z")); // "5 min ago"
    console.log(renderRecent("2019-02-28T05:14:00Z")); // "18 min ago"
    console.log(renderRecent("2019-02-28T03:27:00Z")); // "2 hr ago"
    console.log(renderRecent("2019-02-12T05:27:00Z")); // "16 days ago"
    console.log(renderRecent("2018-02-28T05:27:00Z")); // "365 days ago"
    '

    0 sec ago
    10 sec ago
    5 min ago
    18 min ago
    2 hr ago
    16 days ago
    365 days ago

    $
    ```

    On 27 Feb 2019, at 13:12, David Koblas <da...@koblas.com
    <mailto:da...@koblas.com>> wrote:

    Just for folks who might be interested, added a babel-plugin to
    see what was involved in making this possible.

    Pull request available here --
    https://github.com/babel/babel/pull/9604

    I'm sure I'm missing a bunch of details, but would be interested
    in some help in making this a bit more real.

    Thanks

    On 2/26/19 2:40 PM, Isiah Meadows wrote:
    You're not alone in wanting pattern matching to be expression-based:

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

    -----

    Isiah Meadows
    cont...@isiahmeadows.com <mailto:cont...@isiahmeadows.com>
    www.isiahmeadows.com <http://www.isiahmeadows.com>

    -----

    Isiah Meadows
    cont...@isiahmeadows.com <mailto:cont...@isiahmeadows.com>
    www.isiahmeadows.com <http://www.isiahmeadows.com>


    On Tue, Feb 26, 2019 at 1:34 PM David Koblas <da...@koblas.com
    <mailto:da...@koblas.com>> 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 <da...@koblas.com
    <mailto:da...@koblas.com>> 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 <ljh...@gmail.com
    <mailto:ljh...@gmail.com>> 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 <da...@koblas.com
    <mailto:da...@koblas.com>> 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 <bluesh...@gmail.com
    <mailto:bluesh...@gmail.com>> 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
    <da...@koblas.com <mailto:da...@koblas.com>> 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
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss
    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    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 <ljh...@gmail.com
    <mailto:ljh...@gmail.com>> 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 <da...@koblas.com
    <mailto:da...@koblas.com>> 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 <bluesh...@gmail.com
    <mailto:bluesh...@gmail.com>> 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
    <da...@koblas.com <mailto:da...@koblas.com>> 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
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss
    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss

    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss

    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss
    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss

    _______________________________________________
    es-discuss mailing list
    es-discuss@mozilla.org <mailto:es-discuss@mozilla.org>
    https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to