In looking into my TH bug stack, I've found the following question. Suppose we have d1 :: Q [Dec] d1 = return [FunD (mkName "f") ...] d2 :: Q [Dec] d2 = do { fn <- newName "f"; return [FunD fn ...] } QUESTION 1: is this OK: $d1 h = f 3 QUESTION 2: What about this? $d2 h = f 3 The answer to Q1 must presumably be 'yes', but what about Q2. "newName" generates a fresh name, to be sure, but does it bind the 'f' in the subsequent declaration. I think the answer is probably 'yes'. COnsier [| \x -> f $(dyn "x") |] Here I think we all agree the $(dyn "x") picks up the binding for 'x', even though the binding must be generated with newName. And (returning to Q2), the "top-level splice hack" treats everything following the top-level splice as if it were (dyn "f") stuff. But a 'yes' to Q2 might be considered inconvenient, because you might generate lots of (newName "f"), and they'd then clash. Views? Simon
Simon Peyton-Jones wrote:
[cut]
But a 'yes' to Q2 might be considered inconvenient, because you might generate lots of (newName "f"), and they'd then clash.
Views?
Erm confusing... what about: d2 :: Q [Dec] d2 = do f1 <- newName "f" f2 <- newName "f" fn1 <- funD f1 ... fn2 <- funD f2 ... return [fn1,fn2] Keean
On Thu, Nov 25, 2004 at 02:06:27PM -0000, Simon Peyton-Jones wrote:
In looking into my TH bug stack, I've found the following question.
Here's what I think should happen:
Suppose we have
d1 :: Q [Dec] d1 = return [FunD (mkName "f") ...]
d2 :: Q [Dec] d2 = do { fn <- newName "f"; return [FunD fn ...] }
QUESTION 1: is this OK:
$d1 h = f 3
QUESTION 2: What about this?
$d2 h = f 3
The answer to Q1 must presumably be 'yes',
Yes - mkName "f" gives you the same name as just writing f.
but what about Q2. "newName" generates a fresh name, to be sure, but does it bind the 'f' in the subsequent declaration.
No - here you have created a name that only looks a bit like f - it is not the same as f. In fact, were you to pprint the above you should get something like f_4 = ... h = f 3 The only way to refer to a newName is with the result of that call.
I think the answer is probably 'yes'. COnsier [| \x -> f $(dyn "x") |]
Here dyn calls mkName so you get the same name as would just writing x. So it gets bound to that \x.
Here I think we all agree the $(dyn "x") picks up the binding for 'x', even though the binding must be generated with newName. And (returning to Q2), the "top-level splice hack" treats everything following the top-level splice as if it were (dyn "f") stuff.
I don't think it should. If you did [d| f = ... |] then that should use mkName, but if you explicitly construct something with newName then that should be respected. After all, there is no gain for using newName if you want to refer to it as f later, as you'd need to make sure there are no name collisions so you may as well have just used mkName in the first place. The only reason to use newName is /because/ you don't want it to bind f (or to conflict with another newName).
But a 'yes' to Q2 might be considered inconvenient, because you might generate lots of (newName "f"), and they'd then clash.
Indeed; $d1 $d2 , $d2 $d2 and $d2 f = ... should cause no name clashes, but both $d1 $d1 and $d1 f = ... should. Thanks Ian
I agree with Ian, newName should generate unique names that no not bind anything else. Duncan On Thu, 2004-11-25 at 18:41 +0000, Ian Lynagh wrote:
On Thu, Nov 25, 2004 at 02:06:27PM -0000, Simon Peyton-Jones wrote:
In looking into my TH bug stack, I've found the following question.
Here's what I think should happen:
Suppose we have
d1 :: Q [Dec] d1 = return [FunD (mkName "f") ...]
d2 :: Q [Dec] d2 = do { fn <- newName "f"; return [FunD fn ...] }
QUESTION 1: is this OK:
$d1 h = f 3
QUESTION 2: What about this?
$d2 h = f 3
The answer to Q1 must presumably be 'yes',
Yes - mkName "f" gives you the same name as just writing f.
but what about Q2. "newName" generates a fresh name, to be sure, but does it bind the 'f' in the subsequent declaration.
No - here you have created a name that only looks a bit like f - it is not the same as f. In fact, were you to pprint the above you should get something like
f_4 = ... h = f 3
The only way to refer to a newName is with the result of that call.
Hi, I am trying to generate classes on the fly... as classes may get generated more than once, I want guaranteed unique names (sounds like a job for newName)... However, whilst the first example works, the second fails:
-- this works test :: Q [Dec] test = do k <- newName "k" c <- classD (cxt []) (mkName "MyClass") [k] [] [] return [c]
-- this fails test :: Q [Dec] test = do n <- newName "MyClass" k <- newName "k" c <- classD (cxt []) n [k] [] [] return [c]
In the second case this error is given: ghc-6.3: panic! (the `impossible' happened, GHC version 6.3): nameModule MyClass{tc a3dX} Is this a bug? How easy is it to fix? Regards, Keean.
participants (4)
-
Duncan Coutts -
Ian Lynagh -
Keean Schupke -
Simon Peyton-Jones