gotta admit an `if (let y = fn())` would be a very nice feature to have. Only the `for(...)` lets us declare block variables, the `let` expression would solve/simplify this case and many others.
```js const newFoo = (let x = getSomething()) ? (doSomethingFirst(), x.doSomething()) : doSomethingElse(); ``` On Wed, Sep 20, 2017 at 10:41 AM, Isiah Meadows <[email protected]> wrote: > I'll just note that the only two languages I know of with a feature like > this is Haskell with its `maybe fn orElse m`* function in `Data.Maybe` and > Scala's `Option[T].mapOrElse(fn, orElse)`. Here's what many other languages > do: > > Several languages use some form of `if let`, including Rust, Scala, and > Swift: > > ```swift > // In Swift > let newFoo > if let x = getSomething() { > doSomethingFirst() > newFoo = x.doSomething() > } else { > newFoo = doSomethingElse() > } > ``` > > Clojure offers the macro `(if-let)`, which does mostly the same thing > (Common Lisp has a similar macro): > > ```clj > ;; Top-level declaration > (def new-foo > (if-let x (get-something) > (do > (do-something-first) > (do-something x)) > :else (do-something-else))) > ``` > > OCaml uses pattern matching, and C/C++, most of its derivatives (like > Python), and Kotlin just do `if (x != NULL) ... else ...` or similar. > (Kotlin has flow-sensitive typing like TypeScript, which helps avoid > mistakes.) > > * I might have gotten the argument order wrong - I'm not a regular Haskell > user, and it's not commonly used. > > On Tue, Sep 19, 2017, 09:36 Michael Rosefield <[email protected]> > wrote: > >> We still have to explicitly create a variable (x), either in the do block >> or before that ternary, and the bracket-enclosed comma-separated >> expressions are... not to my taste. >> >> This was always about syntactic sugar and concision, as there are always >> other ways to go about it; as I commented in my reddit post, both operators >> can be done functionally: >> >> const $equivFn = (cond, ifTruthy, otherwise) => cond ? ifTruthy(cond) : >> otherwise(), >> foo = $equivFn(getSomething(), x => doSomething(x), () => >> doSomething()), >> equivFoo = getSomething() ?! x => doSomething(x) : doSomethingElse(); >> >> // normal ternary >> const $ternary = (cond, ifTruthy, otherwise) => cond ? ifTruthy() : >> otherwise(), >> foo = $ternary(checkSomething(), () => doSomething(), () => >> doSomething()), >> equivFoo = checkSomething() ? doSomething() : doSomethingElse(); >> >> >> ... but it's not elegant. >> >> And I appreciate ?! was a bad choice, but can easily be substituted by >> anything else. >> >> On Tue, 19 Sep 2017 at 14:06 Andrea Giammarchi < >> [email protected]> wrote: >> >>> I don't think `do` is "much longer" than your last example, however, it >>> can be shorter >>> >>> ```js >>> const newFoo = do { >>> let x = getSomething(); >>> x ? >>> (doSomethingFirst(), x.doSomething()) : >>> doSomethingElse(); >>> }; >>> >>> On Tue, Sep 19, 2017 at 3:00 PM, Sebastian Malton <[email protected] >>> > wrote: >>> >>>> I don't think that talking about the syntax is relevant now since it is >>>> not important when talking about the reasonability of a suggestion. Saying >>>> that the syntax could be `?|` >>>> >>>> The `do` is much longer than the example. >>>> >>>> I think that this a reasonable idea. >>>> >>>> *From:* [email protected] >>>> *Sent:* September 19, 2017 8:57 AM >>>> *To:* [email protected]; [email protected] >>>> *Subject:* Re: Proposal: result-forwarding ternary operator >>>> >>>> Few issues: >>>> >>>> 1. This is already technically valid code: `cond?!fn:orElse` is >>>> equivalent to `cond ? !fn : orElse` >>>> 2. Have you considered `do` expressions (stage 1 proposal)? They work a >>>> lot like IIFEs, but allow easy definition of computed constants. >>>> 3. Have you considered using in-condition assignment or just factoring >>>> out the computed condition into a separate variable? Sometimes, a little >>>> verbosity helps. >>>> >>>> Using `do` expressions, your second code sample would look like this: >>>> >>>> ```js >>>> const newFoo = do { >>>> let x = getSomething(); >>>> if (x) { >>>> doSomethingFirst(); >>>> x.doSomething(); >>>> } else { >>>> doSomethingElse(); >>>> } >>>> }; >>>> ``` >>>> >>>> On Tue, Sep 19, 2017, 08:33 Michael Rosefield <[email protected]> >>>> wrote: >>>> >>>>> (I've also put this on reddit >>>>> <https://www.reddit.com/r/javascript/comments/7129tn/proposal_resultforwarding_ternary_operator/>, >>>>> which I've copied this from. Hope the formatting doesn't go haywire...) >>>>> >>>>> First course of action for this proposal is, obviously, to >>>>> come up with a better name for it.... >>>>> >>>>> >>>>> Motivation >>>>> >>>>> As with the 'optional chaining' proposal for tc39 >>>>> <https://github.com/tc39/proposal-optional-chaining>, this operator >>>>> is a way to avoid excess and annoying code from safety-checking. >>>>> >>>>> The optional chaining proposal, above, follows a chain and >>>>> short-circuits it upon acting on a null object, returning a safe ' >>>>> *undefined*' result; it can be thought of as an extended '*if*' >>>>> sequence. It looks like this: >>>>> >>>>> // safeVal = result of someProp, or undefined if looking for props on >>>>> null obj >>>>> const safeVal = blah?.someMethod()?.someProp; >>>>> >>>>> This proposal provides for an '*else'* scenario, particularly in >>>>> situations where chaining isn't appropriate, by forwarding the result of a >>>>> truthy conditional check to a single-parameter function. >>>>> >>>>> >>>>> Syntax >>>>> >>>>> *condition ?! fn : expr* >>>>> >>>>> Parameters >>>>> >>>>> - condition: any condition, *identical to use in standard ternary* >>>>> - fn: function taking single parameter, which is the result of >>>>> evaluating *condition* >>>>> - expr: any expression, *identical to use in standard ternary* >>>>> >>>>> >>>>> Usage Example >>>>> >>>>> // temporary variable >>>>> const temp = getSomething(), >>>>> foo = temp ? doSomething(temp) : doSomethingElse(); >>>>> >>>>> // repeated code, possible side-effects >>>>> const foo2 = getSomething() ? doSomething(getSomething()) : >>>>> doSomethingElse(); >>>>> >>>>> // proposal, no chaining >>>>> const newFoo = getSomething() ?! x => doSomething(x) : doSomethingElse(); >>>>> >>>>> // proposal, chaining >>>>> const newFoo = getSomething() ?! >>>>> x => { >>>>> doSomethingFirst(); >>>>> return x.doSomething(); >>>>> } : >>>>> doSomethingElse(); >>>>> >>>>> >>>>> Notes >>>>> >>>>> - >>>>> >>>>> The choice of '?!' is entirely arbitrary and not a core part of >>>>> the proposal. >>>>> - >>>>> >>>>> The result of the conditional check is not passed on to the falsey >>>>> path, because it seems pointless to do so. >>>>> >>>>> _______________________________________________ >>>>> 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

