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

yield / await #53

Closed
Volune opened this issue Aug 26, 2017 · 19 comments
Closed

yield / await #53

Volune opened this issue Aug 26, 2017 · 19 comments

Comments

@Volune
Copy link

Volune commented Aug 26, 2017

For checking, since all information I found in other issues are more than 18 months old, about the yield and await keywords:

The following functions:

function* g() {
"input" |> yield foo |> bar;
}
async function a() {
  "input" |> await foo |> bar;
}

Would be equivalent to:

function* g() {
  const input = "input";
  const f = yield foo;
  bar( f( input ) );
}
async function a() {
  const input = "input";
  const f = await foo;
  bar( f( input ) );
}

And there would be no easy way to do the following using the pipeline operator:

function* g() {
  bar(yield foo("input"));
}
async function a() {
  bar(await foo("input"));
}
@lukeed
Copy link

lukeed commented Aug 26, 2017

It should already expand to the last code block.

@Volune
Copy link
Author

Volune commented Aug 28, 2017

It should already expand to the last code block.

Can you point me where in the proposal this is defined?
It seems to me that the await would take precedence over |>, and a |> await b would be interpreted as a |> (await b)

@gilbert
Copy link
Collaborator

gilbert commented Aug 28, 2017

I think you would need parenthesis to achieve what you want. If written this way...

a |> yield b |> c

...then it would be interpreted as a |> (yield b |> c), since b |> c is the expression of yield.

However with explicit parenthesis I think it could work:

a |> (yield b) |> c

The problems is that this solution becomes less apparent when broken up by newlines:

input
  |> yield b //<-- Needs parens!
  |> f

@Volune
Copy link
Author

Volune commented Aug 29, 2017

Wow thanks, that's even less intuitive that what I expected.

So my first example would be

function* g() {
  const f = yield (bar(foo));
  f("input");
}
async function a() {
  const f = await (bar(foo));
  f("input");
}

And the example in #31 would absolutely not behave as expected.

I assume we could rely on linters to discourage the use of yield/await with |>, is there something that can be improved in the proposal?

@gilbert
Copy link
Collaborator

gilbert commented Aug 29, 2017

I should make clear my comment is just a guess. I don't know how to read proposal grammars, so I can't verify if a spec like #51 behaves this way or not.

@littledan
Copy link
Member

The spec in #51 puts |> at a higher precedence than yield but lower than await.

@azz
Copy link

azz commented Sep 30, 2017

const addOne = (x) => Promise.resolve(x + 1);
const double = (x) => Promise.resolve(x * 2);

(async () => {
  const foo = await (1
    |> async x => await addOne(x)
    |> async x => await double(x)
  );
  
  console.log(foo); // 4
})();

This works (repl) but it leaves a bit to be desired. Sounds like we'd need additional syntax to clean it up.

Something like this could be nice:

const foo = await (1
  |> await with addOne
  |> await with double
);

// loosely

Promise.resolve(1)
  .then(addOne)
  .then(double)
  .then(foo => {})

@azz
Copy link

azz commented Sep 30, 2017

Potentially partial application with await? Has this been discussed elsewhere?

const foo = await (1
  |> addOne(await?)
  |> double(await?)
);

@littledan
Copy link
Member

@azz interesting idea. But it's a bit complicated, as I'm not sure what happens with that function as a value. How can it block? I think we'd need something which is not a rectified function.

To clarify, in the current spec text, even if you put in parens, yield and await won't do what you expect--they would refer to the function, not what was passed in. You just have to break out of the pipeline chain for now.

@gilbert
Copy link
Collaborator

gilbert commented Sep 30, 2017

If await were to be accommodated in the spec, the simplest solution might be to require it on its own pipeline:

const foo = 1
  |> addOne
  |> await
  |> double
  |> await;

// or...

const foo = 1
  |> addOne |> await
  |> double |> await;

A bit annoying, but it would work.

@TheNavigateur
Copy link
Contributor

TheNavigateur commented Oct 15, 2017

Why not allow x |> await f to be parsed the same way as await f(x) (as I also mentioned here: #64 (comment))

And the same for yield?

I would think this is the most natural use of those keywords from within a |> function pipeline...

@gilbert
Copy link
Collaborator

gilbert commented Oct 15, 2017

I agree it would be better, I just don't know how complicated it would make the proposal.

@azz
Copy link

azz commented Oct 15, 2017

What if f is a promise resolving to a function?

let double = Promise.resolve(x => x + x);

await (1 |> await double); // 2

@TheNavigateur
Copy link
Contributor

TheNavigateur commented Oct 15, 2017

That should be invalid. Pipeline operator should only allow |> anyFunction or |> await anyFunction or |> yield anyFunction or |> yield await anyFunction, not |> await promise. The error would be e.g. promise is not a function. The same as if you tried to do await double(1) (where double is a promise)

@azz
Copy link

azz commented Oct 15, 2017

Oh, my intuition was it was any expression, i.e.:

1 |> await double; 

would be

(await double)(1);

@TheNavigateur
Copy link
Contributor

The expression after a |> (except await and yield) must be a function. That's my understanding (otherwise how can you pass an argument to a non-function?)

@TheNavigateur
Copy link
Contributor

@azz Seems like a complicated way of just doing x=>x+x as a function. I think just accepting functions is probably fine.

@TheNavigateur
Copy link
Contributor

I've created a pull request for x |> await f here: #66 for review

@Volune
Copy link
Author

Volune commented Nov 10, 2017

I guess we can close this, now everything is answered in #66

@Volune Volune closed this as completed Nov 10, 2017
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 24, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants