[chuck-users] OOP and Style Qs, Operators

Veli-Pekka Tätilä vtatila at mail.student.oulu.fi
Sat Mar 17 08:32:08 EDT 2007


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.

>> - 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.

 >> - 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? HOw's the VM like, by the way, 
would it make sensse to hand-code anything in ChucK assembler?

> 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?

> 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? For example, Java's ArrayList can store objects but you can then 
downcast them to the desired type or let the compiler do it for you which is 
called autoboxing I think.

Another way to do it might be to add some reflection API through which you 
can ask for the method and call it for a particular object. I've noticed 
there's already a class named Class, based on some error messages. What 
,members does it have?

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?

Would it be feasible to keep track of how many   instances a particular 
class has as a static member? Sure you can inc the count in a constructor, 
but one would need a ddestructor to know when to decrease the count? Or 
alternatively, have uggly method calls for upping and downing the count 
explicitly, as in COM.

> 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.

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.

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

> One practice you might consider adopting is returning the value of
> the parameter in your set method <snip>
> myClass a, b, c, d;
> 1 => a.p => b.p => c.p => d.p;
Ah the good old chained assignments. ANother possibility would be to return 
the object itself so you could chain method calls. A Perl module I saw 
recently did just that to let you construct English looking regular 
expressions via huge chains of method calls. Another funny consequence is in 
Java:
String s = "foo";
s.toString().toString().toString();
Doesn't make any sense at all, but is legal, because all objects including 
String have a toString method. ChucK would benefit from one, too. As well as 
more formatted printing, hint sprintf is in very many languages these days 
including Java, C++, Perl, Python and even PHP.

>> 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?
>> [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.
Why is the message talking about another value, though? Conceptually, one 
does not think of the function's formal argument as being a value. ONly when 
it is an actual one, it has a value at that point. But this is a minor 
semantic quibble.

There are various other practices for naming instance data. Although not 
really for oop use in Perl, I could use the prefix my for instance data and 
our for class data. And some Java styleguide recommended its and their, too, 
which I kinda like as well. I read code partially with synthetic speech so 
if it sounds like English that's a plus. You could infer from this i like 
SQL as well. Other practices, hmm, the SymbianOS uses a small i for instance 
and a small letter a for function arguments. SO a player class might have a 
member named iTunes, pun intended.

>> 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
Ah yes, will do that. Although it means I'll have to call it explicitly 
anyway. Would be nice to have constructors some day, <sigh>.

snipped plenty of stuff here. Thanks for the rest of the ansers, too. 
Apparently the typos are my bad, again, and crashing in null pointers will 
be fixed. I think I'll wait for the official next release to try And see 
that it does not crash any more, as I'm pretty happy with this one. IS the 
manual updated in sync with the next release?

-- 
With kind regards Veli-Pekka Tätilä (vtatila at mail.student.oulu.fi)
Accessibility, game music, synthesizers and programming:
http://www.student.oulu.fi/~vtatila/ 



More information about the chuck-users mailing list