Changeset 00ad2a0
- Timestamp:
- May 20, 2025, 12:22:33 AM (4 months ago)
- Branches:
- master
- Children:
- 4791307
- Parents:
- 206f4cf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/fangren_yu_MMath/resolution.tex
r206f4cf r00ad2a0 504 504 where one can be uniquely resolved and allow the type @T@ to be inferred immediately, and another has many ways to be resolved, each resulting in @T@ being bound to a different concrete type. 505 505 If the first assertion is examined by the algorithm, the inferred type can then be utilized in resolving the second assertion eliminating many incorrect options without producing a list of candidates requiring further checks. 506 In practice, this have a significant impact when an unbound type @T@ is declared to satisfy the basic \emph{object assertions}\footnote{The term is borrowed from object-oriented languages although \CFA is not object-oriented.} of having a default constructor, destructor, and copy assignment operations. 507 Since these functions are implicitly defined for almost every type in scope, there can be hundreds or even thousands of matches to these functions with an unspecified operand type. 508 In most cases, the value of @T@ can be inferred by resolving other assertions first, and then the object lifetime-functions can easily be fulfilled since functions are sorted internally by the operand type; 509 because of its size, this optimization greatly reduces the number of wasted resolution attempts. 510 511 This issue also limits the capability of the assertion resolution algorithm. 506 In practice, this have a significant impact when an unbound type @T@ is declared to satisfy the basic \emph{object assertions}\footnote{The term is borrowed from object-oriented languages although \CFA is not object-oriented.} of having a default constructor, destructor, and copy assignment operations. Since these functions are implicitly defined for almost every type in scope, there can be hundreds or even thousands of matches to these functions with an unspecified operand type. 507 508 Based on this observation, I implemented an optimization to the assertion resolution algorithm that will only attempt to resolve object assertions after all other assertions are resolved successfully, and further delay resolving object assertions with an unbound first argument type, \ie the type of the argument being constructed or destructed, until no progress can be made otherwise. 509 This simple optimization on assertion resolution order eliminates over 80 percent of unbound object lifetime function lookups. 510 In most cases, the operand type can be inferred by resolving other assertions first, and then the object lifetime functions can be looked up efficiently, since these functions are indexed by the operand type in the identifier table of the compiler. 511 Although the unbound parameter case appears infrequently in practice, it is potentially very costly due to thousands of wasted type unification runs each time it occurs. As a result, this optimization is able to produce an overall compilation speedup of around 10 percent. 512 513 The issue of having unbound parameters also limits the capability of the assertion resolution algorithm. 512 514 Assertion matching is implemented to be more restrictive than expression resolution in general, in that the parameter types must match exactly, rather than just merely callable. 513 515 If a function declaration includes the assertion @void f(T)@ and only a @f(long)@ is in scope, trying to resolve the assertion with @T == int@ does not work. … … 520 522 Currently, type resolution cannot do enough return-type inferencing while performing eager assertion resolution: the return type information is unknown before the parent expression is resolved, unless the expression is an initialization context where the variable type is known. 521 523 By delaying the assertion resolution until the return type becomes known, this problem can be circumvented. 522 The truly problematic case occurs if a type variable does not appear in either of the parameter or return types and only appears in assertions or variables (\newterm{associate types}).524 The truly problematic case occurs if a type variable does not appear in either of the parameter or return types and only appears in assertions or variables (\newterm{associated types}). 523 525 \begin{cfa} 524 526 forall( T | { void foo( @T@ ) } ) int f( float ) { … … 526 528 } 527 529 \end{cfa} 528 This case is rare so forcing every type variable to appear at least once in parameter or return types does not limit the expressiveness of \CFA type system to a significant extent.529 \VRef{s:AssociatedTypes} presents a proposal for including type declarations in traits rather than having all type variables appear in the trait parameter list, which provides equivalent functionality to an unbound type parameter in assertion variables, and also addresses some of the variable cost issue discussed in \VRef{s:ExpressionCostModel}.530 This case is rare, so forcing every type variable to appear at least once in parameter or return types does not limit the expressiveness of \CFA type system to a significant extent. 531 \VRef{s:AssociatedTypes} presents a proposal for including type declarations in traits rather than having all type variables appear in the trait parameter list, which provides equivalent functionality to an unbound type parameter in assertion variables, serves as a guidance to the resolution algorithm that works in more general cases than the specific optimization for object assertions mentioned above, and also addresses some of the variable cost issue discussed in \VRef{s:ExpressionCostModel}. 530 532 531 533
Note:
See TracChangeset
for help on using the changeset viewer.