Hello, list.

This is a topic that we've briefly discussed in past, and it has come to
our attention again while working on some refactoring in the libraries with
Stéphane.

When implementing recursive systems, I often end up using this pattern as
it allows me to write versatile and readable code:

fun(param0, ..., paramN) = loop ~ si.bus(M)
    with {
        loop(state0, ..., stateM) = y0, ..., yM
            with {
                y0 = state0 * param0;
                ...
            };
    };

Consider this function:

onePoleSwitching(att, rel, x) = loop ~ _
with {
loop(yState) = (1.0 - coeff) * x + coeff * yState
with {
coeff = ba.if(x > yState, ba.tau2pole(att), ba.tau2pole(rel));
};
};

We cannot write this using `letrec` as in this example:

onePoleSwitching(att, rel, x) = y
    letrec {
        'y = (1.0 - coeff) * x + coeff * y;
    }
        with {
            coeff = ba.if(x > y, ba.tau2pole(att), ba.tau2pole(rel));
        };


since `y` is not visible within the `with` scope.

We could write:

onePoleSwitching(att, rel, x) = y

letrec {
'coeff = ba.if(x > y, ba.tau2pole(att), ba.tau2pole(rel));
'y = (1.0 - coeff) * x + coeff * y;
};

but this would introduce a delay in the `coeff` signal, which would make
the filter output not correct.

What I was wondering is, since the first implementation using `with` is
possible, could we combine `with` and `letrec` for a more concise and
powerful environment such as the example below or is there anything that
I'm missing in the syntax that makes it non-computable?

onePoleSwitching(att, rel, x) = y

with {
'y = (1.0 - coeff) * x + coeff * y;
coeff = ba.if(x > y, ba.tau2pole(att), ba.tau2pole(rel));
};

Ciao,
Dario

Dr Dario Sanfilippo
http://dariosanfilippo.com
_______________________________________________
Faudiostream-users mailing list
Faudiostream-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-users

Reply via email to