[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: Fri, 6 Jul 2018 20:20:25 -0500

> 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
Received on Sat Jul 07 2018 - 01:21:04 BST

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