Re: [chuck-users] can there be many ::ms in while?
just to chime in here - i'm VERY new to programming. how do you create this kind of concurrency? if, say, you wanted to create two while loops, but wanted them to run "side-by-side", but looping at different speeds, how would you do it?for example:while (true){ do something; 100::ms => now;}andwhile (true) {do something else; 150::ms => now;}cheers> Date: Fri, 3 Aug 2007 05:53:57 +0900> From: electriclightheads@gmail.com> To: chuck-users@lists.cs.princeton.edu> Subject: Re: [chuck-users] can there be many ::ms in while?> > oh> maybe in the second way> am just looping the 1st while only?> > maybe it was a bit too early for me to ask things on the list> (only i can do is modifying the tut)> i thought> 100::ms => now;> was something like "100msec later do ..." or "every 100msec do ..."> but i happened to find that in () expression of while> > mmm> i'll go through a bit more ahead in the manual> yes> then i'll find Blit-UGen waiting for me?> > On 8/2/07, Martin Ahnelöv
fre 2007-08-03 klockan 07:14 +0000 skrev Stephen Ball:
just to chime in here - i'm VERY new to programming. how do you create this kind of concurrency? if, say, you wanted to create two while loops, but wanted them to run "side-by-side", but looping at different speeds, how would you do it?
for example:
while (true){ do something; 100::ms => now;}
and
while (true) {do something else; 150::ms => now;}
Yes, you can do that. FYI, it's called threading in traditional programming languages and is often a pain in the ass, but since chuck isn't a traditional language it's called sporking and is as simple as running a chuck file. I don't know how you create your patches and run them on your system, but I am a command-line person, so when I start coding in chuck, I open a command-line and type "chuck --loop". Then I open another command-line and create/dig out my patch and I run it with "chuck + patch.ck". Notice how the first command-line with chuck --loop tells us that we have added a file? Good. Now I'll create another patch with the second while-loop. I add it to the virtual machine (the chuck --loop) with another "chuck + patch2.ck". If you already got both of them done, you can play them synced with the command "chuck patch.ck patch2.ck" You can also do sporking in the code, but I haven't looked at that enough - it's in the help pages, though. Hope that helps, Gasten ps. look at the on-the-fly-commands.
On 8/3/07, Martin Ahnelöv
loops, but wanted them to run "side-by-side", but looping at different speeds, how would you do it?
Yes, you can do that. FYI, it's called threading in traditional
programming languages and is often a pain in the ass, but since chuck isn't a traditional language it's called sporking and is as simple as running a chuck file.
That's right!
You can also do sporking in the code, but I haven't looked at that enough - it's in the help pages, though.
That's also quite simple. You can run threads (we call them shreds) next to the main one. You define those as functions and you "spork" the function. ======================================= //let's define a function fun void paralel() { while(true) { //this will loop forever <<<"beep">>>; second => now; } } //let's try sporking it spork ~ paralel(); //now we write the main loop that will run next to it while(true) { //this will also loop forever <<<"boop">>>; .75::second => now; } //anything that you would write here will never get executed because the program will always be stuck in that last loop. you could still define functions here though. ----------------------------- See? not at all hard. You can run as many functions next to eachother as you like, they can all be different or they could all be the same. If they are all the same you only need to define it once and can spork it as many times as you'd like (untill the cpu gives up! Notice that they can all run at different speeds if you'd like, in my example above one loops in .75 seconds while the other takes a whole second so they will drift in and out of phase. Cheers, Kas.
That's also quite simple. You can run threads (we call them shreds) next to the main one. You define those as functions and you "spork" the function. ======================================= //let's define a function fun void paralel() { while(true) { //this will loop forever <<<"beep">>>; second => now; } }
//let's try sporking it spork ~ paralel();
//now we write the main loop that will run next to it while(true) { //this will also loop forever <<<"boop">>>; .75::second => now; }
//anything that you would write here will never get executed because the program will always be stuck in that last loop. you could still define functions here though.
-----------------------------
See? not at all hard. You can run as many functions next to eachother as you like, they can all be different or they could all be the same. If they are all the same you only need to define it once and can spork it as many times as you'd like (untill the cpu gives up! Notice that they can all run at different speeds if you'd like, in my example above one loops in .75 seconds while the other takes a whole second so they will drift in and out of phase.
Cool! Thanks!
All,
That was very well explained, folks. Personally, I think that the
area of the manual describing concurrency in Chuck is a little bit
thin. It would really help people new to Chuck (like myself) to have
a series of examples of what can be done with the concurrency
features, syncing, & c. It's one of Chuck's most important and
powerful features.
Maybe we could add a little section of the Wiki for concurrency
examples? Chuck/Programs/Concurrency or something like that.
I wish I had some examples of sporked shreds sharing data with each
other, for instance.
Just thinking out loud...
Mike
On 8/3/07, Martin Ahnelöv
That's also quite simple. You can run threads (we call them shreds) next to the main one. You define those as functions and you "spork" the function. ======================================= //let's define a function fun void paralel() { while(true) { //this will loop forever <<<"beep">>>; second => now; } }
//let's try sporking it spork ~ paralel();
//now we write the main loop that will run next to it while(true) { //this will also loop forever <<<"boop">>>; .75::second => now; }
//anything that you would write here will never get executed because the program will always be stuck in that last loop. you could still define functions here though.
-----------------------------
See? not at all hard. You can run as many functions next to eachother as you like, they can all be different or they could all be the same. If they are all the same you only need to define it once and can spork it as many times as you'd like (untill the cpu gives up! Notice that they can all run at different speeds if you'd like, in my example above one loops in .75 seconds while the other takes a whole second so they will drift in and out of phase.
Cool! Thanks!
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
I wish I had some examples of sporked shreds sharing data with each other, for instance.
Ok. Let's not go into sharing data between shreds that come from different .ck files just now as that's slightly advanced (but not that hard either). For shreds that come from the same file, (this comes down to paralel sporked functions) there are a few things to keep in mind. Anything that gets defined inside of a function's definition {between the brackets} is that function's data and is seperate from there rest. However; anything that gets defined in the main text is shared by everything in that file. This includes ugen parameters. I'll demonstrate this now. In the code below we'll define a variable that is shared between paralel shreds and we'll have one shred writing to it and have the other shred print it. ========================= int shared; fun void writer() { //let's just define another variable int example; while(true) { Std.rand2(0, 10) => shared; second => now; } } fun void reader() { //notice how this "example" won't clash with the other one //as each function has it's own namespace. //if you'd like to share data it would be a mistake to also //define a second int named "shared" here as that would confuse things. int example; while(true) { <<<shared>>>; second => now; } } spork ~ writer(); spork ~ reader(); while(true) { <<<"hello, I'm the main shred, I'm still alive!">>>; 5::second => now; } ========================== This would be the most basic way to share data between shreds. I'd be happy to give more advanced examples if that's nesicary but in that case I'd have to know what direction you want to move in. Also; I'm dyslexic and didn't test this code, just warning you :¬) Yours, Kas.
On 8/3/07, Martin Ahnelöv
spork ~ writer(); spork ~ reader();
By the way Kassen, what do we call the ~-symbol in chuck? (I know it's a tilde, but does it have a nifty name like Sporker or something like that, since => is named Chuck and not Arrow)
This is such a advanced subject that I dare not speak on it. I porpose that we all chant in the direction of Princeton while chucking ceremonial salt over our shoulder and hope Ge will speak on this. I believe Ge is font of eating so using real sea salt or celery salt might speed up the process. ;¬) Kas.
what do we call the ~-symbol in chuck? (I know it's a tilde, but does it have a nifty name like Sporker or something like that, since => is named Chuck and not Arrow)
This is a very good question (thanks Kassen for the redirect though I believe he is as much of an authority on spork/chuck-related issues as anyone. FYI: I do love sea salt, especially on deep-fried triple cheeseburgers - don't bother tossing those over your shoulder, unless of course I am standing directly behind you). Okay, for those who may be wondering about its function/origin, the ~ after the spork really serves no practical purpose that we are aware of (since sporking is such a fundamental operation in chuck, we thought it deserves its own syntactic sugar/wasabi/etc, and so the ~ was added to make the spork more prominent in code - quite possibly a horrible idea except it might be extended to other operators for different flavors of spork in the future). Anyway, as for a name for the ~, we ain't thought much about it. Let's make one up right here! How about: the sporkilator operator? shred assimilation facilitator? spork-to-shred warp vector? the twisty noodle of spork? spork syntax compensator? sporker? (short and sweet, good job Martin) spork linguini? Um, other suggestions? Thoughts? Best, Ge! On Aug 3, 2007, at 4:06 PM, Kassen wrote:
On 8/3/07, Martin Ahnelöv
wrote: spork ~ writer(); spork ~ reader();
By the way Kassen, what do we call the ~-symbol in chuck? (I know it's a tilde, but does it have a nifty name like Sporker or something like that, since => is named Chuck and not Arrow)
This is such a advanced subject that I dare not speak on it. I porpose that we all chant in the direction of Princeton while chucking ceremonial salt over our shoulder and hope Ge will speak on this. I believe Ge is font of eating so using real sea salt or celery salt might speed up the process.
;¬) Kas. _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
On 8/7/07, Ge Wang
This is a very good question (thanks Kassen for the redirect though I believe he is as much of an authority on spork/chuck-related issues as anyone.
Oh, thank you, but I don't think it would be good for me to go make up new naming conventions independantly. Before you know it there would be one naming convention on the forum, one on the list, various classrooms would have their own... There would be Southern ChucKish, Northern ChucKish, nobody would understand anyone anymore untill somebody designed a "ChucKish (simplified)" font. FYI: I do love sea salt, especially on deep-fried triple cheeseburgers -
don't bother tossing those over your shoulder, unless of course I am standing directly behind you).
Ah, triple cheesburgers! A important element in the fat-rich diet! I'm sadened to have to report that Dutch fastfood places have a rather unfortunate inclination towards being reasonable and so triples are hard to come by.... unless of cource one makes them onself. Um, other suggestions? Thoughts?
I was thinking about "you". I'll explain, this would make the pronounciation of the whole line like; "spork you reader" (brackets are silent) This could be taken as a reference to Pokemon with it's "I choose you" when fielding Pokemon which is fitting since we are realy summoning functions to do our bidding and "Frankenstein", "Dracula" and "quintesson" already reference pop-culture. We would maintain that that is what it means and that there is no link at all to "spork" somehow seeming like a naughty word. ;¬) Kas.
Okay, I'm having a bit of an "ah-ha!" moment here. It makes sense to
me when described like this. If I understand this process correctly,
data-sharing aside, this is functionally equivalent to using the
"chuck --loop" invocation to start the VM and sporking shreds with
"chuck + this.ck" and "chuck + that.ck." Or is that more like
Machine.add()?
According the manual, sporking a shred will return a reference to the
shred, while using Machine.add() will return the ID. Can one pass
messages between shreds in the VM like in Erlang processes using this
information? Using a shared variables to store state information
might get kind of hairy in big programs.
Mike
On 8/3/07, Kassen
I wish I had some examples of sporked shreds sharing data with each other, for instance.
Ok. Let's not go into sharing data between shreds that come from different .ck files just now as that's slightly advanced (but not that hard either).
For shreds that come from the same file, (this comes down to paralel sporked functions) there are a few things to keep in mind. Anything that gets defined inside of a function's definition {between the brackets} is that function's data and is seperate from there rest. However; anything that gets defined in the main text is shared by everything in that file. This includes ugen parameters. I'll demonstrate this now. In the code below we'll define a variable that is shared between paralel shreds and we'll have one shred writing to it and have the other shred print it. ========================= int shared;
fun void writer() { //let's just define another variable int example;
while(true) { Std.rand2(0, 10) => shared; second => now; } }
fun void reader() { //notice how this "example" won't clash with the other one //as each function has it's own namespace. //if you'd like to share data it would be a mistake to also //define a second int named "shared" here as that would confuse things. int example;
while(true) { <<<shared>>>; second => now; } }
spork ~ writer(); spork ~ reader();
while(true) { <<<"hello, I'm the main shred, I'm still alive!">>>; 5::second => now; } ==========================
This would be the most basic way to share data between shreds. I'd be happy to give more advanced examples if that's nesicary but in that case I'd have to know what direction you want to move in.
Also; I'm dyslexic and didn't test this code, just warning you :¬)
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
On 8/3/07, mike clemow
Okay, I'm having a bit of an "ah-ha!" moment here.
Great! I'm having coffee here :¬). It makes sense to
me when described like this. If I understand this process correctly, data-sharing aside, this is functionally equivalent to using the "chuck --loop" invocation to start the VM and sporking shreds with "chuck + this.ck" and "chuck + that.ck." Or is that more like Machine.add()?
Actually, Machine.add() and "chuck +" are basically equivalent (aside from returning a Id in the .add() case). Sporking also results in new code being run in a new shred but it's different in that it shares the name-space of the parent. Also; if a shred sporks a new shred and then "dies" all it's sporked childeren will be "killed" too, shreds it has added using Machine.add() won't die in that case. According the manual, sporking a shred will return a reference to the
shred, while using Machine.add() will return the ID. Can one pass messages between shreds in the VM like in Erlang processes using this information? Using a shared variables to store state information might get kind of hairy in big programs.
Yes, you definately could. You could, for example use events, extended to have a id as a parameter and have sporked shreds listen for that event, then compare that "id parameter" to it's own. I sugest you read the manual section on events, events are cool; quite simple, very powerfull and they can be extended. If that's not enough you might need to look into classes. Classes can also spork their own shreds upon construction and in that case you can use the class instance's name. I hope that answers your question, if you are after something more specific we can look into that as well. Happy to have been able to contribute to your "Ah-ha!", Kas.
fre 2007-08-03 klockan 11:29 -0400 skrev mike clemow:
All,
That was very well explained, folks. Personally, I think that the area of the manual describing concurrency in Chuck is a little bit thin. It would really help people new to Chuck (like myself) to have a series of examples of what can be done with the concurrency features, syncing, & c. It's one of Chuck's most important and powerful features.
Maybe we could add a little section of the Wiki for concurrency examples? Chuck/Programs/Concurrency or something like that.
I'm not sure if this was the correct thing to do, but I felt free to add a couple of extra categories to http://wiki.cs.princeton.edu/index.php/ChucK/Examples . Hope that's fine. Please fill them up.
I wish I had some examples of sporked shreds sharing data with each other, for instance.
I think I'm gonna experiment with sporks next, so we'll see if I can get something cool to work. Gasten
this aspect is great!!
i think i"ll do a lot of function things going on in the near future
ah!! i cannot help myself from becoming greedy but
if i have
SinOsc s1 => Gain g1 => dac;
somewhere(where?) related to the main while
could the s1.freq() be used for calculation in defining the function?
looking for a global something might be a better solution?
i have some sort of fake indian music structure in mind
making a note "sa" should have function "ri"~"ni" floating around them
sub-note "ri"~"ni" should own jointly "sa"'s freq
in that way
i think we can make music in a
.ck = harmony = melody = raga
way
blablabla
On 8/3/07, Kassen
On 8/3/07, Martin Ahnelöv
wrote: loops, but wanted them to run "side-by-side", but looping at different speeds, how would you do it?
Yes, you can do that. FYI, it's called threading in traditional programming languages and is often a pain in the ass, but since chuck isn't a traditional language it's called sporking and is as simple as running a chuck file.
That's right!
You can also do sporking in the code, but I haven't looked at that enough - it's in the help pages, though.
That's also quite simple. You can run threads (we call them shreds) next to the main one. You define those as functions and you "spork" the function. ======================================= //let's define a function fun void paralel() { while(true) { //this will loop forever <<<"beep">>>; second => now; } }
//let's try sporking it spork ~ paralel();
//now we write the main loop that will run next to it while(true) { //this will also loop forever <<<"boop">>>; .75::second => now; }
//anything that you would write here will never get executed because the program will always be stuck in that last loop. you could still define functions here though.
-----------------------------
See? not at all hard. You can run as many functions next to eachother as you like, they can all be different or they could all be the same. If they are all the same you only need to define it once and can spork it as many times as you'd like (untill the cpu gives up! Notice that they can all run at different speeds if you'd like, in my example above one loops in .75 seconds while the other takes a whole second so they will drift in and out of phase.
Cheers, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
oops!
Kassen was writing the answer this when i was preparing the
question...excuse me!
On 8/4/07, 2g
this aspect is great!! i think i"ll do a lot of function things going on in the near future ah!! i cannot help myself from becoming greedy but if i have SinOsc s1 => Gain g1 => dac; somewhere(where?) related to the main while could the s1.freq() be used for calculation in defining the function? looking for a global something might be a better solution?
i have some sort of fake indian music structure in mind making a note "sa" should have function "ri"~"ni" floating around them sub-note "ri"~"ni" should own jointly "sa"'s freq in that way i think we can make music in a .ck = harmony = melody = raga way
blablabla
On 8/3/07, Kassen
wrote: On 8/3/07, Martin Ahnelöv
wrote: loops, but wanted them to run "side-by-side", but looping at different speeds, how would you do it?
Yes, you can do that. FYI, it's called threading in traditional programming languages and is often a pain in the ass, but since chuck isn't a traditional language it's called sporking and is as simple as running a chuck file.
That's right!
You can also do sporking in the code, but I haven't looked at that enough - it's in the help pages, though.
That's also quite simple. You can run threads (we call them shreds) next to the main one. You define those as functions and you "spork" the function. ======================================= //let's define a function fun void paralel() { while(true) { //this will loop forever <<<"beep">>>; second => now; } }
//let's try sporking it spork ~ paralel();
//now we write the main loop that will run next to it while(true) { //this will also loop forever <<<"boop">>>; .75::second => now; }
//anything that you would write here will never get executed because the program will always be stuck in that last loop. you could still define functions here though.
-----------------------------
See? not at all hard. You can run as many functions next to eachother as you like, they can all be different or they could all be the same. If they are all the same you only need to define it once and can spork it as many times as you'd like (untill the cpu gives up! Notice that they can all run at different speeds if you'd like, in my example above one loops in .75 seconds while the other takes a whole second so they will drift in and out of phase.
Cheers, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
participants (7)
-
2g
-
Ge Wang
-
Kassen
-
Martin Ahnelöv
-
mike clemow
-
Stephen Ball
-
Vassili Slessarenko