T.J. Crowder (2017-02-01T18:22:38.000Z)
tj.crowder at farsightsoftware.com (2017-02-01T18:25:24.186Z)
The chief advantage I see to doing this with syntax is short-circuiting. Otherwise, you could use a helper function to achieve `if (valueIn(object.property.secondProp, 'a', 'b'))` quite readily. Short-circuiting makes this interesting, though I worry about it pulling its syntactic weight. If the mechanism did short-circuiting (lazy evaluation), then this (using your syntax for now)... ```js if (object.property.secondProp === (foo() : bar())) { // do something } ``` ...wouldn't call `bar` if the property's value matches the return value of `foo` (just like `x === foo() || x === bar()` wouldn't). That being the case, the syntax would have to be visually distinct from an array (as yours is) to avoid confusion, while still supporting arbitrary expressions and, ideally, spread syntax. I notice that you've used a relational operator (strict equality, in this case) and then special syntax following it, rather than (say) `if (x anyof ('a', 'b'))`. Is it your intention that other operators would work with it too? `if (x > (a : b : c))`? (Rather than `if (x > a || x > b || x > c)` or `if (x > Math.min.call(Math, a, b, c))`.) Also, you've used `||` in your example. What about `&&`? Suppose I want to make sure that `x` is greater than all three values in `a`, `b`, and `c`? I wonder if we could keep the syntax general enough to handle both cases. On syntax: I'm with Ryan about not being keen on the `(x : y : z)` syntax. Also, given that the values could be arbitrary expressions nested arbitrarily deep, it seems like the `:` after the first value is a bit late to be telling the parser what's going on. I wonder if we could do it earlier. (Also, `:` isn't a natural list delimiter to my mind...) Hmmm, taking the `||` vs. `&&` into it, one idea would be to put the logical operator immediately (other than whitespace) following the opening paren: ```js if (x === (|| 'a', 'b')) { ``` Equivalent to (but x is only evaluated once): ```js if (x === 'a' || x === 'b') ``` and ```js if (x > (&& foo(), bar())) { ``` Equivalent to (but x is only evaluated once): ```js if (x > foo() && x > bar()) ``` (Starts feeling a bit like Lisp.) I can't help but think: At a high level, operators are just functions with special syntax, multiple dispatch, and lazy operand evaluation. Setting aside the multi-dispatch aspect, what if we...had a way to lazily evaluate function arguments? It sounds simple, but it gets complicated *fast* for situations like this where the argument list varies in length. But potentially quite powerful, and plays into [operator overloading](https://esdiscuss.org/topic/operator-overloading-proposal) should that happen... -- T.J.
tj.crowder at farsightsoftware.com (2017-02-01T18:24:36.347Z)
The chief advantage I see to doing this with syntax is short-circuiting. Otherwise, you could use a helper function to achieve `if (valueIn(object.property.secondProp, 'a', 'b'))` quite readily. Short-circuiting makes this interesting, though I worry about it pulling its syntactic weight. If the mechanism did short-circuiting (lazy evaluation), then this (using your syntax for now)... ```js if (object.property.secondProp === (foo() : bar())) { // do something } ``` ...wouldn't call `bar` if the property's value matches the return value of `foo` (just like `x === foo() || x === bar()` wouldn't). That being the case, the syntax would have to be visually distinct from an array (as yours is) to avoid confusion, while still supporting arbitrary expressions and, ideally, spread syntax. I notice that you've used a relational operator (strict equality, in this case) and then special syntax following it, rather than (say) `if (x anyof ('a', 'b'))`. Is it your intention that other operators would work with it too? `if (x > (a : b : c))`? (Rather than `if (x > a || x > b || x > c)` or `if (x > Math.min.call(Math, a, b, c))`.) Also, you've used `||` in your example. What about `&&`? Suppose I want to make sure that `x` is greater than all three values in `a`, `b`, and `c`? I wonder if we could keep the syntax general enough to handle both cases. On syntax: I'm with Ryan about not being keen on the `(x : y : z)` syntax. Also, given that the values could be arbitrary expressions nested arbitrarily deep, it seems like the `:` after the first value is a bit late to be telling the parser what's going on. I wonder if we could do it earlier. (Also, `:` isn't a natural list delimiter to my mind...) Hmmm, taking the `||` vs. `&&` into it, one idea would be to put the logical operator immediately (other than whitespace) following the opening paren: ```js if (x === (|| 'a', 'b')) { ``` Equivalent to (but x is only evaluated once): ```js if (x === 'a' || x === 'b') ``` and ```js if (x > (&& foo(), bar())) { ``` Equivalent to (but x is only evaluated once): ```js if (x > foo() && x > bar()) ``` (Starts feeling a bit like Lisp.) I can't help but think: At a high level, operators are just functions with special syntax, multiple dispatch, and lazy operand evaluation. Setting aside the multi-dispatch aspect, what if we...had a way to lazily evaluate function arguments? It sounds simple, but it gets complicated *fast* for situations like this where the argument list varies in length. But potentially quite powerful, and plays into [operator overloading](https://esdiscuss.org/topic/operator-overloading-proposal) should that happen... -- T.J.