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

Add support for bidirectional effects #29

Merged
merged 18 commits into from
Nov 16, 2020

Conversation

long-long-float
Copy link
Member

@long-long-float long-long-float commented Oct 15, 2020

This PR adds the feature of bidirectional control flow to the Effekt language. The feature is inspired by the paper

"Handling bidirectional control flow".
Yizhou Zhang, Guido Salvaneschi, and Andrew C. Myers. OOPSLA'20 (PDF).

@long-long-float
Copy link
Member Author

I'll rebase to solve conflicts.

@long-long-float long-long-float force-pushed the bidirectional branch 2 times, most recently from 71ab306 to 5a77660 Compare October 15, 2020 07:59
@long-long-float long-long-float changed the title Supports Bidirectional-effect WIP: Supports Bidirectional-effect Oct 15, 2020
@long-long-float long-long-float changed the title WIP: Supports Bidirectional-effect Supports Bidirectional-effect Oct 15, 2020
@b-studios
Copy link
Collaborator

Could you maybe add a couple of example files with expected output check files to the examples/pos directory?

Copy link
Collaborator

@b-studios b-studios left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks already pretty good to me. I added a few suggested changes that would be great if you could incorporate them. As already mentioned, it would also be great to have a few examples that illustrate the new feature.

In the changes I propose to reject programs where resume is used in the wrong way. I think that is easiest for now. If you would like to stick with the automatic adaption to the correct kind, I think we need another, consistent way that actually changes the terms.

shared/src/main/scala/effekt/Parser.scala Outdated Show resolved Hide resolved
shared/src/main/scala/effekt/Namer.scala Outdated Show resolved Hide resolved
shared/src/main/scala/effekt/Typer.scala Outdated Show resolved Hide resolved
shared/src/main/scala/effekt/Typer.scala Outdated Show resolved Hide resolved
shared/src/main/scala/effekt/core/Transformer.scala Outdated Show resolved Hide resolved
lib/effekt_runtime.js Outdated Show resolved Hide resolved
lib/effekt_runtime.js Outdated Show resolved Hide resolved
lib/effekt_runtime.js Outdated Show resolved Hide resolved
@long-long-float
Copy link
Member Author

@b-studios I applied suggested changes and added an example. Please review it.

@b-studios
Copy link
Collaborator

closing and reopening to trigger CI

@b-studios b-studios closed this Oct 30, 2020
@b-studios b-studios reopened this Oct 30, 2020
@b-studios
Copy link
Collaborator

b-studios commented Nov 7, 2020

Thank you @long-long-float for your contributions! As you will see (after fixing my accidental bug missing a brace), there are still a few tests that do not pass and I cannot merge your feature without the CI going through.

The Effekt language has multiple backends and your bidirectionality feature only supports one of them (JavaScript), which is fine. It is expected that your new test fails on all other backends. You can see how the bidirectionality test can be disabled in the other backends here:

lazy val ignored: List[File] = List(
examplesDir / "pos" / "arrays.effekt",
examplesDir / "pos" / "maps.effekt",
// unsafe continuations are not yet supported in our Chez backend
examplesDir / "pos" / "unsafe_cont.effekt",
examplesDir / "pos" / "propagators.effekt",
// the number representations differ in JS and Chez
examplesDir / "casestudies" / "ad.md"
)

(If you are interested, you can of course also consider supporting the other backends -- like Chez Scheme, but this is not strictly necessary for now).

However, all other tests that are not concerned with bidirectionality should still pass. Maybe you can look into this? If you have any questions, I am happy to assist.

