Changes between Version 1 and Version 2 of UnresolvedInfixExpressions

Nov 6, 2010 5:52:07 AM (5 years ago)



  • UnresolvedInfixExpressions

    v1 v2  
    1919data Exp =
    2020     ...
    21      | UnresolvedInfixE [(Exp, Exp)] Exp Section
     21     | UnresolvedInfixE [(Exp, Op)] Exp Section
    2222     ...
    24 and we add the following datatype:
     24and we add the following type synonym and datatype:
     26type Op = Exp
    2627data Section = NoSection
    2728             | LeftSection Exp
    9697 InfixE (Just e1) op Nothing      <--->    UnresolvedInfixE []        e1 (RightSection op)
    9798 InfixE Nothing   op Nothing   <------------ this will be rejected when splicing.
     99 e                                <--->    UnresolvedInfixE []        e NoSection
    99   In view of the previous dot point, we see that there is also no special treatment for trees of {{{InfixE}}} and {{{UnresolvedInfixE}}} constructors.
     101  In view of the previous dot point, we see that there is no special treatment for trees of {{{InfixE}}} and {{{UnresolvedInfixE}}} constructors.
     102  [[BR]]
     103  These equivalences tell us that {{{UnresolvedInfixE}}} expressions are unambiguous if either:
     104     * the list has length 0; or
     105     * the list has length 1 and we have {{{NoSection}}}
     106  The redundancy introduced by these equivalences is discussed further down.
    100107 * The following two syntax trees:
    113120  This demonstrates that it is necessary to include sectioning information in the {{{UnresolvedInfixE}}} constructor, as we do not want to silently convert illegal section expressions (such as {{{(2 + 3 +)}}} when {{{(+)}}} is right-associative) into legal, but different, section expressions (say {{{((2 + 3) +)}}}).
     122== Template Haskell Quotations and {{{UnresolvedInfixE}}} ==
     123If we have a Template Haskell quote containing infix expressions, for example
     125 foo = [| x + y * z |]
     127then how will these infix expressions be represented?
     129The important point is: '''the infix expressions will have already been resolved'''. (This is because GHC knows that {{{(+)}}} and {{{(*)}}} in the above example refer to the in-scope ones, so the fixities are known when the quote is constructed -- so we should certainly communicate this information.)
     131The precise representation of the (already-resolved) infix expressions will depend on whether the {{{InfixE}}} constructor will be removed, as discussed in the following section. At present, we can say the following:
     132 * if the {{{InfixE}}} constructor is ''not'' removed, then (already-resolved) infix expressions will be written in terms of the {{{InfixE}}} constructor, as is currently the case.
     133 * if the {{{InfixE}}} constructor ''is'' removed, then infix expressions will be written in terms of unambiguous {{{UnresolvedInfixE}}} expressions (see above for discussion of when {{{UnresolvedInfixE}}} expressions are unambiguous).
     135== Redundancy; should {{{InfixE}}} be removed? ==
     136Because of the equivalences discussed earlier, we see that the {{{InfixE}}} constructor will be completely redundant after these changes. It is not clear to me what this means for design. The following are some options.
     137 * We could remove the {{{InfixE}}} constructor. Unfortunately, this means that every TH program which generates infix expressions would have to be changed.
     138 * We could modify the {{{UnresolvedInfixE}}} constructor to remove the ambiguity -- the idea being that {{{UnresolvedInfixE}}} is reserved for infix expressions which are truly ambiguous. This would involve requiring the list to be of length >=2 when we have {{{NoSection}}}, and length >=1 when we have {{{LeftSection}}} or {{{RightSection}}}. To do this the most obvious way ("unrolling" part of the list) unfortunately makes the constructors very large:
     140 data Exp =
     141    ...
     142    | UnresolvedInfixE       [(Exp,Op)] Exp Op Exp Op Exp
     143    | UnresolvedLeftSection  Op Exp Op Exp [(Op,Exp)]   
     144    | UnresolvedRightSection [(Exp,Op)] Exp Op Exp Op
     146 * We could put up with the redundancy, and perhaps write a {{{convertUnambiguousToInfixE :: Exp -> Exp}}} which converts all unambiguous {{{UnresolvedInfixE}}}s to {{{InfixE}}}s.
     148== Is there a better definition of {{{UnresolvedInfixE}}}? ==
     149The definition of {{{UnresolvedInfixE}}} I have given above is somewhat ugly, because it suggests an asymmetry which is not actually present. However, it manages to enforce the precise relationship that must hold between the number of operators and the number of operands -- which, for example, {{{InfixE}}} does not currently enforce.
     151Is there a better definition of this constructor?