-
Notifications
You must be signed in to change notification settings - Fork 4
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
Rework Collections for Expect
and Name
#439
Conversation
Remove the collection Expect construct. Instead, we use generics now and substitution of generics to deal with unification of collections. - Ignore collection type in output - Make temporary variables top-level Need to augment the unification rule for types a bit. If generics match and any generic is temporary, these must be substituted as well.
ad4e7e4
to
d7eb8fe
Compare
- __iter__() call, which gives iterator. We constrain this using a temporary type - __next__() call, whose return type is constrained to the collection type
Need to generalize how we convert mamba types to Python types in generate stage. In particular: - When encountering types in the wild - When encountering constructors in the wild And _only_ in those situations so we don't accidentally change identifiers with say class names.
Add issue that we should only override identifiers with Python type in:
|
Makes unification logic much simpler.
Now easier to check whether something callable or tuple. Also simply generate by not looking at type annotations, except for class arguments. We are now dependent on the check stage to annotate variables
When looking up classes in context, we convert generic parents to concrete parents (in the form of StringNames). So, Collection[Int] is a super of Set[Int]: - Set has a parent Collection[Int] - We check that Collection[Int] is super of itself: - The first part is equal to itself. We also see that it has the same amount of generics as itself. - We proceed to perform this now for each generic by matching them.
Expect::Collection
Expect
and Name
} | ||
|
||
pub trait IsTemp { | ||
fn is_temp(&self) -> bool; | ||
} | ||
|
||
pub trait MatchTempName { | ||
fn temp_map(&self, other: &StringName, mapping: HashMap<Name, Name>, pos: Position) -> TypeResult<HashMap<Name, Name>>; |
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.
Hm perhaps some of this logic could be re-used for match_name
?
They are very similar, except for the if statement.
So if you can pass a predicate then they're the same basically.
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.
Do this at the end perhaps when we have a build where all the tests pass again.
Will make it much easier to quickly verify the refactor.
89b6fe6
to
ad2cbad
Compare
Also match identifier with any expression if no type present.
} | ||
}; | ||
match (ty, expr) { | ||
(Some(ty), Some(expr)) => { |
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.
Have we tested type and expr?
Should the logic below for Some(expr)
not also be here?
Tuple literals are bound, so it should be fine, but perhaps just a small comment to make it clear so this doesn't appear like an oversight.
If it should be here, then better to have wildcard for ty
and just have a small if let Some(...) = ...
binding for ty in the body.
And remove unnecessary push_ty in unify_ty.
For tuples we make an exception by iterating over the elements and checking that they each define __str__(). Also add extra rule for self. In union, self is always equal to entity_name. Other arguments are left as-is.
Should restructure name such the Name can have nested unions.
Codecov Report
@@ Coverage Diff @@
## develop #439 +/- ##
===========================================
- Coverage 88.59% 88.46% -0.14%
===========================================
Files 110 107 -3
Lines 11956 11729 -227
===========================================
- Hits 10593 10376 -217
+ Misses 1363 1353 -10
|
* Add substitution of names Remove the collection Expect construct. Instead, we use generics now and substitution of generics to deal with unification of collections. - Ignore collection type in output - Make temporary variables top-level Need to augment the unification rule for types a bit. If generics match and any generic is temporary, these must be substituted as well. * Match and substitute generic * Create two constraints for every col - __iter__() call, which gives iterator. We constrain this using a temporary type - __next__() call, whose return type is constrained to the collection type * Get rid of Generic NodeTy Need to generalize how we convert mamba types to Python types in generate stage. In particular: - When encountering types in the wild - When encountering constructors in the wild And _only_ in those situations so we don't accidentally change identifiers with say class names. * Add type annotation to non-nested builders * Get rid of tuple construct * Remove NameVariants * Simplify Name to Core in generation * Match generics when checking parent When looking up classes in context, we convert generic parents to concrete parents (in the form of StringNames). * Deal with variable generics for tuples * Rework identifier matching with ty, expr We added extra logic to deal with: - tuple literals - streamlining of tuples of identifiers Tuple matching still trips up when not matching with tuple literals. Perhaps we do need some logic in the unification stage, but this should be a last resort. * Name hash is deterministic * Recursively deconstruct builders * Reorder generation in lookup * Add extra __str__ rule to unify stage For tuples we make an exception by iterating over the elements and checking that they each define __str__(). Also add extra rule for self. In union, self is always equal to entity_name. Other arguments are left as-is. * Ensure nested Unions to_py deterministic * Remove unnecessary class and function union
Relevant issues
Expect::Collection
construct #437Summary
As has been a running theme for the past few days, this PR changes quite a lot more than originally intended.
However, we had some sloppy code which I figured would be best to clean up now instead of laborously splitting it over many PR's.
For now I see this a one in a set of major refactors, which for now is fine since I'm the only active developer.
Best to just improve the quality of the codebase now and get rid of as many bugs as possible by generalizing the type system as much as possible.
This includes getting rid of as much superfluous logic as possible.
Main change:
Except::Collection
toExpect::Call { ... }
Remove the collection Expect construct.
Instead, we use generics now and substitution of generics to deal with unification of collections.
Collection
type in annotatedAST
since that is not a valid type annotation in Python.Useful if we want to substitute temporary names.
Useful if we want to substitute generics which are temporary names.
This greatly simplifies a lot of exceptions we had to make for collections.
We also get to make use of type annotation logic now.
Secondary: Remove
NameVariant
Instead, we just make use of
Tuple[...]
andCallable[Tuple[...],[...]
by making helper methods which create these for us on the fly.Under the hood, it's always
StringName
.For now, I leave optionality untouched, so we don't make use of
Optional[...]
, but instead have a boolean inTrueName
.This makes it much easier to match names directly and simplifies a lot of substitution logic within
Name
.The changes here don't affect the codebase outside of
name
too much, because most of it was abstracted away.But it does greatly reduce the chances of introducing a bug.
And it also simplifies the unification stage even further.
To accomodate these changes, we also revamp the generic system:
Specifically, if the literal of the names are equal (checking the
lit
s inStringName { lit1, generics: [Name] }
), we check proceed to check for each generic whether self is name of other as long as the generic count is the same.Added Tests
TODO: list tests