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 user defined kinds #2486

Merged
merged 14 commits into from
Dec 28, 2016
Merged

Add support for user defined kinds #2486

merged 14 commits into from
Dec 28, 2016

Conversation

LiamGoodacre
Copy link
Member

@LiamGoodacre LiamGoodacre commented Dec 17, 2016

Initial work towards #919

Kind declarations:

foreign import kind Nat

Import/export kinds:

module F (kind N) where
import B (kind N)

Use of kinds in various places (see example/passing/ForeignKind/Lib.purs):

foreign import data Zero :: Nat
foreign import data Succ :: Nat -> Nat
...

Should I also move Symbol to use the new KindConstructor?
There are probably a lot more tests I should add, but it's a start.
Any issues, things I've missed, etc?
Thanks 😄

@@ -95,6 +95,7 @@ convertDecl P.EDValue{..} = Just $ IdeDeclValue $
IdeValue edValueName edValueType
convertDecl P.EDClass{..} = Just (IdeDeclTypeClass edClassName)
convertDecl P.EDInstance{} = Nothing
convertDecl P.EDKind{} = Nothing
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 wasn't sure what this was. I'll investigate further to see what actually needs doing here. I assume I'll need to add a new IdeDeclaration constructor.

Copy link
Contributor

Choose a reason for hiding this comment

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

@kritzcreek Can you comment?

Copy link
Member

Choose a reason for hiding this comment

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

If you wanted the custom Kinds to show up in completions you'd have to add a new IdeDeclaration constructor, yep. One question though: Do kinds live in their own name space as well? So can I have a kind, type and identifier with the same name? That would require some more changes to psc-ide.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes they have their own namespace. What kind of changes are required?

Copy link
Member

Choose a reason for hiding this comment

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

Add a dtor to IdeDeclaration in Ide.Types and fill in identifierFromIdeDeclaration and completionFromMatch in Ide.Util.

Copy link
Member

Choose a reason for hiding this comment

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

Oh sry I read that as though they didn't :D the changes required are in extractSpans in Ide.SourceFile where I used an Either to disambiguate names on the type and value level

@rightfold
Copy link
Contributor

rightfold commented Dec 17, 2016

Should I also move Symbol to use the new KindConstructor?

I think putting it in Prim is less surprising when someone wants to shadow it, although this is a very specific use-case. It may also simplify some of the Kind case analysis in the compiler.

Any issues, things I've missed, etc?

Kind aliases? E.g. kind Type = *. Though that could be a different PR.

@@ -19,7 +19,7 @@ import Language.PureScript.AST
import Language.PureScript.Crash
import Language.PureScript.Errors
import Language.PureScript.Names
import Language.PureScript.Sugar.Names.Env
Copy link
Member Author

Choose a reason for hiding this comment

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

All the lines that have changed but don't look different in this file are line-ending changes.

@LiamGoodacre
Copy link
Member Author

If I move Symbol to use KindConstructor, should I also add Ordering while I'm there and cancel #2484

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

I think Symbol needs to be in Prim since there is built-in syntax which needs it, but Ordering can defined in a library (and if it can, I think it should be). Maybe something like purescript-typelevel-prelude?

@@ -20,6 +22,8 @@ data Kind
| FunKind Kind Kind
-- | Type-level strings
| Symbol
-- | A kind constructor
| KindConstructor (Qualified (ProperName 'KindName))
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we just call this NamedKind or OtherKind? Constructor seems to imply that we can have kinds which take other kinds as arguments, which isn't true.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I've gone with NamedKind.

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

Looks great, thanks!

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

One more thing you'll probably need to update is usedModules in ModuleDependencies.hs.

@LiamGoodacre
Copy link
Member Author

@paf31 for updating usedModules it looks like a need to update everythingOnTypes to support traversing kind annotations, is that correct?

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

Yes, that sounds right.

@LiamGoodacre
Copy link
Member Author

Changing everythingOnTypes looks really annoying :P it is used everywhere - is it acceptable to instead write an accumKinds like we have accumTypes?

@LiamGoodacre
Copy link
Member Author

Actually, changing everythingOnTypes wouldn't be enough anyway, it wouldn't pick up kinds in foreign data declarations - I think.

@LiamGoodacre
Copy link
Member Author

Okay so I added accumKinds because kinds don't just appear in types, they appear in type class declarations, foreign data declarations, etc.

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

Actually, having thought about this more, I'm not sure why usedModules does what it does now actually. @garyb shouldn't module sort-order be determined entirely by imports now?

(in which case there would be less work to do here, so you might want to hold off until this is clarified)

@garyb
Copy link
Member

garyb commented Dec 18, 2016

shouldn't module sort-order be determined entirely by imports now?

Yep, I mentioned this a while ago in another PR!

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

Sorry :) So does that mean we can just get rid of usedModules apart from the ImportDeclaration bit then?

@LiamGoodacre
Copy link
Member Author

Even if I don't change usedModules, the accumKinds function still looks useful to have?

@rightfold
Copy link
Contributor

rightfold commented Dec 18, 2016

Are changes to psc-docs also necessary? E.g. https://github.com/purescript/purescript/blob/master/psc-docs/Tags.hs and Markdown generation.

@LiamGoodacre
Copy link
Member Author

I think we need to add stuff to Interactive/Completion and Sugar/BindingGroups too.

@LiamGoodacre
Copy link
Member Author

Unfortunately I can't build psci and psc-ide-server locally, so I'll have to depend on CI for that.

@paf31
Copy link
Contributor

paf31 commented Dec 18, 2016

Even if I don't change usedModules, the accumKinds function still looks useful to have?

Yes, I think so.

= IdeNameValue Text
| IdeNameType Text
| IdeNameKind Text
deriving (Show, Eq, Ord)
Copy link
Member Author

Choose a reason for hiding this comment

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

@kritzcreek is this okay for replacing the use of Either Text Text that you mentioned?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe replace Name with NS or Namespace but other than that looks great!

@LiamGoodacre
Copy link
Member Author

Actually I don't think anything needs adding to Interactive/Completion, right?

@@ -73,6 +73,7 @@ createBindingGroups moduleName = mapM f <=< handleDecls
valueVerts = map (\d -> (d, declIdent d, usedIdents moduleName d `intersect` allIdents)) values
bindingGroupDecls <- parU (stronglyConnComp valueVerts) (toBindingGroup moduleName)
return $ filter isImportDecl ds ++
filter isExternKindDecl ds ++
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'm slightly confused about this. Without adding in this filter, does that mean that the kind declarations disappear when creating binding groups? Also is this all that is needed here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Correct

@LiamGoodacre LiamGoodacre changed the title Add foreign import kind Add support for user defined kinds Dec 20, 2016
@LiamGoodacre
Copy link
Member Author

Updated the ForeignKind test with a kinded type annotation and I see the following error:

  1) Passing examples 'ForeignKind.purs' should compile and run without error
       Error found:
       in module ForeignKinds.Lib
       at /Users/liamgoodacre/git/purescript/examples/passing/ForeignKind/Lib.purs line 25, column 1 - line 25, column 22

         Could not match kind

           Nat

         with kind

           Nat


       while checking the kind of Kinded Zero
       in type synonym N0

