[<<][meta][>>][..]
Sat Dec 24 08:59:57 EST 2011

Flat structures

So.. Should structures always be flattened?  Maybe there's something
to say for Term keeping the binary tree structure.  Flattening does
seem a bit arbitrary.

What's the real point?  Eventually, compiling to C, the data structure
*does* need to be flattened.  Whether this is done in one of the two
following ways doesn't matter much, except for how get/set is
implemented:

    struct {
        float m0;
        float m1;
        float m2;
    };

    struct {
        float car;
        struct {
            float car;
            float cdr;
        } cdr;
    };

The latter seems a bit more "honest" to me.

Also, it might be good to add tuple naming to Term to avoid having to
do this in the C generator (non-monadic PrettyC).  Could be a way out,
though it seems rather awkward..  Let's not.

Also, for arguments in lambda and apply it seems simpler to just stick
with lists.

Back to confusion.  How to specify struct member get/set?

Backtracking a bit, the issue of indexing can be completely
sidestepped if pack/unpack is done in one operation, so let's try that
first.  The problem with that is that there is no multiple-variable
binding form at this point.  The only such form is Lambda.  Maybe
that's the first thing to add?  I.e. this would support primitive
multi-valued ops too.

So, looping further..  Maybe a separate multi-var LetStruct is really
better.  This separates structuring and value return, which then could
be a structure.

There is an assymetry if we're going with all at once unpacking: the
Unpack needs to be a binding form because it introduces multiple
binders.  The Pack operation can be the same as ordinary application.

This assymetry comes from a many->one assymetry that's already present
because tree-like (expressions), and not DAG-like.  This is an
essential structural element.  Trees are really easier to handle in
anything that has t do with notation.  DAGs can be built on top of
trees by introducing binders = opening up the graph structure.

Anyways, this is what _pack -> Pack looks like.  I have no idea how to
recover that type though..  After the flattening introduced by
structCompile it's really gone.  However, from the list of varrefs a
type could be reconstructed at ->C compile time.

  _pack ras = return $ packed where
    packed = Code $ Pack typ refs
    refs = structCompile ras
    typ = undefined -- FIXME: ???
    
Let's just kick that type out for now:


  _pack ras = return $ packed where
    packed = Code $ Pack refs
    refs = structCompile ras
   

  t25 = term $ _pack (Atom $ lit (1 :: Int), 
                      (Atom $ lit (2 :: Int),
                       Atom $ lit (3 :: Int)))
                     

  *Main> t25
  Pack [Lit (Type int []) "1",
        Lit (Type int []) "2",
        Lit (Type int []) "3"]



For _unpack we ahve something that this is very similar to _lambda,
which is also a multi-variable binding form.

  _unpack (Code as) body = do
    (structVars, structCode) <- mStruct "a"
    (Code body) <- mBlock $ body structCode
    return $ Code $ Unpack structVars as body
  
  t26 = term $ do
    p <- _pack (Atom $ lit (1 :: Int), 
                (Atom $ lit (2 :: Int),
                 Atom $ lit (3 :: Int)))
    _unpack p (\(Atom a, (Atom b, Atom c)) ->
                _ret b)


Problem with previous def of _pack is that it doesn't introduce a
variable.  Fixing that (replace 'return' with 'mVar') a missing
instance TMLprim (Atom t) arose.  After fixing that and a missing case
of show Apair, we get:

  *Main> t25
  Let (Var {varType = Type (int,(int,int)) [], varName = "t0"})
      (Pack [Lit (Type int []) "1",
             Lit (Type int []) "2",
             Lit (Type int []) "3"])
   (Ref (Var {varType = Type (int,(int,int)) [], varName = "t0"}))

  *Main> t26
  Let (Var {varType = Type (int,(int,int)) [], varName = "t0"}) 
      (Pack [Lit (Type int []) "1",
             Lit (Type int []) "2",
             Lit (Type int []) "3"])
    (Unpack [Var {varType = Type int [], varName = "a1"},
             Var {varType = Type int [], varName = "a2"},
             Var {varType = Type int [], varName = "a3"}]
        (Ref (Var {varType = Type (int,(int,int)) [], varName = "t0"}))
      (Ret (Ref (Var {varType = Type int [], varName = "a2"})))) 



[Reply][About]
[<<][meta][>>][..]