Sat Aug 27 08:53:24 CEST 2011

Sharing revisited

It's clear from the previous example that sharing (observable through
abstract evaluation) is necessary.  This means that when defining the
integrator int we already need to add a constraint on the data types
that allows the use of an expression like:

        let_  expr body

The trouble here is syntax.  It's going to be ugly.

When designing the do notation, the main constraint is that we want
expressions like

           m t -> m t -> m t

instead of "machine code" like

           t -> t -> m t

Previously I thought it better to not use do notation at all, and just
use the let_ construct.  Let's see what it takes to make this work.

Anyways, trying to bride SymAsm.hs with SigOp.hs
For now, just use an explicit DFL class:

  class DFL v r where
    var :: v -> (v -> r) -> r
    -- Default is no sharing.
    var v b = b v
Trouble is that tupling doesn't go well with Sym.  So maybe this needs
automatic distribution?

    No instance for (DFL (Asm Tint) (Asm Tint, Asm Tint))

Ok, got some wrap/unwrap problem.  
Maybe it's simpler to catch it at the root and define a Monad instance for Asm.

What i really want is Asm (Tint, Tint).  The reason seems to be that
tupling is not embedded in the language.  I'm using the metalanguage

I thought this would be no problem but apparently it doesn't work for
let.  Let's remove that approach and use the let_ from Sym.  This then
needs a different int.

Same problem using the let_ from Sym:

  int' = SigOp (\(s, i) -> let_ (i `iadd` s) (\o -> (o, o))) 0

This returns (SymAsm a, SymAsm b) and not (SymAsm (a,b)).  How to fix
that?  It seems like a serious problem.

What it looks like is that when I DSL-ify, lot's of native constructs
can't be used: if let (,)

The problem is that I don't have a good mental model of what is object
language, and what is meta language.  In my mind, the tuples should
just be "unrolled" to form some kind of data dependency structure.

Does it help to allow let_ to be more general?

Doesn't seem so..

This is a problem.  I don't understand it.

It seems the only way around this is to allow let_ to have generic
return type.

Or, to just mix let and let_ like this:

   int' = SigOp (\(s, i) -> let o = let_ (i `iadd` s) id in (o,o)) 0

Which is more like the approach in the sharing monad in [1].
Essentially the let_ can be replaced with "share" as

   share x = let_ x id

This looks like it's a better approach.  Nope.  It's not the same.
This is still not CPS because the body of the bind is not executed in
the correct context.

This approach is too difficult.  I need something simpler.

Maybe it's best to express the language as a monad, and use the do
form for the binding.  That way there is no room for obscure sharing
problems.  Expressions can be built on top of that using the same
trick as for LLVM.

The question then remains: would it still be possible to use SigOp ?

[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=