Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interaction with optional chaining #35

Closed
phaux opened this issue Jul 23, 2019 · 3 comments
Closed

Interaction with optional chaining #35

phaux opened this issue Jul 23, 2019 · 3 comments

Comments

@phaux
Copy link

phaux commented Jul 23, 2019

Since optional chaining is reaching stage-3, I thought it would be worth discussing how that syntax interacts with partial application. Currently it's a syntax error in babel AFAIK.

Example:

const fn = foo?.(x, ?)

Option 1

fn is a function which either does nothing if foo was nullish or in other case works normally. This would be equivalent to:

const fn = $ => foo != null ? foo(x, $) : undefined

The question is if it should also work like that with foo?.bar(?) (maybe) and foo?.bar.baz(?) (probably not)

Option 2

fn is undefined if foo was nullish. Equivalent to:

const fn = foo != null ? ($ => foo(x, $)) : undefined

It would work the same way no matter how deep in the chain which is less surprising. E.g. foo?.bar.baz(?) would be undefined if foo was nullish. We can then use the resulting maybe-function like fn?.(x).

Motivating example

Supporting this syntax would be beneficial in some situations.

const ItemList = props => (
  <ul>
    {props.items.map(item => (
      // onItemClick is optional prop and we want pass the event as second arg
      <li onClick={props.onItemClick?.(item.id, ?)}>
        {item.title}
      </li>
    ))}
  </ul>
)

This example would work pretty much the same way with both options.

@phaux
Copy link
Author

phaux commented Mar 26, 2020

Looks like babel implements option 2.

@nicolo-ribaudo
Copy link
Member

Looks like babel implements option 2.

Note that this is not intended. Probably it would be better to throw an error until it's decided.

@rbuckton
Copy link
Collaborator

rbuckton commented Apr 9, 2020

In general I would expect foo?.bar(?) to return undefined if foo is null/undefined, rather than deferring evaluation. The reason is that partial application eagerly evaluates non-placeholder arguments, i.e., foo.bar(++i, ?) would eagerly evaluate the pre-increment ++i. However, arguments in an optional chain are not evaluated if the root of the chain is null/undefined, i.e., foo?.bar(++i, x) would not evaluate the pre-increment ++i.

The only option to remain consistent would be Option 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants