-
Notifications
You must be signed in to change notification settings - Fork 323
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
By-type pattern matching #3742
By-type pattern matching #3742
Conversation
6bb58fe
to
cafbb2e
Compare
boolean test = isSameObject.execute(expectedType, typeOfTarget); | ||
if (profile.profile(test)) { | ||
accept(frame, state, new Object[] {target}); | ||
} else if (TypesGen.isType(typeOfTarget)) { |
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.
@JaroslavTulach I suppose I should profile conditions in this branch as well?
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.
Can we analyze the positive/negative check? Check the IGV graphs or have a benchmark for the simple expectedType
equals typeOfTarget
and for the case when it is not? Especially when there are some tpe.getSupertype()
?
If we can guarantee some stability of superTpe
, then this while
cycle would be candidate for @ExplodeLoop...
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.
couple of minor bits - only looked at the enso stuff.
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.
This is awesome! I'm glad we finally have that.
Looks good, just a few comments/questions in-line.
Text -> if other == "" then self else Builder_Data (self.fragments ++ (code other).fragments) | ||
text : Text -> if text == "" then self else Builder_Data (self.fragments ++ (code text).fragments) |
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.
Wow, I didn't know we'll be able to do that too! It's great!
...n/java/org/enso/interpreter/node/controlflow/caseexpr/CatchPolyglotSymbolTypeBranchNode.java
Outdated
Show resolved
Hide resolved
engine/runtime/src/test/java/org/enso/interpreter/test/VectorTest.java
Outdated
Show resolved
Hide resolved
@@ -25,4 +25,6 @@ spec = | |||
pattern = "http://example.com" | |||
Regex.escape pattern . should_equal "\Qhttp://example.com\E" | |||
|
|||
## TODO: Missing tests for No_Such_Group_Error |
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.
Any more information on what happened here?
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.
This is more of a wishlist since No_Such_Group_Error.to_display_text
pattern matches on Text
and Integer
types but I only discovered those via a simple grep because all tests were passing.
...n/java/org/enso/interpreter/node/controlflow/caseexpr/CatchPolyglotSymbolTypeBranchNode.java
Outdated
Show resolved
Hide resolved
engine/runtime/src/main/scala/org/enso/compiler/codegen/IrToTruffle.scala
Outdated
Show resolved
Hide resolved
Added supported for deeply nested type patterns, such as |
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.
Without no doubts this change has to get in! I have some doubts when Node
references a value, but that is a strategic problem, not something that has to be resolved in this PR. Thank you @hubertp for simplifying the logic of branching by reducing the number of various branch nodes!
@NodeInfo(shortName = "PolyglotSymbolTypeMatch") | ||
public abstract class CatchPolyglotSymbolTypeBranchNode extends BranchNode { | ||
|
||
private final Object polyglotSymbol; |
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.
Code (e.g. Node
subclasses) cannot directly hold on values, if we ever want to use single Engine for multiple Contexts. CCing @kustosz
Enso symbols aren't referenced directly, but via Enso Context and that's OK. We need something same for non-Enso values.
...untime/src/main/java/org/enso/interpreter/node/controlflow/caseexpr/CatchTypeBranchNode.java
Outdated
Show resolved
Hide resolved
CatchTypeBranchNode(Type tpe, RootCallTarget functionNode) { | ||
super(functionNode); | ||
this.expectedType = tpe; | ||
this.isArrayExepctedType = Context.get(this).getBuiltins().array() == tpe; |
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.
boolean test = isSameObject.execute(expectedType, typeOfTarget); | ||
if (profile.profile(test)) { | ||
accept(frame, state, new Object[] {target}); | ||
} else if (TypesGen.isType(typeOfTarget)) { |
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.
Can we analyze the positive/negative check? Check the IGV graphs or have a benchmark for the simple expectedType
equals typeOfTarget
and for the case when it is not? Especially when there are some tpe.getSupertype()
?
If we can guarantee some stability of superTpe
, then this while
cycle would be candidate for @ExplodeLoop...
@@ -1,63 +0,0 @@ | |||
package org.enso.interpreter.node.controlflow.caseexpr; |
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.
Great to see all these special branch nodes being deleted!
@@ -829,6 +829,17 @@ object AstView { | |||
case Pattern(pat) => Some((pat, right)) | |||
case _ => None | |||
} | |||
case AST.App.Infix( |
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.
CCing @kazcw.
@@ -968,52 +968,9 @@ class IrToTruffle( | |||
) => | |||
val tpe = | |||
mod.unsafeAsModule().getScope.getTypes.get(tp.name) | |||
val any = context.getBuiltins.any |
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.
Removing all the specialized branch nodes and replacing them with a single construct is a magnificent improvement regardless of any other comments.
4348b1f
to
52f274c
Compare
`scope.getType` vs `scope.getTypes.get` is easy to get wrong. Now ``` case Date_Time.now of _ : Date_Time.Date_Time -> "OK" _ -> ``` works as expected.
We can now pattern match on types!
Polyglot values coming from JS or Python were problematic because they followed a different path than Java's polyglot values. The type of JS' Array values was PolyglotProxy which we need to specialize on. Python's Array values are on the other hand represented as Python list. Since it is impossible to special case those when inferring the type, CatchType has a specialization on Array-like values that have a meta object but no type. Additionally added support for pattern matching on polyglot symbols (both in types and as values).
And replace it with pattern matching on Text type.
Also now supporting subtyping for Enso as well as polyglot types.
Co-authored-by: Radosław Waśko <radoslaw.wasko@enso.org>
This messes up aliasing info, which in turn affects global names pass.
1d55a67
to
cb7e952
Compare
Pull Request Description
This change brings by-type pattern matching to Enso.
One can pattern match on Enso types as well as on polyglot types.
For example,
as well as Java's types
It is no longer possible to match a value with a corresponding type constructor.
For example
will no longer match and one should match on the type (
_ : Date
) instead.is fine though, as requested in the ticket.
The change required further changes to
type_of
logic which wasn't dealing well with polyglot values.Implements https://www.pivotaltracker.com/story/show/183188846
Important Notes
I discovered late in the game that nested patterns involving type patterns, such asThis is now supported!Const (f : Foo) tail -> ...
are not possible due to the old parser logic.I would prefer to add it in a separate PR because this one is already getting quite large.
Checklist
Please include the following checklist in your PR:
Scala,
Java,
and
Rust
style guides.
./run ide build
and./run ide watch
.