Hi all, Chuck newbie here. Is it possible to pass a function as an argument? I'd like to be able to transform things in a functional programming manner. As a trivial example, if I had an array of midi notes and wanted to raise them all one interval. fun int increment(int note) { note + 1; } // use map to apply a function to all elements of an array map ( array_of_notes, increment); thanks in advance, John
Hello John,
It is not really possible in normal Chuck syntax: functions are not values in Chuck and there is no function type.
However, you can simulate functions as values, by creating classes that create objects that behave like a function would.
The library LicK provides an implementation of that idea:
https://github.com/heuermh/lick/tree/master/lick/fn https://github.com/heuermh/lick/tree/master/lick/fn
The approach is best explained with an example I think.
// this is the Function class from LicK for functions that take one float argument.
class FloatFunction
{
0.0 => float default;
fun float evaluate(float arg0) // evaluate is abstract method applying the function to an argument.
{
return default;
}
}
// You extend it to make some function, for example, to make an addition Function object:
class Adder extends FloatFunction
{
float value;
fun void init(float arg) {
arg => value;
}
fun float evaluate(float arg0) { // here we override the evaluate method from the base class.
return value + arg0;
}
}
// this is just a helper, to create a Adder object:
fun Adder mkAdder(float arg) {
Adder a;
a.init(arg);
return a;
}
// Now it is possible to implement map, where you can take a function object as an argument:
fun float [] map (FloatFunction f, float lst[]) {
float result[lst.cap()];
for (int i;i
On 25 Aug 2020, at 22:51, John Crane
wrote: Hi all,
Chuck newbie here. Is it possible to pass a function as an argument? I'd like to be able to transform things in a functional programming manner. As a trivial example, if I had an array of midi notes and wanted to raise them all one interval.
fun int increment(int note) { note + 1; }
// use map to apply a function to all elements of an array map ( array_of_notes, increment);
thanks in advance,
John _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
Hello John, Casper
For better or worse, LiCK was inspired by functional-ish language features in Java (the colt library and commons-functor specifically) well before JDK8 lambdas or other JVM languages such as Scala. The downside as Casper points out is lots of little classes.
John's original example might look like
IntArrayList notes;
notes.size(10);
notes.assign(42);
<<
On Aug 26, 2020, at 6:22 AM, Casper Schipper
wrote: Hello John,
It is not really possible in normal Chuck syntax: functions are not values in Chuck and there is no function type.
However, you can simulate functions as values, by creating classes that create objects that behave like a function would. The library LicK provides an implementation of that idea: https://github.com/heuermh/lick/tree/master/lick/fn https://github.com/heuermh/lick/tree/master/lick/fn
The approach is best explained with an example I think.
// this is the Function class from LicK for functions that take one float argument. class FloatFunction { 0.0 => float default; fun float evaluate(float arg0) // evaluate is abstract method applying the function to an argument. { return default; } }
// You extend it to make some function, for example, to make an addition Function object: class Adder extends FloatFunction { float value;
fun void init(float arg) { arg => value; }
fun float evaluate(float arg0) { // here we override the evaluate method from the base class. return value + arg0; } }
// this is just a helper, to create a Adder object: fun Adder mkAdder(float arg) { Adder a; a.init(arg); return a; }
// Now it is possible to implement map, where you can take a function object as an argument: fun float [] map (FloatFunction f, float lst[]) { float result[lst.cap()]; for (int i;i
result[i]; } return result; } fun void printArray(float arr[]) { for (int i;i
>>; } } // so now your transposing mapping would look something like this: [10.,11.,12.,13] @=> float test[];
map(mkAdder(10.0),test) => printArray; map(mkAdder(20.0),test) => printArray;
A limitation that remains with this, since there is no curying etc.., you need a lot of classes, for each function type one. So creating and defining functions like this is not very lightweight (you almost always have to extend some class :-/). No surprise I guess: this is just programming a functional programming language using an object oriented one. My personal way of getting around that limitation was to build a translator in python that takes my own (scheme-like) syntax and parses it into chuck code* to automate all that boilerplate. But that is still quite a lot work! If you are really into doing functional stuff, it may also be worthwhile to consider use a “proper" functional language (ocaml/haskell) and communicate with chuck through OSC? It depends a bit on what level you would like to use the functions (controlling parameters or audio processing itself). I probably would have done something like this now if I didn’t have a whole bunch of tools written in chuck already :-P.
Hope this helps, Casper
* https://github.com/casperschipper/ChucK-Tools https://github.com/casperschipper/ChucK-Tools & https://github.com/casperschipper/cisp https://github.com/casperschipper/cisp There is some documentation in the cisp repo (sorry not very complete, this is kind of a personal toolbox).
On 25 Aug 2020, at 22:51, John Crane
mailto:john.crane@gmail.com> wrote: Hi all,
Chuck newbie here. Is it possible to pass a function as an argument? I'd like to be able to transform things in a functional programming manner. As a trivial example, if I had an array of midi notes and wanted to raise them all one interval.
fun int increment(int note) { note + 1; }
// use map to apply a function to all elements of an array map ( array_of_notes, increment);
thanks in advance,
John _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu mailto:chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
participants (3)
-
Casper Schipper
-
John Crane
-
Michael Heuer