ekmett / ekmett/reflection

Can we get inlining with a skolem?

Open
#31 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
105
Forks
24
PR merge metrics
No merged PRs in 30d

Description

Currently, `reflection` clogs up the inliner pretty badly. The following modification seems to fix this, but there could be some gotcha somewhere.

``` haskell
data Skolem = Skolem
newtype Magic a r = Magic (Reifies Skolem a => Proxy Skolem -> r)
```

The function passed to `reify`, of type `forall (s :: *). Reifies s a => Proxy s -> r`, can certainly be passed to `Magic` (automatically instantiating `s` to `Skolem`).

For example, using this definition,

``` haskell
foo :: Int -> Int
foo x = reify (5 :: Int) $ \(p :: Proxy s) -> reflect p + x
```

yields

``` haskell
foo :: Int -> Int
foo =
\ (x_a4WB :: Int) ->
case ((\ _ -> I# 5) `cast` ...) ((Proxy) `cast` ...)
of _ { I# x1_a9qY ->
case x_a4WB of _ { I# y_a9r2 -> I# (+# x1_a9qY y_a9r2) }
}
```

The only remaining traces of reflection are the `Proxy` and the failure to unbox `5`. Note that `Tagged`-based reflection manages to get rid of absolutely all traces even when `Proxy`-based reflection is built on top of it:

``` haskell
class Reifies s a | s -> a where
reflect' :: Tagged s a

data Skolem = Skolem

newtype Magic a r = Magic (Reifies Skolem a => Tagged Skolem r)

reify' :: forall a r . a -> (forall (s :: *) . Reifies s a => Tagged s r) -> r
reify' a k = unsafeCoerce (Magic k :: Magic a r) a
{-# INLINE reify' #-}

reflect :: Reifies s a => proxy s -> a
reflect = proxy reflect'
{-# INLINE reflect #-}

reify :: forall a r . a -> (forall (s :: *) . Reifies s a => Proxy s -> r) -> r
reify a k = reify' a (unproxy k)
{-# INLINE reify #-}
```

With these definitions, `foo` compiles to

``` haskell
foo :: Int -> Int
foo =
\ (x_aDk :: Int) ->
case x_aDk of _ { I# y_a12D -> I# (+# 5 y_a12D) }
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.