-
Notifications
You must be signed in to change notification settings - Fork 48
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
Improve type and function sharing between modules #62
Comments
Opinions on separating function and type imports into two different statements? E.g.
Too much? I kind of like the separation for clarity but I'm not particularly attached to it. |
Does not matter much to me. Personally, I just want to bring a name into local scope, be it a function name or type name. That argues for having a single import statement. However, since it is possible to define both a function |
👍 to |
I kind of like the idea that a type itself can be completely hidden in a module as it seems with the Idris docs you linked, @yurrriq. For type exports I'm thinking:
Type imports would be simpler, either just the type name or specific constructors/members. The four export points do seem a little messy. Might look something like:
Does that seem needlessly convoluted? Should we be adopting something like Idris' syntax here? I do like the decoupling of definition and exposure with something like |
I don't feel very strongly any particular way. I believe however that your proposal grants a lot of control over what is exported without being too awkward to use, so I can't see any problems with rolling with that. |
I agree with @lepoetemaudit; your proposal sounds good, @j14159. I'm not sure I love the third bullet point, but 👍 for fine-grained control and if I don't like it I don't have to use it 😄 Edit: Pulled out types question to #77 |
@yurrriq I hadn't thought of it but I don't think there's any particular problem with having the same name with different arity to describe different versions of a type. I'm not sure I can think of a concrete use for it but we could certainly try it out and see if it's useful. Mind filing a different issue for it as a feature and broader discussion? |
Regarding bullet point 1: How do you handle the case when you have not exported a type, but you have some function returning a value of that type? E.g.
If I call |
FWIW Idris will fail to compile the module in that case, so 👍 to having the compiler check. |
I don't think the check would be too hard to implement, basically "for every top level function it is a type privacy violation iff the function is exported AND the function's type contains any unexported types". IIRC recursive ADTs (not the most appropriate name but all user-defined types are considered to be ADTs) only refer to themselves by name so we shouldn't get non-terminating behaviour running this check but that's a potential issue. I guess the bigger question is: where do we want to sit in the balance of simplicity for the user vs most expressive/high degree of control? Related questions:
|
"are errors about unexported types going to cause more confusion than all type names being public?l In this case, a glaringly obvious error message would be sufficient no? "I can't find type foo, you must add import_type your_module.foo" |
Your comment about a types being public is far more simple, maybe cross the type-name collision bridge when you get to it? |
Idris says something like "exported function Edit: changed names to go with @danabr's example. |
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
This was suggested in alpaca-lang#63. It's not actually part of the AST generation phase yet but it made sense to handle this at the same time as function imports for alpaca-lang#62. I'm going to decouple the basic parsing pass from the renaming and rewriting pass of the parser since rewriting the names of imported functions to inter-module calls will require the other modules to already be parsed and accessible.
I think in the interest of simplicity for now I'd like to go with:
References to types that aren't exported must be qualified by their module name, e.g. given
This is an error:
This is OK but the constructor
This should ensure that exported functions exposing un-exported implementations are still intelligible on some level and this will be somewhat consistent with us later adding things like opaque types coming in from Erlang code (e.g. a request structure passed to a callback written in Alpaca from something like Webmachine or Cowboy). Both private types and limited implementation imports (e.g. Thoughts? |
+1 on this, since it is fairly easy to reason about. |
Fixes alpaca-lang#94. We can now refer to type constructors with their module name rather than needing to import them. This is restricted to types that are exported by their modules which helps towards alpaca-lang#62.
Fixes alpaca-lang#94. We can now refer to type constructors with their module name rather than needing to import them. This is restricted to types that are exported by their modules which helps towards alpaca-lang#62.
Fixes alpaca-lang#94. We can now refer to type constructors with their module name rather than needing to import them. This is restricted to types that are exported by their modules which helps towards alpaca-lang#62.
Fixes alpaca-lang#62 This was the last bit to wrap up issue alpaca-lang#62 so that unexported types can be referred to by other modules' types without exposing their implementation. This correspondingly does not allow an unexported type's constructors to be used.
Short list, driven by discussion on PR #61 with @danabr and from @lepoetemaudit's infix function work:
Per @danabr we should consider a single
import
directive that allows importing specific functions, types, or even a subset of a type's constructors.Ideas/expansions/criticisms most welcome.
The text was updated successfully, but these errors were encountered: