I guess we have a different opinion about what's confusing and what's not. To me having a `??` with potential side-effects is more bug prone than the proposed mouse trap, as it's subtle, yet "promoted" by the `?.` + `??` pattern.
On Mon, Sep 9, 2019 at 11:16 AM Naveen Chawla <[email protected]> wrote: > "resultsContainerOrSingleResult" appears to be the end variable. I just > find this "shoehorning" to be a sacrifice in code clarity and > manageability. "rowCount" would be undefined if greater than 0 in the 2nd > example, it seems. Surely that is a confusing behaviour, if not bug prone > > On Mon, 9 Sep 2019, 09:17 Andrea Giammarchi, <[email protected]> > wrote: > >> so *maybe* we'll come back... >> >> On Mon, Sep 9, 2019 at 10:04 AM Andrea Giammarchi < >> [email protected]> wrote: >> >>> `require("module")<?.default` is the easiest use case for this, as >>> initially explained. >>> >>> `db.get(SQL)<?.rows?.[0]` the most common use case, for queries you know >>> that won't fail but might not return the desired result, so that you end up >>> holding the top most object with all the informations, instead of simply >>> ending up with undefined. This works well with destructuring too. >>> >>> ```js >>> const {rowsCount, id, name, email} = db.get(SQL)<?.rows?.[0]; >>> if (rowCounts === 0) >>> askUserToRegister(); >>> else >>> showUserDetails(); >>> ``` >>> >>> As mentioned, there is a module that let you explicitly use this >>> operator through a callback that tries to be as safe as it can (void after >>> first `.trap` access + self clean on next microtask), so manye we'll come >>> back to this discussion once we all understand the use case and why it's >>> actually very useful in some circumstance. >>> >>> Regards >>> >>> >>> >>> On Sat, Sep 7, 2019 at 1:23 PM Naveen Chawla <[email protected]> >>> wrote: >>> >>>> There has to be a better pattern than returning the "foo()" if the baz >>>> property doesn't exist. >>>> >>>> I'm curious what you would want to do with the resulting "foo()" >>>> anyway. I can imagine a flow where I want "bar", and it doesn't exist it >>>> doesn't. I cannot imagine wanting the "foo()" in place of it. There is type >>>> unpredictability in the result, so subsequent operations would normally >>>> expected to be impossible without type-branching. Hence my question to you >>>> about what you would typically want to do with the "foo()" if that was the >>>> returned result. >>>> >>>> On Sat, 7 Sep 2019 at 12:08, Andrea Giammarchi < >>>> [email protected]> wrote: >>>> >>>>> 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 >>>>> >>>>
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

