[chuck-users] OOP and Style Qs, Operators

Spencer Salazar ssalazar at CS.Princeton.EDU
Tue Mar 20 16:08:06 EDT 2007

On Mar 17, 2007, at 8:32 AM, Veli-Pekka Tätilä wrote:

> Spencer Salazar wrote:
>> On Mar 16, 2007, at 6:55 PM, Veli-Pekka Tätilä wrote:
>> A disconnect method is something that I can see being useful,
> Fair enough, especially as the module config can be changed in real  
> time.
> WHich reminds me, we talked about growing arrays dynamically. If I  
> change
> the number of inputs on the fly for my OneOfN switch, and chuck new  
> inputs
> to it, does this happen fast enough that I can run it in a 1::samp  
> loop?
> I've never benchmarked it but somehow have an intuitive notion that
> allocating new memory might be heavy.

It should be fast enough.  Though you pretty much have to benchmark  
it on your own platform, because its all very much dependent on OS,  
hardware, audio driver, and the versions of everything.  Anecdotally,  
allocating an array of 660,000 floats on OS X 10.4.8 on a MacBook  
will cause a short skip, but allocations an order of magnitude or so  
below that are likely to be okay.

Additionally, you can save a little time/memory by using arrays of  
null UGen references, rather than arrays of UGens.  In the former,  
each element of the array is initially null, while in the latter,  
each element in the array is initialized to a new UGen.  So youd replace

UGen in[];
UGen newIn[newSize];


UGen @ in[];
UGen @ newIn[newSize];

And everything else should be the same.

>>> - 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.
> Hmm I still think it might be needed. The code for my connect  
> method is:
> function void connect(UGen output) { out => output; }
> Where out is the Gain module.
> That is I need something to chucK to my output. And I presume that  
> must be
> another UGen. As I cannot inherit from a UGen, I guess the gain  
> module might
> be my only choice.

I was thinking you could store the output UGen in a UGen @ member  
variable, and then connect the appropriate UGen from UGen in[] as  
needed (essentially cutting out the middle man (where man is a  
Gain)).  Either approach works well, though, there is very certainly  
no "one true way" to write ChucK code.

>>> - ALso in the test script, I would like to initialize my UGen array
>>> anonymously
>> Fortunately, there is the 'new' operator, which, similar to its
>> counterparts in Java and C++, anonymously allocates an object of
>> the specified type.
>> [ new SinOsc $ UGen, new SawOsc, new SqrOsc ] @=> UGen @oscs[];
> Ah that's the ticket, thanks. In Java you need the new operator for  
> every
> non-primitive type. But in C++ not using new means that the  
> variables live
> in the stack just like other function arguments. So are chucK  
> objects, not
> allocated with new, also stack variables?

All ChucK objects are heap variables, regardless of instantiation  
method.  Primitive types (int, float, time, dur) are on the stack.

> HOw's the VM like, by the way,
> would it make sensse to hand-code anything in ChucK assembler?

Probably not.  There isn't really any such ChucK assembler, although  
one could conceivably implement something like that.

>> Note that the initial $ UGen (typecast to UGen) is needed to tell the
>> compiler that this is a UGen array, not a SinOsc array.
> Ah I see, sort of. Is this dollar thing documented in the manual?

It is, under the "operators" section of the language specification  
(its the cast operator).  Its presented in the context of casting  
floats to ints, but you can also use it to move an Object up and down  
its inheritance hierarchy.

>> 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.
> Ah, that's bad. I mean the arrays are homogenous then and each  
> element must
> be of the specified type or some derived type. As polymorphism  
> based on a
> method name, aka duck typing, is not supported as this is a Java:ish
> language, will there be a template mechanism or the ability to  
> downcast
> arguments?

You can always cast them to back to what they were initially, using  
the $ operator.  You just have to actually know what they are.  Once  
interfaces are implemented there are probably a few tricks that could  
be used with those also.

> Which brings us to inheritance. You said that interfaces are  
> considered as a
> future extension. IF it works like Java. does this mean I can  
> currently
> inherit from only one class even if it would be abstract?

Yes, thats correct.

>> There is no style manual, but I think following the lead of the
>> examples and Java is probably the best approach at this point.
> Ah yes, that sounds reasonable. And Howabout the braces are they  
> commonly
> the K&R style or the BSD/Allman style? I think Java and most other  
> C-like
> langs have adopted the former. I like the latter myself for some  
> fairly
> specific reasons, although being a fan of the K&R book. In addition to
> preferring to comment decisions right after the opening brace, I use
> magnification and braille in coding which means a limited viewport.  
> Only a
> handful of chars magnified and max 40 in braille, though you stil  
> have to
> scan that with your fingers. So keeping the braces aligned makes  
> them easier
> to spot. This is also why I comment end braces, as you can easily  
> check
> Which brace it was using sspeech or braille. Though these are  
> definitely
> minor things I guess I'd ideally take the ADA syntax foo some stuff  
> end foo.
> I guess it might be slightly more musician friendly anyway, than C:ish
> things like braces, the pre and post dec and inc ops, augmented  
> assignments
> and other such thingies, most of which are just syntactic sugar.  
> But I've
> gotten used to them in C; Perl and java, so I ain't complaining.

The trend seems to be towards BSD/Allman bracket style in ChucK, but  
you should go with whatever you feel most comfortable with.  We  
should all be able to read your code either way.

> Speaking of operators, I really like the assignment operator in  
> ChucK. AS
> I've never been a fan of doubling a symbol to give it another  
> meaning, I
> once suggested that some language should have something similar to  
> what
> ChucK has only right-associative. So I was very pleased to see =>  
> in ChucK:
> and that's even left-associative, meaning potentially more user- 
> friendly.
> Which brings me to the chucK equality operator ==. Why two equals  
> signs, one
> would be much more logical as we have a dedicated assignment operator
> anyway, and as >= has one equals sign, not two.

I dont know the exact reasoning, but it seems logical to me when I  
consider that most programmers coming to ChucK will think that ==  
makes the most sense, while arguably non-programmers won't have any  
particular predisposition to whether = or == is better.  So to C/C++/ 
Java/Perl/etc. programmers, testing equality is business as usual,  
while for new programmers, its just one more thing to remember, like  
ending statements with semi-colons and having parentheses for  
function calls.  Its also convenient for those (like me) that are  
used to = for assignment, as expressions involving = are caught with  
a compile-time error instead of a more subtle runtime error.

> Another thing I like is the syntactic sugar for handling setters as
> properties. That is:
> object.setter(firstArg);
> can be turned into
> firstArg => object.setter;
> So you don't have to know it is a function call behind the scenes.  
> But could
> this also be exteneded to cover getters as well. Namely that as an  
> l-value:
> object.getter() => itsValue;
> Could be reduced to:
> object.getter => itsValue;
> Where l-valueness and lack of braces Would imply a method call,  
> provided
> that the class does not have a public data member named getter. But  
> this is
> a bit more ambiguous I know, and there might be some pathological  
> cases in
> the context of the whole language if this kind of addition is made.  
> It is
> hard to judje the extent of such changes, though they are easy to  
> suggest,
> from the user point of view.

This is an interesting idea, but it wouldn't work right now because  
functions without parentheses are already rvalues (returning the  
function address I believe).  You can't actually use this value for  
anything though, so maybe something like your suggestion could be  
implemented in the future.

> Is there a BNF grammar for chucK, by the way? I
> don't know Yacc yet, but should probably look into it some day.

There is no official BNF grammar for ChucK available.  I don't know  
yacc either, but in my experience its pretty easy to pick up the  
basics by just reading a .y file.


More information about the chuck-users mailing list