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

Dyno: implement manage statements & context managers #26494

Merged
merged 27 commits into from
Jan 21, 2025

Conversation

DanilaFe
Copy link
Contributor

@DanilaFe DanilaFe commented Jan 8, 2025

This PR adds support for context managers:

manage bla as foo {
  // etc.
}

It does so by leaning on interface support, since we have decided to use them to "bless" the special methods enterContext and exitContext. As such, this PR depends on #26396 and #26471.

The diff without the interface implementations can be found here: https://github.com/chapel-lang/chapel/pull/26494/files/8c4102910462ff3e792bddaa75e01bdbf1b2ee63..a2e2745e3d47a65c284fb8119660288f028bbaa4

The general approach is straightforward: since we can compute witnesses for special interfaces like contextManager, this PR ensures that manage statements find the contextManager interface, and then use the witness functions as associated actions. Some complications arise due to the fact that context managers are design right now must be able to resolve return-intent-overloaded functions at manage time, which means (if the witness approach is to be used) that witnesses must contain all overloads. This PR adjusts for that, but only stores the additional overloads when ifc any return intent (the pragma that decorates enterContext) is used, thus attempting to avoid paying the multi-overload cost for other interfaces and functions.

Reviewed by @riftEmber -- thanks!

Testing

  • dyno tests
  • paratest

@DanilaFe DanilaFe marked this pull request as draft January 8, 2025 20:07
@DanilaFe DanilaFe marked this pull request as ready for review January 14, 2025 01:12
Signed-off-by: Danila Fedorin <[email protected]>
Previously, we didn't correctly find them during Dyno scope resolution,
and later the production scope resolver took care of them. However, now
that we find them, we have to note them as converted symbols so that
when a toId points at an 'as' Variable, we know what to point the
SymExpr to.

Signed-off-by: Danila Fedorin <[email protected]>
Signed-off-by: Danila Fedorin <[email protected]>
Signed-off-by: Danila Fedorin <[email protected]>
Signed-off-by: Danila Fedorin <[email protected]>
Copy link
Member

@riftEmber riftEmber left a comment

Choose a reason for hiding this comment

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

The manage technote and "manage statement" docs should be updated to reflect support for return intent overloading.

Also curious, what's the origin of the term 'witness' in this context?

frontend/lib/resolution/Resolver.cpp Show resolved Hide resolved
frontend/lib/resolution/resolution-types.cpp Show resolved Hide resolved
frontend/test/resolution/testManage.cpp Show resolved Hide resolved
frontend/test/resolution/testManage.cpp Show resolved Hide resolved
frontend/test/resolution/testManage.cpp Show resolved Hide resolved
frontend/test/resolution/testManage.cpp Outdated Show resolved Hide resolved
@DanilaFe
Copy link
Contributor Author

DanilaFe commented Jan 18, 2025

The manage technote and “manage statement” docs should be updated to reflect support for return intent overloading.

Return intent overloading existed prior to my PR (I’m merely mimicking production) — I can add a follow-up to check the docs, but I don’t think my PR made any changes to the semantics of manage statements on that front.

Also curious, what’s the origin of the term ‘witness’ in this context?

Logic! For propositions like exists x, P(x), the “x” (or abusively, the whole combination of x and a proof of P(x)) is called a witness. In fact, interface search in general is “merely” a proof search in first order logic. You can think of each interface as a predicate (N-ary where N is the number of formals), and each implements as an axiom that asserts the P(x) for the given type / interface combo. Generic implementation points like, for instance, someInterface(integral), are actually axiom schemas, under this correspondence.

This analogy typically comes from functional languages whose typeclasses are much like our interfaces. C.f. Haskell's typeclasses, Coq's typeclasses and Agda's instance arguments

Signed-off-by: Danila Fedorin <[email protected]>
@riftEmber
Copy link
Member

Return intent overloading existed prior to my PR (I’m merely mimicking production) — I can add a follow-up to check the docs, but I don’t think my PR made any changes to the semantics of manage statements on that front.

Oh right, we're in dyno lol. All good then.

Logic!

Thanks for the explanation! I do remember that use of the term "witness" now, and the rest of it is new to me.

@riftEmber riftEmber self-requested a review January 18, 2025 01:03
@DanilaFe DanilaFe merged commit f7aea92 into chapel-lang:main Jan 21, 2025
8 checks passed
@bradcray
Copy link
Member

Nice!

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