@@ -100,7 +100,7 @@ case class VarDef(id: IdDef, annot: Option[ValueType], binding: Stmt) extends De
case class EffDef(id: IdDef, ops: List[Operation]) extends Def {
type symbol = symbols.UserEffect
}
case class Operation(id: Id, tparams: List[Id], params: List[ValueParams], ret: Effectful) extends Definition {
case class Operation(id: IdDef, tparams: List[Id], params: List[ValueParams], ret: Effectful) extends Definition
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh.. I forgot the opening brace here, when editing this in the online editor. @long-long-float could you fix this in your branch?

@long-long-float
Copy link
Member Author

@b-studios The CI fails and says an error [error] examples/neg/existential_effect_leaks.effekt:22:1: Unhandled effects: GiveInt. My modification may effect this. Should I fix this?

@b-studios
Copy link
Collaborator

Yes, it should warn about an effect leaving its scope as you can see in the check file. Would be great if you could look into this

@long-long-float
Copy link
Member Author

@b-studios I fixed the test case of examples/neg/existential_effect_leaks.effekt, but other cases are faild.

[info]   - unbound_type.effekt (lift) *** FAILED *** (145 milliseconds)
[info]     "... pos: Position): A
[info]     ^[^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]
[info]     " did not equal "... pos: Position): A
[info]     ^[]
[info]     " (ChezSchemeTests.scala:62)
[info]     Analysis:
[info]     "... pos: Position): A
[info] ^[^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^]
[info] " -> "... pos: Position): A
[info] ^[]

I Investigated the cause and guess that the position of the type of an operator (ret: Effectful) is not set (but I don't know how to set it.)

@b-studios

This comment has been minimized.

@b-studios

This comment has been minimized.

@b-studios
Copy link
Collaborator

Update: I just modified Namer in master so you only need to rebase. This should hopefully also solve the problem you described here.

@@ -571,7 +579,13 @@ class Typer extends Phase[Module, Module] { typer =>
effs = (effs ++ (stmtEffs -- handled))
}

(params zip args) foreach { case (ps, as) => checkArgumentSection(ps, as) }
(params zip args) foreach {
// Special case - treat 1st param type () => T as T
Copy link
Collaborator

@b-studios b-studios Nov 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could expand a bit on this comment (and maybe add an example to examples/pos?). This part is really the most tricky bit, I believe.

(the detailed explanation is not necessary for merging into master, but would be nice at some point)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reconsidered about it, it is unnecessary. So I removed it.

@b-studios b-studios changed the title Supports Bidirectional-effect Add support for bidirectional effects Nov 15, 2020
@long-long-float
Copy link
Member Author

@b-studios All tests are passed! Thanks for your advice.

@b-studios
Copy link
Collaborator

Thanks for your contributions @long-long-float, which I'll merge now!

If you want, you could add more examples of the feature, potentially translating the examples from the original paper? The paper is presented this week at OOPSLA and having translated their examples could facilitate discussion.

@b-studios b-studios merged commit d5dcbf6 into effekt-lang:master Nov 16, 2020
@long-long-float
Copy link
Member Author

Of course I'm creating more examples for the paper 😄

@b-studios
Copy link
Collaborator

@long-long-float Just to be clear: What I meant is: could you take examples from the existing paper by Zhang er al., translate them to Effekt and add them to this repository?

@long-long-float
Copy link
Member Author

Yes, I'm translating examples from the existing paper by Zhang er al., to Effekt.

  • Generators: I'm translating it.
  • Async-await: I considered that it cannot be because Effekt doesn't have first-class function.
  • Ping and Pong: I translated it as examples/pos/bidirectional.effekt.

@b-studios
Copy link
Collaborator

Hey, thanks! I added a quick translation of the iterator example here to talk about it with people at the OOPLSA conference.

@long-long-float
Copy link
Member Author

Cool! I have just translated the same example here.

@b-studios
Copy link
Collaborator

That's great. Since you are the expert on bidirectional effects in the Effekt language, do you want to document it on the website? We have a separate repository for that. I added a quick stub, but there could be much detailed explanation about what bidirectional effects motivates, how they work and how they interact with effect polymorphism:

https://github.com/effekt-lang/effekt-website/blob/master/docs/bidirectional.md

@long-long-float
Copy link
Member Author

Sure, I want to do. I'll write it with my master thesis.

b-studios added a commit that referenced this pull request Sep 27, 2022
Supersedes and closes #29

Co-authored-by: @edding4500
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

Successfully merging this pull request may close these issues.

3 participants