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

Implement type_of #3722

Merged
merged 10 commits into from
Sep 26, 2022
Merged

Implement type_of #3722

merged 10 commits into from
Sep 26, 2022

Conversation

hubertp
Copy link
Contributor

@hubertp hubertp commented Sep 19, 2022

Pull Request Description

This change implements a simple type_of method that returns a type of a given value, including for polyglot objects.

The change also allows for pattern matching on various time-related instances. It is a nice-to-have on its own, but it was primarily needed here to write some tests. For equality checks on types we currently can't use == due to a known feature which essentially does wrong dispatching. This will be improved in the upcoming statics PR so we agreed that there is no point in duplicating that work and we can replace it later.

Also, note that this PR changes Meta.is_same_object. Comparing types revealed that it was wrong when comparing polyglot wrappers over the same value.

Checklist

Please include the following checklist in your PR:

  • The documentation has been updated if necessary.
  • All code conforms to the
    Scala,
    Java,
    and
    Rust
    style guides.
  • All code has been tested:
    • Unit tests have been written where possible.
    • If GUI codebase was changed: Enso GUI was tested when built using BOTH
      ./run ide build and ./run ide watch.

Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

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

I like it. Few comments and opinions left inline.

@@ -140,4 +140,7 @@ type Time_Zone

## Compares two Zones for equality.
== : Time_Zone -> Boolean
== self that = Time_Utils.equals_zone self that
== self that =
Copy link
Member

Choose a reason for hiding this comment

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

I believe this can be written as:

== self that = case Meta.type_of that of
    Time_Zone -> Time_Utils.equals_zone self that
    _ -> False

that would mean less changes in the engine now. Moroever this kind of code would remain valid in the future even with by type pattern matches

distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
@hubertp hubertp changed the title Implement type_of method Implement type_of Sep 22, 2022
@hubertp hubertp marked this pull request as ready for review September 22, 2022 14:08
Copy link
Member

@radeusgd radeusgd left a comment

Choose a reason for hiding this comment

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

Looks good to me overall.

I don't like the is_of_type function - the name is pretty confusing to me. I'd love if we could just fix equality on types. If we cannot, can we at least rename the function to something indicating that it is just checking type equality? And updating the docstring to say that also (currently "matching" of two types is a concept that is not very well-defined and can be associated with other concepts like subtyping, so it is just confusing). May be worth adding a note in the docstring why this function exists and == cannot just be used.

If possible, would be cool if the builtin could handle numeric types and errors too - for uniformity. If not - can we get a descritption in a comment somewhere - why? So that we don't waste time revisiting this in the future if we forget the 'why'.

Lastly, I think we absolutely need a test suite for the case-of pattern matching.

Currently, I'm pretty sure

case Date_Time.now of
    Time_Zone -> "TZ!"
    _ -> "..."

will match and return TZ!. Is this what we want? I'm not sure but intuition tells me that nope.
So I think we should add proper test cases to show it works correctly and amend the branch nodes too.

CHANGELOG.md Outdated Show resolved Hide resolved
distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso Outdated Show resolved Hide resolved
distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso Outdated Show resolved Hide resolved
distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
test/Tests/src/Semantic/Meta_Spec.enso Outdated Show resolved Hide resolved
@hubertp
Copy link
Contributor Author

hubertp commented Sep 26, 2022

I changed type_of tests to use Meta.is_same_object rather than the new function. I reused some of the logic from it though (see isIdentical) to fix wrong semantics for polyglot values. Added a bunch of tests, changed the subtyping for date/time to what was requested.

I couldn't use ==, as we all wished, to test types because that is currently broken and it is a known feature. Should be fixed once work on statics is finalized.

Copy link
Member

@radeusgd radeusgd left a comment

Choose a reason for hiding this comment

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

Looks good to me, just a few suggestions and a question.

hubertp and others added 10 commits September 26, 2022 16:48
This change implements a simple `type_of` method that returns a type of
a given value, including for polyglot objects.

The change also allows for patterning matching on various time-related
instances. It is a nice-to-have on its own, but it was primarily needed
here to write some tests.
Addressed PR comments - eliminated `Meta.type_of_polyglot_builtin`
and merged its implementation into a single node.
Added `is_of_type` to avoid using `==` checks on types, which doesn't
work as expected, half the time.
Removed `is_of_type` and moved some of the logic to `is_same_object`.
Turns out the latter was actually broken when comparing polyglot values
with the same underlying java class.

Additionally, discovered why I can't simply use `==` - the dispatch for
types is broken and it's a known "feature". This will be improved in the
upcoming statics change so I'm not going to duplicate that work. Once
in, we can most likely get rid of `should_equal_type` and
`should_not_equal_type`.

Addressed comments re date/time-related branches in pattern matching so
that it doesn't try to do semi-subtyping checks but rather checks for
equality.

Moved all logic of `type_of` to the builtin node.
Added tests for `type_of` of Date, Date_Time, Time_Of_Day and Time_Zone.
Might still change `type_of` to ensure that java classes aren't leaking.
We want to make sure that the type of Java's LocalTime or LocalDate etc
is a corresponding Enso type, Enso's Time_Of_Day or Date, respectively.

Added more tests, including those that ensure lack of subtyping between
Enso's Date, Date_Time, Time_Of_Day and Time_Zone.
Co-authored-by: Radosław Waśko <radoslaw.wasko@enso.org>
@hubertp hubertp added the CI: Ready to merge This PR is eligible for automatic merge label Sep 26, 2022
@mergify mergify bot merged commit 7a6ee0c into develop Sep 26, 2022
@mergify mergify bot deleted the wip/hubert/typeof-183188858 branch September 26, 2022 16:01
@wdanilo wdanilo mentioned this pull request Feb 6, 2023
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants