[livecode] Re: Vivid: Create a value of type `I a` where `a` is chosen at runtime

From: Jeffrey Brown <jeffbrown.the_at_gmail.com>
Date: Sat, 7 Jul 2018 12:25:33 -0500

Bah! I could have caught that.

It works now! Thanks, Tom!

I don't know if this is of interest to anyone, but I'm building a
collection of examples of how to do simple tasks in Vivid at
https://github.com/JeffreyBenjaminBrown/vivid/tree/jbb/learning

On Sat, Jul 7, 2018 at 12:02 AM <amindfv_at_gmail.com> wrote:

> Whoops, that's a not-very-nice error message saying it can't set the
> "foobar" property of the synth because it doesn't have that property. If
> you remove that line it'll work.
>
> Tom
>
>
> El 6 jul 2018, a las 21:20, Jeffrey Brown <jeffbrown.the_at_gmail.com>
> escribió:
>
> > no maximum
>
> Nice!
>
> > Here's how I might
>
> After half an hour of study I haven't figured out how to evaluate that.
>
> > :{
> *Main|
> *Main| main = do
> *Main| s <- synth boop ()
> *Main|
> *Main| -- Randomly pick one from the list:
> *Main| set' <- pick ( [ \n -> set s (toI n :: I "freq")
> *Main| , \n -> set s (toI n :: I "amp")
> *Main| , \n -> set s (toI n :: I "foobar")
> *Main| ] -- :: [(Real n, VividAction m) => n -> m ()]
> *Main| )
> *Main| set' 35
> *Main| :}
>
> <interactive>:208:26: error:
> • Could not deduce: Elem "foobar" '[] arising from a use of ‘set’
> from the context: (MonadRandom m, VividAction m)
> bound by the inferred type of
> main :: (MonadRandom m, VividAction m) => m ()
> at <interactive>:(202,1)-(211,9)
> • In the expression: set s (toI n :: I "foobar")
> In the expression: \ n -> set s (toI n :: I "foobar")
> In the first argument of ‘pick’, namely
> ‘([\ n -> set s (toI n :: I "freq"),
> \ n -> set s (toI n :: I "amp"),
> \ n -> set s (toI n :: I "foobar")])’
>
>
> On Fri, Jul 6, 2018 at 2:28 PM <amindfv_at_gmail.com> wrote:
>
>> 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
>>
>> El 5 jul 2018, a las 00:51, Jeffrey Brown <jeffbrown.the_at_gmail.com>
>> escribió:
>>
>> 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_at_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 m
>>> bound 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_at_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 = do
>>>> s0 <- synth sd0
>>>> s1 <- synth sd1
>>>> forM_ myNums $ \n -> do
>>>> set 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"
>>>>
>>>> Tom
>>>>
>>>>
>>>> El 4 jul 2018, a las 08:30, Jeffrey Brown <jeffbrown.the_at_gmail.com>
>>>> escribió:
>>>>
>>>> Composers 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.TypeLits
>>>> toIOf :: (Real n, GHC.TypeLits.KnownSymbol a) => String -> n -> I a
>>>> toIOf "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?
>>>>
>>>> --
>>>> Jeff Brown | Jeffrey Benjamin Brown
>>>> Website <https://msu.edu/~brown202/> | Facebook
>>>> <https://www.facebook.com/mejeff.younotjeff> | LinkedIn
>>>> <https://www.linkedin.com/in/jeffreybenjaminbrown>(spammy, so I often
>>>> miss messages here) | Github
>>>> <https://github.com/jeffreybenjaminbrown>
>>>>
>>>> _______________________________________________
>>>> Livecode mailing list -- livecode_at_we.lurk.org
>>>> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>>>>
>>>> _______________________________________________
>>>> Livecode mailing list -- livecode_at_we.lurk.org
>>>> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>>>>
>>>
>>>
>>> --
>>> Jeff Brown | Jeffrey Benjamin Brown
>>> Website <https://msu.edu/~brown202/> | Facebook
>>> <https://www.facebook.com/mejeff.younotjeff> | LinkedIn
>>> <https://www.linkedin.com/in/jeffreybenjaminbrown>(spammy, so I often
>>> miss messages here) | Github
>>> <https://github.com/jeffreybenjaminbrown>
>>>
>>
>>
>> --
>> Jeff Brown | Jeffrey Benjamin Brown
>> Website <https://msu.edu/~brown202/> | Facebook
>> <https://www.facebook.com/mejeff.younotjeff> | LinkedIn
>> <https://www.linkedin.com/in/jeffreybenjaminbrown>(spammy, so I often
>> miss messages here) | Github
>> <https://github.com/jeffreybenjaminbrown>
>>
>> _______________________________________________
>> Livecode mailing list -- livecode_at_we.lurk.org
>> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>>
>> _______________________________________________
>> Livecode mailing list -- livecode_at_we.lurk.org
>> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>>
>
>
> --
> Jeff Brown | Jeffrey Benjamin Brown
> Website <https://msu.edu/~brown202/> | Facebook
> <https://www.facebook.com/mejeff.younotjeff> | LinkedIn
> <https://www.linkedin.com/in/jeffreybenjaminbrown>(spammy, so I often
> miss messages here) | Github <https://github.com/jeffreybenjaminbrown>
>
>
> _______________________________________________
> Livecode mailing list -- livecode_at_we.lurk.org
> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>
> _______________________________________________
> Livecode mailing list -- livecode_at_we.lurk.org
> To unsubscribe send an email to livecode-leave_at_we.lurk.org
>


-- 
Jeff Brown | Jeffrey Benjamin Brown
Website <https://msu.edu/~brown202/>   |   Facebook
<https://www.facebook.com/mejeff.younotjeff>   |   LinkedIn
<https://www.linkedin.com/in/jeffreybenjaminbrown>(spammy, so I often miss
messages here)   |   Github <https://github.com/jeffreybenjaminbrown>


_______________________________________________
Livecode mailing list -- livecode_at_we.lurk.org
To unsubscribe send an email to livecode-leave_at_we.lurk.org
Received on Sat Jul 07 2018 - 17:26:02 BST

This archive was generated by hypermail 2.4.0 : Sun Aug 20 2023 - 16:02:23 BST