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