Interesting solution! Here's how I might solve it (wanting to set a random parameter of a synth that's playing):

s <- synth foo ()

-- Randomly pick one from the list:

set' <- pick [

\n -> set s (toI n :: I "freq")

, \n -> set s (toI n :: I "amp")

, \n -> set s (toI n :: I "foobar")

]

set' 35

(You can eliminate the "\n ->" too but thought I'd show the more general case)

To answer your specific questions:

- Yes, it's definitely intentional that Vivid only lets you set parameters the synth has. If you really need to get around it I've built in a few escape hatches (which I can describe), but I've used Vivid nearly every day for a few years now and haven't needed it so far.

- There's no maximum to the number of arguments set' could have. In the worst case (thousands of them?) it could slow down your compilation, but it shouldn't slow down runtime at all.

Tom

It works!set' :: (Subset '["freq","amp"] sdArgs, Real n, VividAction m)=> String -> Node sdArgs -> n -> m ()set' "freq" s n = set s (toI n :: I "freq")set' "amp" s n = set s (toI n :: I "amp")This has a property that, depending on your point of view, you could call a disadvantage or a feature: `set'` can only send messages to synths (`Node`s) for which "freq" and "amp" are both valid parameters. If you wanted to use it with a lot of unique synths, and their parameters have unique names, then you would have to make every synth recognize all the parameters of all the others. (Those extra parameters could be no-ops, part of the type signature but unused in the definition.)I'm in kind of a weird place, fighting with Vivid's brilliant type safety.Is there a theoretical maximum to the number of parameter names `set'` could be defined for? I tried 33 and it compiled.On Wed, Jul 4, 2018 at 9:31 PM Jeffrey Brown <jeffbrown.the@gmail.com> wrote:Thanks, Claude! I'm working on moving your example into the Vivid context.Tom, indeed, that would be simpler! I wanted to use `toI`. But I don't see how to do that without hard-coding every choice of which parameter to send a message to.For instance, suppose you've got a list of parameter names `["freq","amp" ..]` from which you want the code to choose a parameter `p` randomly every cycle, and set it to the value `x`. You can't write `set s (x :: I p)`, because the `p` in `I p` is a type-level variable rather than an ordinary one.I considered keeping a list of functions `[setFreq, setAmp ..]` instead of a list of parameter names, but I haven't found how to represent such a list:.> :set -XDataKinds> :set -XRankNTypes> s <- synth boop ()> [set s (3::I "amp"), set s (5::I "freq")]<interactive>:194:22: error:• Could not deduce: Elem "freq" '[] arising from a use of ‘set’from the context: VividAction mbound by the inferred type of it :: VividAction m => [m ()]at <interactive>:194:1-41• In the expression: set s (5 :: I "freq")In the expression: [set s (3 :: I "amp"), set s (5 :: I "freq")]In an equation for ‘it’:it = [set s (3 :: I "amp"), set s (5 :: I "freq")]>On Wed, Jul 4, 2018 at 11:50 AM <amindfv@gmail.com> wrote:_______________________________________________The approach I'd use might be a little different. Vivid offers a "toI" function which takes any number and converts it to an "I".So for example:```myNums = [1..10] :: [Double]sd0 = undefined :: SynthDef '["freq"]sd1 = undefined :: SynthDef '["amp"]main = dos0 <- synth sd0s1 <- synth sd1forM_ myNums $ \n -> doset s0 (toI n :: I "freq")set s1 (toI n :: I "amp")```Also: "toI" works on any numeric type (any "Real n"), and "I" itself is a numeric type. So you can always write:x = 5 :: I "freq"y = toI x :: I "amp"TomComposers reuse melodic material across different instruments. I would like to do that in Vivid. I would keep a sequence of values and send it sometimes to one parameter of one synth, sometimes to a different parameter of a different synth.To do that I would have to coerce those numbers to values of type `I a`, where the string `a` is known only at runtime. I tried to write a function to do that:import GHC.TypeLitstoIOf :: (Real n, GHC.TypeLits.KnownSymbol a) => String -> n -> I atoIOf "freq" n = toI n :: I "freq"toIOf "amp" n = toI n :: I "amp"but it won't compile, because the outputs of `toIOf "freq"` and `toIOf "amp"` have different types.Is this possible?--_______________________________________________

Livecode mailing list -- livecode@we.lurk.org

To unsubscribe send an email to livecode-leave@we.lurk.org

Livecode mailing list -- livecode@we.lurk.org

To unsubscribe send an email to livecode-leave@we.lurk.org

--

--

_______________________________________________

Livecode mailing list -- livecode@we.lurk.org

To unsubscribe send an email to livecode-leave@we.lurk.org