
Hi Veli-Pekka, please see responses below. On Mar 16, 2007, at 6:55 PM, Veli-Pekka Tätilä wrote:
1. Is the code in the class OK in terms of style and implementation i.e. is there something highly uncanonical in naming or some things that could be done smarter for such a simple thing?
Looks pretty good from here. A disconnect method is something that I can see being useful, though.
- In particular, I'm not sure if the gain module is needed in the output.
It shouldnt be needed, but may be useful if you wanted to adjust the gain of the entire UGen unilaterally.
- Is there a better way to grow the array on demand? In Perl I can just assign to higher indeces and it will grow, or use the push function to add an arbitraryly sized list at the end. And Java has array lists, too.
Yes, your approach is currently the only way to grow the numeric part of the array. It is a goal to eventually have the ability to dynamically adjust the capacity of an array.
- ALso in the test script, I would like to initialize my UGen array anonymously without having to make up variable names for each object and manully assign the indeces, I'm lazy I guess.
I don't see this as laziness, necessarily--it is a completely legitimate thing to want to do. Fortunately, there is the 'new' operator, which, similar to its counterparts in Java and C++, anonymously allocates an object of the specified type. Amending part of your code below to use this operator would look something like this:
UGen @oscs[3]; // Our oscs. new SinOsc @=> oscs[0]; new SawOsc @=> oscs[1]; new SqrOsc @=> oscs[2];
or even this:
[ new SinOsc $ UGen, new SawOsc, new SqrOsc ] @=> UGen @oscs[];
Note that the initial $ UGen (typecast to UGen) is needed to tell the compiler that this is a UGen array, not a SinOsc array. One caveat to this technique is that you won't be able to set any parameters to your oscillators beyond those that are present in every UGen. Notably, UGen doesn't have a frequency parameter.
- Is there a style manual for ChucK? Until we can inherit from UGen it would be great to have a common set of method names for UGen like modules. Currently I've drawn my influences from Java and Dinky.ck.
There is no style manual, but I think following the lead of the examples and Java is probably the best approach at this point.
- Which reminds me, does chucK support duck typing? Abstractly put, Suppose a class or interface c with the method name m and an object o such that not o instanceof c. Does o.m() get called in its own class, even if o is not related to c by inheritance. Polymorphism that works based on a name is there in Perl and Python, I think, where as Java is stricter and requires that the object be a subclass or interface implementation of c, a common method name is not good enough.
ChucK follows the Java model, requiring explicit inheritance for polymorphism to be (ab)used.
2. How is ChucK naming like? Suppose we have a parameter p of type t. I would like to create its accessors as:
- function void p(t i); // set function t p(); // get Yet although chucK supports overloading functions, it does not let them differ only by return type, right? In a test class I get stuff like:
[test.ck]:line(5): function signatures differ in return type...
The same thing with JAva really and I do understand it could often be ambiguous. Perl is one of the few languages in which this works well as scalar is the only primitive scalar type and it has list and void context to make things more or less unambiguous. But ChucK is not Perl, nough said.
Yes, ChucK is a strongly typed language, which generally require return types of functions to be known at run-time. One practice you might consider adopting is returning the value of the parameter in your set method, i.e.
function t p(t i); // set function t p(); // get
This approach also makes things like this possible, which is sometimes appealing (or appalling): class myClass { int _p; fun int p( int __p ) { return __p => _p; } fun int p() { return _p; } } myClass a, b, c, d; 1 => a.p => b.p => c.p => d.p;
- As I think parameters with the verbs get and set are slightly redundant, if boolean stuff starts with e.g. is , I thought I would use: function t p(); function setP(t i); However, if there is already a data member named p chucK does not let me hav a member function named p in the same class, right? After modding my test class, I got:
[test.ck]:line(4): function name 'p' is already used by another value
Yes, this is similar semantically to many C-like languages. A common practice that I see is, for a given parameter p, to call it _p and then have the accessors use p, as in the myClass example above. m_p (for member variable p) is another popular approach.
3. To save some duplicated code, and as there's no constructor support, it occurred to me I could write a function that given an array of UGens, instanciates my audio switch (OneOfN), populates it and returns a reference.
Ah, yes, a "factory" method. You might consider making this function a static member function of the OneOfN class rather than a non-class function. This has the advantage of making the function accessible to all shreds if OneOfN is a public class. (Its also liable to satisfy any object oriented nitpickers reading your code.)
What might be wrong, i.e. why does it think an array of UGen is just a UGen rather than an array? I'm mightily confused here. The code: [...] choices.caps() => int max; // Cache it, so only one method call.
I believe this should be choices.cap() (no 's').
4. When I use my audio switch to determine whether audio flows through, i.e. as an audio relay one of whose inputs is practically disconnected (I've patched blackhole there), it seems to work OK i.e. I get the sound of silence when expected. However, if I change my array initializer in OneOfN.ck:
from:
blackhole @=> newIn[i]; // Not connected initially.
to
null @=> newIn[i]; // Not connected initially.
Strange things start to happen. I don't get a null pointer exception at runtime as I would expect in my test script, as the unconnected input is actually null. In stead ChucK crashes spectacularly with the standard WIndows XP dialog about it.
Yes! This is a known bug in the currently release version. It should be fixed in the current release candidate, and the upcoming release as well (feel free to test/try to break it at your convenience).
[Speaking of Dracula, I'm just reading Frankenstein, talk about funny co-incidences. Hmm what's the code name for the next release?]
Coincidentally, frankenstein was the code name of the original ChucK release. dracula is the code name for the current series of ChucK releases, whatever that means, so the name will probably be dracula for a while.
I think these were my questions. As I tend to have a bad habbit of asking all too much, when someone who knows far more than I do is around, I'd actually be pleased if even half of these would get answered eventually, <smile>.
No worries! We're all here to help. spencer