Interesting I forgot about that, but it wouldn't cover the "trap here" use case.
foo().bar ?! what => what : what; I'd like to forward foo() here On Sat, Sep 7, 2019, 11:45 Michael Luder-Rosefield <[email protected]> wrote: > This is getting very reminiscent of my 'forwarding ternary' operator (or > whatever I called it) I suggested a couple of years ago. I believe you were > involved in the discussion, Andrea...! > > ``` > const val = foo() ?! > (x) => x.bar.baz : > someFallbackValue; > ``` > > On Sat, 7 Sep 2019, 10:17 Andrea Giammarchi, <[email protected]> > wrote: > >> To better answer, let's start dropping any direct access and put a >> payload in the mix. >> >> As example, in the `foo()?.bar.baz` case, you might end up having `null` >> or `undefined`, as result, because `foo().bar` existed, but `bar.baz` >> didn't. >> >> In the `foo()?.bar?.baz` case, you might end up having `foo().bar`, >> because `bar.baz` didn't exist. >> >> But what if you are not interested in the whole chain, but only in a main >> specific point in such chain? In that case you would have `foo()?.bar.baz >> ?? foo()`, but you wouldn't know how to obtain that via `foo()?.bar?.baz ?? >> foo()`, because the latest one might result into `foo().bar`. >> >> Moreover, in both cases you'll end up multiplying the payload at least * >> 2, while the mouse trap will work like this: >> >> ```js >> foo()<?.bar?.baz >> ``` >> >> if either `foo().bar` or `bar.baz` don't exist, the returned result is >> `foo()`, and it's computed once. You don't care about `foo().bar` if >> `bar.baz` is not there, 'cause you want to retrieve `foo()` whenever you >> have a failure down the chain. >> >> Specially with DB operations, this is a very common case (abstraction >> layers all have somehow different nested objects with various info) and the >> specific info you want to know is usually attached at the top level bject, >> while crawling its sub properties either leads to the expected result or >> you're left clueless about the result, 'cause all info got lost in the >> chain. >> >> The `foo()<?.bar.baz` case is a bit different though, 'cause if >> `foo().bar` existed, there's no way to expect `foo()` as result, and if >> it's `bar` that you're after you can write instead `foo()?.bar<?.baz` so >> that if `baz` is not there, `bar` it is. >> >> This short-circuit the need for `??` in most cases, 'cause you already >> point at the desired result in the chain in case the result would be `null` >> or `undefined`. >> >> However, `??` itself doesn't provide any ability to reach any point in >> the previous chain that failed, so that once again, you find yourself >> crawling such chain as fallback, resulting potentially in multiple chains >> and repeated payloads. >> >> ```js >> // nested chains >> foo()?.bar.baz?.biz ?? foo()?.bar.baz ?? foo()?.bar; >> >> // mouse trap >> foo()?.bar<?.baz?.biz; >> ``` >> >> Above example would prefer `foo().bar` if it exists, and if either >> `bar.baz` or `bar.baz.biz` returned `null` or `undefined`. >> >> I hope this clarifies further the intent, or the simplification, that >> such operator offers: it's a complementary hint for any optional chain, it >> doesn't have to be used, but when it does, it's visually semantic in its >> intent (at least to my eyes). >> >> Regards >> >> >> >> >> On Fri, Sep 6, 2019 at 11:20 PM Tab Atkins Jr. <[email protected]> >> wrote: >> >>> On Fri, Sep 6, 2019 at 8:04 AM Andrea Giammarchi >>> <[email protected]> wrote: >>> > Indeed I'm not super convinced myself about the "branching issue" >>> 'cause `const result = this?.is?.branching?.already` and all I am proposing >>> is to hint the syntax where to stop in case something else fails down the >>> line, as in `const result = this.?.is<?.branching?.too` to know that if any >>> other part is not reached, there is a certain point to keep going (which >>> is, example, checking that `result !== this`) >>> >>> Important distinction there is that ?. only "branches" between the >>> intended type and undefined, not between two arbitrary types. The >>> cognitive load between those two is significantly different. >>> >>> In particular, you can't *do* anything with undefined, so >>> `foo?.bar.baz` has pretty unambiguous semantics - you don't think you >>> might be accessing the .baz property of undefined, because that >>> clearly doesn't exist. >>> >>> That's not the case with mouse, where it's not clear, at least to me, >>> whether `foo<?.bar.baz` is doing `(foo.bar ? foo.bar : foo).baz` or >>> `foo.bar.baz ? foo.bar.baz : foo` or even `foo.bar ? foo.bar.baz : >>> foo`. All three seem at least somewhat reasonable, and definitely >>> *believable* as an interpretation! >>> >>> ~TJ >>> >> _______________________________________________ >> 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

