Sun Jul 24 13:44:11 CEST 2011

Representing "let" in the final language

It seems that in order to use the sharing approach, it might be best
to define it directly in the language itself, or as an extension to

Following the lam amd app examples in the tagless paper it seems that
there need to be 2 elements: a term to bind, and a body to bind it
in.  The result is another term.

class Symantics r => SymanticsLet r where
  -- term -> body -> result
  letS  :: r a -> r (a -> b) -> r b

Let's see if this can be implemented.

Indeed it can be.  I came to this:

class Symantics r => SymanticsLet r where
  -- name -> body -> value
  letS  :: r a -> r (a -> b) -> r b
  body  :: (a -> b) -> r (a -> b)
instance SymanticsLet Eval where
  body = Eval
  letS (Eval term) (Eval body) = Eval $ body term

expr6 = letS (int 3) (body $ \x -> x * x)

The "body" is probably not necessary by building it into the let.

The "lam" in the paper maps (r a -> r b) -> r (a -> b).  The input is
a body, the output is the representation of a function.  So maybe I
should use (r a -> r b).

So it seems to be even simpler then:

class Symantics r => SymanticsLet r where
  letS  :: r a -> (r a -> r b) -> r b
  -- Default implementation just substitutes
  letS term body = body term
instance SymanticsLet Eval 
instance SymanticsLet Code

An implementation that needs to capture the sharing structure then
needs to fill out this operation differently.