"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

