Sun Jan 20 13:17:55 CET 2013

Stream fold

- specification:  (lambda/fold (s0 s1) (i0 i1)
                      (values/fold (q r) (s t)))

- compilation: somehow this needs to make it into the SSA compiler.
  what does it need to know?

It doesn't seem accessible.  This needs a second layer, i.e. a second
"language".  Something that can generate primitives that are plugged
into the other language.

It's really a type issue: stream language operates on streams, not on
scalar samples..

The point in the code where this information needs to be exposed is:

  (define ((e-op op) a b)    (node 0 1 #`(#,op #,a #,b)))
  (define ((e-stream op) x)  (node 1 1 #`(#,op #,x)))

It will work if we can attach something to the `op' syntax identifier.

Hmm.. this stuff is hard to reason about.

This should be done in a boostrap phase:

Phase 1: Use make-ssa-compiler without the stream extensions to compile a bunch of functions that can be tagged as stream processors.

Phase 2: Use make-ssa-compiler again, but this time extended with a
bunch of extra "primtives".

Note that primitives are modeled as Scheme functions now, not syntax,
so this should be straightforward.  Trouble is keeping all the ducks
in a row.

- Turn semantics into a list to make it easier to extend.

Let's think about this some more.  Can't this be used to define a
primitive that does this particular tagging?  I.e. something like:

   (let* ((b (causal 1 (f a)))) ...)

where `causal' indicates that the following function is the
specification of a causal system with 1 state variable.

Let's try this.

The causal form then probably needs to be a macro such that it can
delay the execution of the usual binding form.

Wait.. should the language be abstracted as call by name to leave the
evaluation order up to the abstract interpretation?  Let's give that a
try first.

Hmm, seems to hard to change.  Let's just use a macro for now then see
what happens.

It seems that "causal" needs to be a macro, creating a "state
injection" form, something like

(causal 2 (f a b))

-> (_causal 2 (lambda (s0 s1) (f s0 s1 a b)))

Still, this looks like cheating, i.e. mixing implementation of a
single feature in both the surface syntax and the abstract
interpretation, but I do not see any way around this when using strict
evaluation by default.

Let's build it and see where it goes.

Starts to make sense..  The trouble is opacity of types..

Ok, I got it working.
Ticky part is to distinguish:
- Binding of output variables: these are just primitive nodes!
- Performing the state assignment separately