Something is wrong :P

@paf31
Copy link
Contributor

paf31 commented Dec 20, 2016

Did you update the unify function for kinds? It's in TypeChecker.Kinds.

@LiamGoodacre
Copy link
Member Author

@paf31 yes I believe unifyKinds is fine, it looks like the problem is that the kind in a KindedType hasn't been fully qualified. E.g:

Qualified Nothing (ProperName "Nat")
Qualified (Just (ModuleName [ProperName "ForeignKinds", ProperName "Lib"])) (ProperName "Nat")

@paf31
Copy link
Contributor

paf31 commented Dec 22, 2016

Ideally not, but I don't think we should make a special case for the $PSCI module either. Really, this should take into account which modules are imported, but we have a separate issue for that already, so maybe we can handle it then.

-- | Type-level strings
| Symbol
-- | A named kind
| NamedKind (Qualified (ProperName 'KindName))
Copy link
Contributor

@paf31 paf31 Dec 23, 2016

Choose a reason for hiding this comment

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

I wonder if Star and Bang should be moved into Prim too?

Eventually, I would like Bang to be moved into purescript-eff, but in order to do that, we need to introduce a name for it other than ! (perhaps Effect?). So how about we move it into Prim now, allow both ! and Effect in the parser, and then move it out to purescript-eff in 0.11?

While we're at it, we can alias * as Type.

Copy link
Member Author

Choose a reason for hiding this comment

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

That sounds great, I should hopefully be able to get this done tonight/tomorrow.

Copy link
Member Author

Choose a reason for hiding this comment

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

In updating this I've found that I'd missed updating primImports in Sugar/Names/Env.hs.

@LiamGoodacre
Copy link
Member Author

I removed the ShadowPrimKind test as it now fails due to #2499 since I added primKinds to primImports in Sugar/Names/Env.

@paf31
Copy link
Contributor

paf31 commented Dec 24, 2016

@LiamGoodacre Looks great, but could you please see if it's possible/simple to add documentation for the kinds in Prim now that @hdgarrood's PR #2494 has been merged?

Thanks!

@hdgarrood
Copy link
Contributor

That will require changes to Language.PureScript.Docs.Types to add a new DeclarationInfo constructor for user defined kinds. As far as I can tell, I think that would be fairly straightforward.

@LiamGoodacre
Copy link
Member Author

@hdgarrood I had already added a new ExternKindDeclaration constructor to DeclarationInfo, so I just needed to extend what you added in your PR.

How does the "Add docs for kinds in Prim" commit look? I haven't written that much for each one.

@LiamGoodacre
Copy link
Member Author

I renamed lookupPrimKind to lookupPrimTypeKind as I thought it was slightly confusing as it is really "lookup this type to find its kind" - and originally I was going to add a lookupPrimKind for kinds - but I can change it back if you want.

@hdgarrood
Copy link
Contributor

Oops :) What you've got there all looks great to me, I agree that the way that you've renamed lookupPrimKind is an improvement. 👍

@paf31
Copy link
Contributor

paf31 commented Dec 28, 2016

@LiamGoodacre Could you please rebase this?

@paf31 paf31 merged commit 144dd6f into purescript:master Dec 28, 2016
@paf31
Copy link
Contributor

paf31 commented Dec 28, 2016

Thanks very much!

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

Successfully merging this pull request may close these issues.

6 participants