#5375: Regression in newName
---------------------------------+------------------------------------------
    Reporter:  reinerp           |        Owner:                           
        Type:  bug               |       Status:  new                      
    Priority:  normal            |    Milestone:                           
   Component:  Template Haskell  |      Version:  7.3                      
    Keywords:                    |     Testcase:                           
   Blockedby:                    |   Difficulty:                           
          Os:  Unknown/Multiple  |     Blocking:                           
Architecture:  Unknown/Multiple  |      Failure:  GHC rejects valid program
---------------------------------+------------------------------------------

Comment(by reinerp):

 Interesting. I've been using {{{newName}}} as you said at the end of your
 comment: to make a fresh name which can't possibly be captured anywhere
 except by use of the produced {{{Name}}}, and as far as I can tell, this
 is exactly how {{{newName}}} has behaved until after ghc-7.0.3. So:

  * I would definitely like some function which produces genuinely
 uncapturable names.

  * Given that {{{newName}}} has produced genuinely uncapturable names up
 to and including ghc-7.0.3, I would suggest keeping it this way. If the
 "partial capturing" behaviour of ghc HEAD's {{{newName}}} is really
 necessary (I don't think it is; see below), then I would at least suggest
 implementing it under a new function name, to avoid changing the semantics
 of {{{newName}}}.

 == Examples ==
 As I said, however, I'm not convinced that a construct supporting "partial
 capturing" is actually necessary. On to the specifics of your examples!
 I'll talk about the examples without quotations {{{[| ... |]}}} first, and
 then I'll talk about quotations.

 {{{
 x = 4
 y = $(do { x <- newName "x"; return (LamE (VarP x) (VarE (mkName "x"))) })
 }}}

 I would have said we produce

 {{{
 x = 4
 y = \x' -> x
 }}}

 If you want to produce what you suggested, why not just write

 {{{
 x = 4
 y = $(return (LamE (VarP (mkName "x")) (VarE (mkName "x"))) })
 }}}

 Similarly, with
 {{{
 $( do { x <- newName "x"; return (ValD (VarP x) (LitE 3)) } )
 v = x
 }}}
 I would expect
 {{{
 x' = 3
 v = x
 }}}
 Otherwise, why not use {{{mkName}}}? Similarly, I'd expect
 {{{
 -- declare 'data E = D' with a fresh name 'D'
 $(do
     nm <- newName "D"
     return $ [DataD [] (mkName "E") [] [NormalC nm []] []] )

 f :: E
 f = D
 }}}
 to produce:
 {{{
 data E = D'
 f = D
 }}}

 But I definitely agree with you on your examples involving quotations. So,
 for instance, this:

 {{{
 $( [d| data E = D |] )
 f :: E
 f = D
 }}}
 should compile successfully (and indeed it does in ghc-7.0.3), as should
 the example in #5037.

 I think the way to achieve the correct behaviour for quotations is simply
 to use {{{mkName}}} in the desugarer, rather than using {{{newName}}}.

 == My suggestion ==
 In summary, I think we should:
  * revert the recent changes to {{{newName}}}
  * make the desugarer use {{{mkName}}} instead of {{{newName}}}

 Let me clarify what I mean when I say "use {{{mkName}}}" in the desugarer.
 Given this:
 {{{
 import Prelude(map)
 g = [| map (\x -> x) |]
 }}}

 the name {{{map}}} should be bound to {{{Prelude.map}}}, whereas both
 occurrences of the name {{{x}}} should be created using {{{mkName}}}. That
 is, the quotation should desugar to:

 {{{
 g = AppE (VarE ''map) (LamE [VarP (mkName "x")] (VarE (mkName "x")))
 }}}

 Here's the rule. When encountering a name in a quotation:
  * if the binding for that name is outside the quotation (like {{{map}}}
 above), use a {{{NameL}}} or {{{NameG}}} as appropriate
  * if the binding for that name is inside the quotation, use {{{mkName}}}
 (i.e. a {{{NameS}}})
  * if a binding for that name can't be found, produce an error (this is
 what ghc currently does)

 Note that what I suggest should leave almost all Template Haskell programs
 with the same semantics, and allow a few more (such as the one in #5037)
 to compile. Even quotations relying on shadowing, such as

 {{{
 f = $( [| \x -> (\x -> x) |] )
 }}}

 should behave the same as before: the only difference is that the
 shadowing is resolved after splicing rather than during desugaring of the
 quotation.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/5375#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler

_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to