electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » ChucK programming language
Passing control methods into functions how?
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [14 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
witt0191



Joined: Feb 13, 2008
Posts: 23
Location: UK

PostPosted: Mon Sep 07, 2009 10:26 am    Post subject: Passing control methods into functions how? Reply with quote  Mark this post and the followings unread

Hi been looking at this all day and just cant get it to work

Trying to spork a function with what I think is called a control method as an argument eg.

Code:
SinOsc s => dac;

fun void thing(what_here gg){
440 => gg;
}

spork ~ thing(s.freq);

1000::ms => now;


Any ideas?

Scott
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Sep 07, 2009 10:35 am    Post subject: Reply with quote  Mark this post and the followings unread

Yes, I see.

In ChucK functions aren't objects and so can't be used as parameters. What you can do though is pass a object like a UGen as a parameter, then call a member function on that.

if you really, absolutely, must use references to functions you will have to create a "functor" class with a single member function called something like "do()" that you would overload for various such functions. You'd then pass a instance of one of those classes and call the ".do()" on that reference.

How you'd go about this depends a bit on what you'd like to accomplish.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
witt0191



Joined: Feb 13, 2008
Posts: 23
Location: UK

PostPosted: Mon Sep 07, 2009 10:51 am    Post subject: Reply with quote  Mark this post and the followings unread

Kassen wrote:
Yes, I see.

In ChucK functions aren't objects and so can't be used as parameters. What you can do though is pass a object like a UGen as a parameter, then call a member function on that.


That sounds interesting could you point me to an example of this?
Back to top
View user's profile Send private message
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Mon Sep 07, 2009 12:38 pm    Post subject: Reply with quote  Mark this post and the followings unread

Curious how function-oriented programming is seeping into the mainstream (not assuming you're mainstream, witt0191, I just see this stuff more and more everywhere). I feel like I'll be old hat soon with my object-oriented thinking (not to mention that I lapse into procedural programming every now and then), if I don't read up on this stuff.

Something like this maybe:

Code:
class Functor {
   fun void do(int i);
}
fun void thing(Functor f) {
   440 => f.do;
}


class FreqSetter extends Functor {
   UGen @ ugen;
   fun void do(int i) {
      i => ugen.freq;
   }
}

FreqSetter => freqSetter;
SinOsc sinOsc @=> freqSetter.ugen;

spork ~ thing(freqSetter);
1000::ms => now;


Didn't test to compile it. It's cludgy - even if you specialize it (maybe you don't need a general Functor, maybe you'll only use one particualr UGen everywhere.) I'd try to solve it some other way, bhut I don't know your specific problem.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Sep 07, 2009 12:53 pm    Post subject: Reply with quote  Mark this post and the followings unread

Here you go;

Code:
class Functor
    {
    fun float run( float arg1, float arg2)
        {
        return 0.0;
        }
    }

class Add extends Functor
    {
    fun float run(float arg1, float arg2)
        {
        return arg1 + arg2;
        }
    }

Add add;

class Mull extends Functor
    {
    fun float run(float arg1, float arg2)
        {
        return arg1 * arg2;
        }
    }

Mull mull;

class Wait extends Functor
    {
    fun float run(float arg1, float arg2)
        {
        arg1::second => now;
        arg2::ms => now;
        return 0.0;
        }
    }

Wait wait;

class SideEffect extends Functor
    {
    fun float run(float arg1, float arg2)
        {
        SinOsc s => dac;
        Std.rand2f(arg1,arg2)::second => now;
        return s.last();
        }
    }

SideEffect fx;



fun void example (Functor arg)
    {
    <<<arg.run(3, 2)>>>;
    }

example(mull);
example(add);
example(fx);
example(wait);


This is of quite basic but it's the principle that matters. The types should still line up but that's strong typing for you.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Mon Sep 07, 2009 1:09 pm    Post subject: Reply with quote  Mark this post and the followings unread

Antimon wrote:
Curious how function-oriented programming is seeping into the mainstream (not assuming you're mainstream, witt0191, I just see this stuff more and more everywhere).


Quite so. According to some every generation of procedural languages becomes more like lisp.

Quote:
I feel like I'll be old hat soon with my object-oriented thinking (not to mention that I lapse into procedural programming every now and then), if I don't read up on this stuff.


Well... actually many functional languages are also object oriented, it's just that the typical object they deal with if a object of type "function". This is basically the core of lisp, where everything is a list or list-element and functions may be such elements (likely returning lists...).

Quote:

Didn't test to compile it. It's cludgy - even if you specialize it (maybe you don't need a general Functor, maybe you'll only use one particualr UGen everywhere.) I'd try to solve it some other way, bhut I don't know your specific problem.


I ran mine and it works. I wouldn't do this unless needed but when I look at it like this it does seem fairly ok-ish. From a distance. I wouldn't push it much further than this because pushing it further will likely involve arrays, then there will be "Clemow's Bane". Also; we can't extend Functor with a overloaded "run" that returns a Functor because of the type-system (according to the language specs) however the parser -if memory serves- won't catch that and then there will be crashes.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
witt0191



Joined: Feb 13, 2008
Posts: 23
Location: UK

PostPosted: Mon Sep 07, 2009 6:23 pm    Post subject: Reply with quote  Mark this post and the followings unread

Hi,

Thanks for your replies.

I find that I tend to write functions and then spork them to change values like in the example above often, so I though that being able to throw the direct target into them rather than creating one for each purpose would be useful. Also could imagine use in a more dynamic system for that sort of capability.

Could see myself wanting to do something like

spork ~ changevalue(s.freq);
spork ~ changevalue(k.freq);

I suppose to be really useful there would be additional arguments setting other variables in the function

spork ~ changevalue(s.freq,500,1000::ms);

I could see this allowing me to reuse lots of functions more
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Tue Sep 08, 2009 5:13 am    Post subject: Reply with quote  Mark this post and the followings unread

Yes, but in that case it's different, in that case you pass the UGen (which is already a object) as the argument.
Code:

fun void setFreq(UGen u, float freq)
    {
    //not all UGens have a ".freq()" se we need to cast.
    //I just pick SinOsc here because it has a .freq()
    //it's the function name that matters.
    //this works fine as long as you never pass UGens without a .freq() member.
   
    freq => (u $ SinOsc).freq;
    }


With a little loop and a extra duration argument you could create a glide.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
witt0191



Joined: Feb 13, 2008
Posts: 23
Location: UK

PostPosted: Tue Sep 08, 2009 5:47 am    Post subject: Reply with quote  Mark this post and the followings unread

Hi,

Thats ace could just explain whats going on in this portion of your code?

(u $ SinOsc)

thanks really like that Smile
Back to top
View user's profile Send private message
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Tue Sep 08, 2009 6:21 am    Post subject: Reply with quote  Mark this post and the followings unread

witt0191 wrote:
Hi,

Thats ace could just explain whats going on in this portion of your code?

(u $ SinOsc)

thanks really like that Smile


That's a cast, in Java or C this would look something like this:

Code:
UGen ugen;
(...)
SinOsc s = (SinOsc) ugen;


It tries to narrow down the type of a variable, if possible. If the variable isn't an instance of the type that you try to cast to (or a subtype of it), you will get a runtime error.

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Tue Sep 08, 2009 7:25 am    Post subject: Reply with quote  Mark this post and the followings unread

Indeed.

more formally; things like SinOsc, LPF and Moog are all UGens and all have a .freq() member function. However, the "UGen" object iself doesn't have one and is just a abstraction (in fact it's virtually indentical to "Gain").

So; if we have a function that we'd like to be able to pass all of those types of UGens it would need to take "Ugen" as it's argument type.

Now there is a issue, as we may have a SinOsc (that does have a .freq) but we are considering it like a UGen, making the .freq inaccessible.

Here the cast ($) operator comes in. We can cast any type to a type that extends it (also to a type it's a extension off and float and int can be cast to each other). So; we cast this UGent-argument to a type that we know has the desired member function.

WARNING; this work, it's legal... but we are over-riding the type system so the type system no longer helps us make sure we are not making typos. When you would feed a "Gain" to this function you will have a VM crash. In the case of the mini that will mean losing all your unsaved code.

It's more or less like when I'd hand you a box and say there is a animal in it. You would not say say "I'm going to milk it" on your own because not all animals can be milked; there might be a beetle in there. The casting is like me guaranteeing you there is a cow, sheep or snake in there (that you will have to milk). If I'd make a mistake and accidentally put a ostrich in the box you would probably quit following my orders as they make no sense, which is exactly what the VM will do.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
blue hell
Site Admin


Joined: Apr 03, 2004
Posts: 24079
Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320

PostPosted: Tue Sep 08, 2009 9:57 am    Post subject: Reply with quote  Mark this post and the followings unread

Does ChucK have run time type information? Such that I could ask an UGen if it in fact is an osc, or if in fact does have a freq() method?

In Pascal I'd write something like :

if anObject is TOscillator
then TOscillator( anObject).frequency := 1000;

_________________
Jan
also .. could someone please turn down the thermostat a bit.
Posted Image, might have been reduced in size. Click Image to view fullscreen.
Back to top
View user's profile Send private message Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Tue Sep 08, 2009 10:44 am    Post subject: Reply with quote  Mark this post and the followings unread

Yeah, in Java you would type

Code:
if (anObject instanceof TOscillator)


I'm not aware of a similar test operator in ChucK. Some languages (Objective C?) even have an operator for testing if an object supports a particular function ("if ugen has freq" or some such).

/Stefan

_________________
Antimon's Window
@soundcloud @Flattr home - you can't explain music
Back to top
View user's profile Send private message Visit poster's website
blue hell
Site Admin


Joined: Apr 03, 2004
Posts: 24079
Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320

PostPosted: Tue Sep 08, 2009 11:28 am    Post subject: Reply with quote  Mark this post and the followings unread

Antimon wrote:
(Objective C?)
Yes it has, just ran into that the other day Wink
_________________
Jan
also .. could someone please turn down the thermostat a bit.
Posted Image, might have been reduced in size. Click Image to view fullscreen.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [14 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use