-
Notifications
You must be signed in to change notification settings - Fork 13
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
added IValue.getPatternMatchFingerprint() that simulates rascal-core:TopLevelType.getFingerprint(v) exactly for the value kinds we have in vallang #210
Conversation
…TopLevelType.getFingerprint(v) exactly for the value kinds we have in vallang
default int getPatternMatchFingerprint() { | ||
return getName().hashCode() << 2 + arity(); | ||
|
||
// TODO: this would distinguish more constructors based on incomparable argument types: |
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 almost committed this, but I realize this has to be reflected in the switch code generator in the compiler as well. So we need to have a java function that produces the hashCode for a given constructor then. We can push this to the future. We only have to realize that changing these hashCodes breaks all earlier compiled Rascal code, always.
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.
Yes indeed. We already have this at the moment in util::Reflective
via the functions getFingerprint
(2 versions) and getFingerprintNode
. Note that the former has a boolean parameter concretePatterns
. In the new compiler set-up a single function getFingerprint(value v)
will do. (In the compiler runtime I have a function getConcreteFingerprint
that operates on concrete syntax trees.)
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.
So leave as is for now and change later?
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.
Yes let's do that
The tests I just added fail. So not ready to merge but it's good they fail now :-) |
I find the name It is also useful to add a function that returns a default value, e.g. |
What should the default method do exactly? Need more info. |
In the compiler I map patterns like The only guarantee that I need is that the default value is never generated for something else. |
I agree with Paul, hash code values for basic java objects are not
guaranteed to remain the same across different versions of java/jvm. And I
think we in some places feed in a string hashcode, so either we add or own
hash implementation for this, or we find a different solution to hand out
ints.
…On Fri, 13 Oct 2023, 21:25 Paul Klint, ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/main/java/io/usethesource/vallang/IValue.java
<#210 (comment)>:
> @@ -28,7 +28,35 @@ public interface IValue {
* @return the ***@***.*** Type} of a value
*/
public Type getType();
+
+ /**
+ * This method is used exclusively by code generated by the Rascal compiler,
+ * or by the Rascal interpreter. The returned integer codes are opaque, although stable.
+ * If you need to know what kind of value you have, use the IValueVisitor or the ITypeVisitor
+ * interfaces and the `accept` methods on IValue and Type.
+ *
+ * @return an integer code that:
+ * * accurate reflects the identity of the top-level structure of this value
+ * * such that if pattern.match(this) ===> pattern.getPatternMatchFingerprint() == this.getPatternMatchFingerprint()
+ * * distinguishes maximally between different kinds of values
+ * * never makes the same or similar value have a different fingerprint
+ */
+ default int getMatchFingerprint() {
The issue of different hash functions in different JVMs is indeed
troublesome. Why don't we remove hash codes completely from this story and
opt for wisely chosen constants.
—
Reply to this email directly, view it on GitHub
<#210 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABL3E3YQK52IHGSF45XI33X7GIUJANCNFSM6AAAAAA5VWK5CM>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
default int getMatchFingerprint() { | ||
int hash = getName().hashCode(); | ||
|
||
return hash == 0 ? 13547528 /* "node".hashCode() << 2*/ + arity() : (hash << 2) + arity(); |
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.
hash << 2
throws away important bits?
So to summarize the discussion:
|
Good summary.
Maybe nitpicking, but doesn't adding increase the risk of clearing the lower bits? This is only a concern if it's about uniformity I guess. |
Yes, so multiplying with a small unique prime number would help with that. If we use @PaulKlint would that be correct? Or should we make sure node patterns have the same fingerprints as their constructor value counterparts? It may be that a node pattern matches against a constructor value? ... thinking out loud here. |
If constructors should behave as nodes, and vice versa, then I've another test to write. |
…arities are equal
…g anymore but multiply and add the arities
…ct of IValue.getMatchFingerprint
Thanks for the discussion @DavyLandman @PaulKlint ; I think we have something to work with now; the next step is the rascal project and adding the right codes to the other types of values. |
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.
@jurgenvinju I had 2 more cases where I wanted your opinion on.
mmmm... I still have a minor puzzle to solve:
Why does this succeed? |
Because the random generator always produces |
No description provided.