
On Mar 17, 2007, at 8:32 AM, Veli-Pekka Tätilä 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
Spencer Salazar wrote: 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]; with 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. spencer