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

