
#14770: Allow static pointer expressions to have static pointer free variables -------------------------------------+------------------------------------- Reporter: TheKing01 | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.2 Resolution: | Keywords: | StaticPointers Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by mpickering): I think the comment in comment:2 is suggesting that the result of a `static` expression is *not* a `StaticPtr`. Terminology: * A `StaticPtr` is something which resides in the static pointer table. * A `Closure` is an expression which can be serialised. We now distinguish the two situations with two keywords. * `static <e :: T>` creates a value of `StaticPtr T` where `e` is placed in the SPT. The current restrictions about static forms apply to `e`. * `closure <e :: T>` creates a value of `Closure T` as per the proposal, free variables in `e` are allowed to refer to values of type `Closure`. We first give the concrete definition of `Closure` which is a simplified version of `Closure` from the [https://hackage.haskell.org/package/static-closure static-closure] package. {{{ data Closure a where CPure :: Closure (ByteString -> a) -> ByteString -> a -> Closure a CStaticPtr :: StaticPtr a -> Closure a CAp :: Closure (a -> b) -> Closure a -> Closure b }}} Then the RHS of `addPointers` from the original post desugars to: {{{ addPointers :: Closure Int -> Closure Int -> Closure Int addPointers c1 c2 = closure ( $$c1 + $$c2 ) ===> addPointers c1 c2 = static (+) `CAp` c1 `CAp` c2 }}} Static parts of the expression are still added to the SPT by using `static`. Dynamic parts of the expression are then applied using `CAp`. This definition also allows us to directly embed serialisable values into the static form. {{{ addOneToPointer :: Closure Int -> Closure Int addOneToPointer p = closure (1 + $$p) ===> addOneToPointer c1 = static (+) `CAp` (CPure (static decode) (encode 1) 1) `CAp` c1 }}} The mechanical transformation that we're performing here is we take a static form, abstract over the spliced variables and then reapply the result of the splice. Let floating the splices in essence. This definition of `Closure` still allows us to serialise a `Closure` to a bytestring and deserialise it. It also allows us to "dereference" the closure just like you can dereference a `StaticPtr`. I think the whole `static-closure` library is lovely and looks like a nice way to make writing `StaticPointers` code more easily. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14770#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler