Skip to content
  • Matthew Pickering's avatar
    a6257192
    Use a newtype `Code` for the return type of typed quotations (Proposal #195) · a6257192
    Matthew Pickering authored and Ben Gamari's avatar Ben Gamari committed
    There are three problems with the current API:
    
    1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition
       of two type constructors. Doing so in your program involves making your own newtype and
       doing a lot of wrapping/unwrapping.
    
       For example, if I want to create a language which I can either run immediately or
       generate code from I could write the following with the new API. ::
    
          class Lang r where
            _int :: Int -> r Int
            _if  :: r Bool -> r a -> r a -> r a
    
          instance Lang Identity where
            _int = Identity
            _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f)
    
          instance Quote m => Lang (Code m) where
            _int = liftTyped
            _if cb ct cf = [|| if $$cb then $$ct else $$cf ||]
    
    2. When doing code generation it is common to want to store code fragments in
       a map. When doing typed code generation, these code fragments contain a
       type index so it is desirable to store them in one of the parameterised
       map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from
       ``parameterized-utils``.
    
       ::
    
          compiler :: Env -> AST a -> Code Q a
    
          data AST a where ...
          data Ident a = ...
    
          type Env = MapF Ident (Code Q)
    
          newtype Code m a = Code (m (TExp a))
    
       In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``.
       Using one of these map types currently requires creating your own newtype and constantly
       wrapping every quotation and unwrapping it when using a splice. Achievable, but
       it creates even more syntactic noise than normal metaprogramming.
    
    3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is
       easier. This is a weak reason but one everyone
       can surely agree with.
    
    Updates text submodule.
    a6257192
    Use a newtype `Code` for the return type of typed quotations (Proposal #195)
    Matthew Pickering authored and Ben Gamari's avatar Ben Gamari committed
    There are three problems with the current API:
    
    1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition
       of two type constructors. Doing so in your program involves making your own newtype and
       doing a lot of wrapping/unwrapping.
    
       For example, if I want to create a language which I can either run immediately or
       generate code from I could write the following with the new API. ::
    
          class Lang r where
            _int :: Int -> r Int
            _if  :: r Bool -> r a -> r a -> r a
    
          instance Lang Identity where
            _int = Identity
            _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f)
    
          instance Quote m => Lang (Code m) where
            _int = liftTyped
            _if cb ct cf = [|| if $$cb then $$ct else $$cf ||]
    
    2. When doing code generation it is common to want to store code fragments in
       a map. When doing typed code generation, these code fragments contain a
       type index so it is desirable to store them in one of the parameterised
       map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from
       ``parameterized-utils``.
    
       ::
    
          compiler :: Env -> AST a -> Code Q a
    
          data AST a where ...
          data Ident a = ...
    
          type Env = MapF Ident (Code Q)
    
          newtype Code m a = Code (m (TExp a))
    
       In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``.
       Using one of these map types currently requires creating your own newtype and constantly
       wrapping every quotation and unwrapping it when using a splice. Achievable, but
       it creates even more syntactic noise than normal metaprogramming.
    
    3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is
       easier. This is a weak reason but one everyone
       can surely agree with.
    
    Updates text submodule.
Loading