-
Notifications
You must be signed in to change notification settings - Fork 334
Fix special handling of static method calls on Any #13939
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
Draft
Akirathan
wants to merge
4
commits into
develop
Choose a base branch
from
wip/akirathan/13892-singleton-type-to-display-text
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ implementation to invoke. | |
|
|
||
| <!-- MarkdownTOC levels="2,3" autolink="true" --> | ||
|
|
||
| - [Static versus instance method calls](#static-versus-instance-method-calls) | ||
| - [Specificity](#specificity) | ||
| - [Multiple Dispatch](#multiple-dispatch) | ||
| - [Resolving Clashes on `Any`](#resolving-clashes-on-any) | ||
|
|
@@ -27,6 +28,25 @@ implementation to invoke. | |
|
|
||
| Another page related to [dispatch](../semantics/dispatch.md) exists. | ||
|
|
||
| ## Static versus instance method calls | ||
|
|
||
| Unlike other programming languages like Java, Enso does not differentiate | ||
| between _static_ and _instance_ method calls. An instance method call is simply | ||
| a static method call with the `self` argument provided implicitly. | ||
|
|
||
| For example, with: | ||
|
|
||
| ``` | ||
| type T | ||
| Cons data | ||
| method self = self.data | ||
|
|
||
| obj = T.Cons 42 | ||
| ``` | ||
|
|
||
| the method call `obj.method` is equivalent to `T.method obj`, which is | ||
| equivalent to `T.method self=obj`. | ||
|
|
||
| ## Specificity | ||
|
|
||
| In order to determine which of the potential dispatch candidates is the correct | ||
|
|
@@ -162,3 +182,54 @@ main = Test.simplify | |
| When invoking a method on _module object_ its _module static methods_ take | ||
| precedence over _instance methods_ defined on `Any`. Thus a module serves | ||
| primarily as a _container for module (static) methods_. | ||
|
|
||
| ### Diagram of method resolution and invocation on `Any` | ||
|
|
||
| This section describes the _special_ method resolution and invocation on `Any` | ||
| type. More specifically, it describes when a `self` argument is implicitly | ||
| provided and what kind of `self` it is. | ||
|
|
||
| Considering: | ||
|
|
||
| ``` | ||
| @Builtin_Type | ||
| type Any | ||
| to_text self = ... | ||
| ... | ||
|
|
||
| type T | ||
| method self = "T.method:" + self.to_text | ||
|
|
||
| Any.method self = "Any.method:" + self.to_text | ||
| ``` | ||
|
|
||
| where `T.method` "overrides" `Any.method`, the method resolution and invocation | ||
| algorithm can be generally described as follows: | ||
|
|
||
| - Is the method called statically? For example like `Any.method ...` or | ||
| `T.method ...`. | ||
|
||
| - No: Continue normal resolution and invocation. | ||
| - Yes: | ||
| - Is the method defined on `Any`? | ||
| - No: Continue normal resolution and invocation. | ||
| - Yes: | ||
| - Is it called on `Any`? For example like `Any.method ...` or | ||
| `Any.to_text ...`. | ||
| - Yes: | ||
| - Method is resolved on `Any` type and invoked with prepended | ||
| `self=Any` argument. Which means that `Any.method` is equivalent | ||
| to `Any.method Any`, which is equivalent to `Any.method self=Any`. | ||
| - No: | ||
| - Is the method _overriden_ in the type on which it is called? | ||
| - Yes: | ||
| - This means that we are calling, e.g., `T.method`. | ||
| - Method is resolved on `T` type and invoked with prepended | ||
| `self=T` argument. | ||
| - Which means that `T.method` is equivalent to `T.method T`, | ||
| which is equivalent to `T.method self=T`. | ||
| - No: | ||
| - This means that we are calling, for example, `T.to_text`. | ||
| - Method is resolved on `Any` type and invoked with prepended | ||
| `self=T` | ||
| - Which means that `T.to_text` is equivalent to `Any.to_text T`, | ||
| which is equivalent to `Any.to_text self=T`. | ||
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
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
There are two things to consider when invoking a method in Enso:
self(and maybeSelf) argumentThe lookup is always done by name in some
Map<String, Function>"pool". The number of pools, their inheritance is not likely to change by this or #11686 changes.I like the idea of defaulted/implicit self argument. It should allow us to make sure that all methods/functions in the pools are always of following
FunctionSchema:fnis an instance method, then the first argument isselfand it doesn't have default valuefnis a static method, then the first argument isselfand it has default value set to the defining typeTBy adhering to this logic, we avoid the duplication of functions (described in #11686) - each function will be defined just once. It will be looked up and based on the type of invocation either implicit
self=objwill be pre-applied or not.PS: Sounds reasonable, but ... it would be good to formalize it with some strict apparatus, otherwise it is clear we'll miss some nuances (as usually).
Uh oh!
There was an error while loading. Please reload this page.
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.
I agree with more formalization, but do you have any suggestions on how such "strict apparatus" may look like?
Uh oh!
There was an error while loading. Please reload this page.
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.
Let's ask the public... meanwhile we should rely on simple, well organized tests. This is my current test case:
there are two errors as far as I can say. Are there any tests related to this instance/static behavior already? Are are they
runtime-integration-tests? Can we group them next to each other, add this new one and constantly add new and new?