`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 <naveen.c...@gmail.com> 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 <
> andrea.giammar...@gmail.com> 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 <
>> rosyatran...@gmail.com> 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, <
>>> andrea.giammar...@gmail.com> 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. <jackalm...@gmail.com>
>>>> wrote:
>>>>
>>>>> On Fri, Sep 6, 2019 at 8:04 AM Andrea Giammarchi
>>>>> <andrea.giammar...@gmail.com> 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
>>>> es-discuss@mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to