I don't think it warrants syntax, but might be nice in a macro. I've had
cases where I just put my entire simulation state in a single object, so I
don't need to give 100s of parameters to every object. In that case (where
the object is more of a container than an abstraction), it might be nice to
use.


On Thu, Jun 12, 2014 at 12:13 AM, Andrew Simper <andrewsim...@gmail.com>
wrote:

> So just to post again to make things clearer, right now algorithms tend to
> look pretty ugly and obfuscated since you have to prefix function arguments
> with the argument names using dot notation:
>
> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>     local v1::Float64 = coef.g0*state.ic1eq - coef.g1*state.ic2eq
>     local v2::Float64 = coef.g1*state.ic1eq + coef.g0*state.ic2eq
>     SvfSinOsc (2*v1 - state.ic1eq, 2*v2 - state.ic2eq)
> end
>
>
> This is a lot more readable to me, and it would be super useful to have a
> "using" type operation similar to namespace but it could run on variables
> instead, so that although writing the following is equivalent to what is
> above, it is much easier to see what is going on:
>
> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>     using state, coef
>     local v1::Float64 = g0*ic1eq - g1*ic2eq
>     local v2::Float64 = g1*ic1eq + g0*ic2eq
>     SvfSinOsc (2*v1 - ic1eq, 2*v2 - ic2eq)
> end
>
> What are peoples opinions on this? Would anyone else find it useful?
>
>
>
> On Friday, June 6, 2014 3:17:31 PM UTC+8, Andrew Simper wrote:
>>
>> In implementations where you want named data, I've noticed that the
>> algorithm gets obfuscated by lots of variable names with dots after them.
>> For example, here is a basic analog model of a state variable filter used
>> as a sine wave generator:
>>
>> immutable SvfSinOscCoef
>>     g0::Float64
>>     g1::Float64
>> end
>> immutable SvfSinOsc
>>     ic1eq::Float64
>>     ic2eq::Float64
>> end
>> function SvfSinOscCoef_Init (;freq=1.0, sr=44100.0)
>>     local g::Float64 = tan (2pi*freq/sr)
>>     local g0 = 1.0/(1.0+g^2)
>>     SvfSinOscCoef (g0,g*g0)
>> end
>> function SvfSinOsc_Init (startphase::Float64)
>>     SvfSinOsc (cos(startphase), sin(startphase))
>> end
>>
>> But the tick function looks a bit messy:
>>
>> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>>     local v1::Float64 = coef.g0*state.ic1eq - coef.g1*state.ic2eq
>>     local v2::Float64 = coef.g1*state.ic1eq + coef.g0*state.ic2eq
>>     SvfSinOsc (2*v1 - state.ic1eq, 2*v2 - state.ic2eq)
>> end
>>
>>
>> It would be really cool if there was a way to shorthand the syntax of
>> this to something like the following, which is a lot more readable:
>>
>> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>>     using s, c
>>     local v1::Float64 = g0*ic1eq - g1*ic2eq
>>     local v2::Float64 = g1*ic1eq + g0*ic2eq
>>     SvfSinOsc (2*v1 - ic1eq, 2*v2 - ic2eq)
>> end
>>
>>
>> Lots of algorithms have arguments with the same type, but even then you
>> could still specify using just the most used argument, but if it doesn't
>> help make things more clear or isn't useful then people don't have to use
>> it at all.
>>
>>
>>
>> Another pattern that would be nice to handle cleanly is: fetch state to
>> local, compute on local, store local to state. I have written code that
>> generates code to handle this since it is such a pain to keep everything in
>> sync, but if there was some way to automate this at the language level then
>> it would really rock, so here is an example of the longhand way, which
>> isn't too bad for this example, but just imagine if there are 20 or so
>> variables, and you are writing multiple tick functions:
>>
>> type SvfSinOsc
>>     ic1eq::Float64
>>     ic2eq::Float64
>> end
>>
>> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>>     local ic1eq::Float64 = state.ic1eq
>>     local ic2eq::Float64 = state.ic2eq
>>     for i = 1:100
>>         # compute algorithm using local copies of state.ic1eq and
>> state.ic2eq
>>     end
>>     state.ic1eq = ic1eq
>>     state.ic2eq = ic2eq
>>     return state
>> end
>>
>>
>> I have a feeling that macros may be able to help out here to result in
>> something like:
>>
>> function tick (state::SvfSinOsc, coef::SvfSinOscCoef)
>>     @fetch state
>>     for i = 1:100
>>         # compute iterative algorithm using local copies of state.ic1eq
>> and state.ic2eq
>>     end
>>     @store state
>>     return state
>> end
>>
>> But I'm not sure how to code such a beast, I tried something like:
>>
>> macro fetch(obj::SvfSinOsc)
>>     return quote
>>         local ic1eq = obj.ic1eq
>>         local ic2eq = obj.ic2eq
>>     end
>> end
>>
>> macro store(obj::SvfSinOsc)
>>     return quote
>>         obj.ic1eq = ic1eq
>>         obj.ic2eq = ic2eq
>>     end
>> end
>>
>> dump(osc)
>> macroexpand (:(@fetch osc))
>> macroexpand (:(@store osc))
>>
>>
>> SvfSinOsc
>>   ic1eq: Float64 1.0
>>   ic2eq: Float64 0.0
>>
>>
>> Out[28]: :($(Expr(:error, TypeError(:anonymous,"
>> typeassert",SvfSinOsc,:osc))))
>>
>>
>>
>>
>>
>>
>>
>>

Reply via email to