[GHC] #14770: Allow static pointer expressions to have static pointer free variables

GHC ghc-devs at haskell.org
Fri Sep 7 16:27:31 UTC 2018


#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


More information about the ghc-tickets mailing list