Why are nested brackets disallowed?

Matthew Pickering matthewtpickering at gmail.com
Fri Jan 25 12:59:49 UTC 2019


That definition typechecks but doesn't do what you intend I think.

If you `lift (lift Bool)` then result of splicing this is of type
`Exp` and not `Q Exp` as you intended so you can't splice it again.

That is why my definition is more complicated and involves `return`.

Cheers,

Matt

On Fri, Jan 25, 2019 at 12:50 PM Richard Eisenberg <rae at cs.brynmawr.edu> wrote:
>
> This typechecks:
>
> instance Lift a => Lift (Q a) where
>   lift :: Q a -> Q Exp
>   lift x = join (fmap lift x)
>
> And it looks correct. Do you agree?
>
> In general, it sounds like you've thought this through. To me, this doesn't rise to the need of a ghc-proposal; I would say to go for it.
>
> Richard
>
> > On Jan 25, 2019, at 6:56 AM, Matthew Pickering <matthewtpickering at gmail.com> wrote:
> >
> > I don't think that cross stage persistence will work as it is
> > currently implemented which is probably why the check exists.
> >
> > 1. The normal case
> >
> > foo x = [| x |] ===>
> >  foo x = [| $(lift x) |]
> >
> > 2. x is defined at stage 0, and used at stage 2.
> >
> > One option is:
> > foo x = [| [| x |] |] ===>
> >  foo x = [| [| $($(lift (lift x))) |] |]
> > or
> > foo x = [| [| x |] |] ===>
> >  foo x = [| let x' = $(lift x) in [| $(lift [| x' |]) |]
> >
> > We need to think a bit how to `lift` something of type `Q Exp` because
> > of the `Q` monad. Lifting an `Exp` seems trivial as it's a normal ADT
> > (I tested and this works after deriving 40 instances).
> >
> > You can define `lift2` which lifts an expression twice as follows.
> >
> > ```
> > lift2 :: Lift a => a -> Q Exp
> > lift2 a = lift a >>= \e -> [| return $ $(lift e) |]
> > ```
> >
> > 3. x is defined at stage 1 and used in stage 2
> >
> > foo = [| \x -> [| x |] |] ===>
> >  foo = [| \x -> [| $(lift x) |] |]
> >
> > Desugared with a single call to `lift` like normal.
> >
> > 4. x is defined in stage 2 and used in stage 1
> >
> > foo = [| [| \x -> $(x) |] |]
> >
> > Rejected just like usual. `x` won't be bound when the splice is run.
> >
> > It seems that with some suitable care that things will work out when
> > lifting across multiple levels but that is the point where care needs
> > to be taken.
> >
> > Matt
> >
> >
> >
> > On Thu, Jan 24, 2019 at 5:46 PM Richard Eisenberg <rae at cs.brynmawr.edu> wrote:
> >>
> >> I think Geoff was primarily concerned with typed Template Haskell, not the untyped variety.
> >>
> >> I, too, have wondered if there was a technical reason behind this restriction, or if merely it was assumed that nested brackets were not worthwhile.
> >>
> >> One question: how would staging work between nesting levels of brackets?
> >>
> >> Richard
> >>
> >>> On Jan 24, 2019, at 12:42 PM, Ben Gamari <ben at smart-cactus.org> wrote:
> >>>
> >>> Matthew Pickering <matthewtpickering at gmail.com> writes:
> >>>
> >>>> There is a check in `RnSplice` which errors on the following program
> >>>> with nested brackets.
> >>>>
> >>> It might be good to explicitly include Geoff Mainland in this thread.
> >>> I'm not sure he'll see it otherwise.
> >>>
> >>> Cheers,
> >>>
> >>> - Ben
> >>>
> >>> _______________________________________________
> >>> ghc-devs mailing list
> >>> ghc-devs at haskell.org
> >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> >>
>


More information about the ghc-devs mailing list