FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add support for local type synonyms by rhendric · Pull Request #3709 · purescript/purescript · GitHub

Add support for local type synonyms - #3709

Closed
rhendric wants to merge 1 commit into
purescript:masterfrom
rhendric:local-type-synonyms
Closed

Add support for local type synonyms#3709
rhendric wants to merge 1 commit into
purescript:masterfrom
rhendric:local-type-synonyms

Conversation

Copy link
Copy Markdown
Member

This implements type X = Y synonyms as another form of let binding,
valid inside let expressions, where clauses, and do notation.
These synonyms are hoisted to the top level during desugaring.


This is a complete attempt at #3708, but subject to change if there's feedback on that feature request. Feedback on this specific implementation is welcome here; feedback on the concept of local type synonyms should probably go there.

The biggest sin I have to confess here is using the hoisted type synonym name mangling to store data, as opposed to just being a unique string. The excuses I offer are that the data are only retrieved by reporting code in Language.PureScript.Errors and Language.PureScript.Pretty, not anywhere ‘important’, and there only through functions defined alongside the name mangling code so that the ‘magic string’ logic stays local; and that the alternative would involve changing ProperName, changing TypeSynonymDeclaration, or adding a new constructor alongside TypeSynonymDeclaration, any of which would likely require refactoring code in a much wider scope than this PR currently targets—an outcome worth avoiding not only because I'm lazy, but also because I figured you would prefer it if I kept my grubby noob hands out of the typechecker. 😄 As always, I'm happy to do the work if I'm wrong.

Closes #3708.

Copy link
Copy Markdown
Contributor

Could you please add some passing and failing tests where a top-level declaration does not have a type signature but there is a local type synonym used in its definition? I feel like it would be good to test that, e.g., the inferred type for the top level declaration does not mention the local synonym in such cases.

Copy link
Copy Markdown
Contributor

(although you might want to wait until we've made a decision on whether to move forward with this, sorry)

This implements `type X = Y` synonyms as another form of let binding,
valid inside `let` expressions, `where` clauses, and `do` notation.
These synonyms are hoisted to the top level during desugaring.
rhendric force-pushed the local-type-synonyms branch from 13c3ed2 to d793b0b Compare May 4, 2020 22:15

rhendric commented May 5, 2020

Copy link
Copy Markdown
Member Author

I added tests as requested (see failing/LocalTypeSynonyms5 and 6, and the end of passing/LocalTypeSynonyms); not sure they cover everything you had in mind though. Mind taking a look? (The build is failing for the same reason master is; I don't see any new hlint complaints in this PR.)

Copy link
Copy Markdown
Contributor

Yeah, that's what I was imagining. Thanks! Also could I request that you not force-push, since it makes it a bit harder to review? We can save commit rewriting for when we're ready to merge.

rhendric commented May 6, 2020

Copy link
Copy Markdown
Member Author

Oh, of course! Sorry for the trouble.

Copy link
Copy Markdown
Contributor

No worries! 🙂

Copy link
Copy Markdown
Contributor

Do we need to support standalone kind signatures for polykinds?

rhendric commented May 6, 2020

Copy link
Copy Markdown
Member Author

Probably! I can easily add some tests that copy what the type synonym parts of the StandaloneTypeSignatures tests do, only in an inner scope; but I think there are probably more interesting things to test around using and/or shadowing kinds from the outer scope. I'm not very comfortable with polykinds yet; do you have any particularly tricky things to exercise in mind?

Copy link
Copy Markdown
Contributor

The primary issues I'm thinking about are:

  • We generalize the kinds of type-level declarations. Type-level declarations are all top-level, and so they have the same generalization strategy as top-level value declarations. It's not clear to me that local type synonyms should be generalized, since we don't otherwise generalize local value declarations.
  • We warn on generalization of type-level declarations like we warn on generalization of value declarations. If we are hoisting and generalizing local declarations, what do these warnings look like?

These issues are part of what make me hesitant to implement this as a desugaring step.

rhendric commented May 6, 2020

Copy link
Copy Markdown
Member Author

I could be missing something here, but is generalization a concern for type synonyms? Since there can't be cycles in type synonyms, eventually all type synonym expansions will bottom out in some type made of top level data, from which kinds can be inferred. Any parameters to type synonyms that aren't included in this final expansion are not only generalizable, they're completely irrelevant, right? There's no point in having them at all: type synonyms can't be partially applied, and everything else in the language that uses types such as instance resolution depends on the expansion, not the synonym form. So generalizing makes no difference; unused type synonym parameters at any scope, top-level or not, could be errors and I don't think any real programs would be affected. Is that right?

natefaubion commented May 6, 2020
edited
Loading

Copy link
Copy Markdown
Contributor

I should clarify, I don't think there's necessarily an implementation problem with generalizing, it's more about expectations around where and how we generalize in PureScript, and if we want a consistent rule-set for generalization, and how warnings and such around it are exposed to the user.

Copy link
Copy Markdown
Contributor

An example to test for right now would be defining a local type LocalApp a = f a synonym where f is bound in the current scope. How does the compiler treat that and warn?

rhendric commented May 6, 2020

Copy link
Copy Markdown
Member Author

An example to test for right now would be defining a local type LocalApp a = f a synonym where f is bound in the current scope. How does the compiler treat that and warn?

Ah, thank you, I think I see the problem now. We're talking about generalization of the type parameters that get added from the local scope. Prior to polykinds, these all had definite kinds at the forall site, either explicitly stated or implicitly Type. But now they can generalize, and the compiler warns about that, and is that right?

On reflection, this seems like a specification question rather than a question about this particular implementation (although, even in the absence of a right thing, this implementation is clearly doing a wrong thing by issuing a warning about type local$1$1$LocalApp). I propose moving this conversation over to #3708.

Copy link
Copy Markdown
Member Author

I'm closing this in favor of #3897, as I'm now reasonably convinced that getting kind signatures and the desired generalization behavior right with desugaring is more trouble than not. There are very probably still issues to work out with #3897 but for now it certainly looks like the more practical path forward (assuming of course that the maintainers ultimately decide the feature is desirable at all).

rhendric closed this Jul 11, 2020
rhendric deleted the local-type-synonyms branch January 19, 2023 21:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

Feature: local type synonyms

3 participants


Back | FazBrowse Home | New Git URL