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

Reply via email to