-
Notifications
You must be signed in to change notification settings - Fork 32
Module Methods #233
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
Module Methods #233
Conversation
b1dbcfd
to
d313fd5
Compare
d313fd5
to
220bfa3
Compare
236c7e8
to
2cfcdf7
Compare
2cfcdf7
to
832f26f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so currently we are trying to see if we can get away with not elaborating imported files. So your approach of accessing the defn
won't work if the function comes from a different file. Based on this, I would suggest adding an explicit module
modifier for parameters: fun foo(module m, arg2, arg3)
. I actually like it better than some subtle type-based check.
1c4936b
to
62f7568
Compare
So is this ready for review? (BTW pls read https://github.com/hkust-taco/mlscript/blob/mlscript/CONTRIBUTING.md, if you haven't) Please notify me once you're addressed all our discussions and updated your branch. Also, why not check your TODOs in #233 (comment)? |
Things are getting messy as we come up with new ideas and rules and changing previous ones. I'm trying to refactor the code to ensure everything looks good and concise. That TODO list was intended to track the new rules that have been refactored. This PR should be ready for review by tonight. I'll notify you when I'm done. 🫡 |
Ok sure, no worries! |
ad176d3
to
d58b350
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider the following scenario?
module M
fun foo() = M
I don't think I saw it in the tests.
|
||
// the return type of the function | ||
val result = td.head match | ||
case InfixApp(_, Keyword.`:`, rhs) => S(term(rhs)(using newCtx)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signature was already elaborated above in s
. Looks like this will redo the work!
Though I guess the signature might be different from the explicitly-ascribed result type.
Anyway, you shouldn't manually retrieve this type by pattern matching the tree, duplicating logic in Tree.scala
. There should only be one source of truth about what is the result type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What. I thought that's the problem we've just discussed earlier.
In this #233 (comment) you said "signatures are only picked up from externally-given declaration"; and at
(symbName, R(id), paramLists, S(typeParams), N) |
it does not always pick up the result type from the parsed tree. That's why I did another parsing to make sure result types are always parsed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let me be completely explicit, so we don't get hung up on details and terminology:
- There should be only one place that determines what is the inline-annotated result type in a definition (if there is any). The logic for finding it by analyzing trees should not be duplicated (as you are doing now), as it means that any update to it must also be duplicated everywhere, which is impractical and error-prone.
Currently, this is done inTypeOrTermDef
and the result is confusingly calledsignature
(we could change it toannotatedResultType
). - In the elaborator, if we see there is no inline-annotated result type, we should use the one given by the separate signature. This could be implemented later, though.
- Such explicitly-annotated result types must not be elaborated several times. Indeed, currently that's not the case, but we should be careful that this does not happen whenever we add the logic to achieve the previous point.
This is more of a comment for the future and not immediately actionable.
it does not always pick up the result type from the parsed tree. That's why I did another parsing to make sure result types are always parsed.
If the implementation in TypeOrTermDef
is missing some cases, you should fix that implementation, instead of leaving it broken and reimplementing it separately!
3c4c12d
to
d5e89d0
Compare
089fc6d
to
c874fe3
Compare
Thanks, this was clearly a typo in the original code.
Actually you also need to update the branch and fix its conflicts with the main branch. If you choose to rebase, pls make sure that the tests still work on each individual commit: |
72e3b31
to
4412c65
Compare
87600c4
to
4dec6e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I've committed some minor last changes. Notably, there was some dead code that I removed.
Module methods are the methods defined within a module.
Module parameters are function parameters that are prefixed with
module
keyword.Module values are module literals or applications of functions returning modules.
Rules
module
keyword.