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<lst.cap();i++) { f.evaluate(lst[i]) => result[i]; } return result; } fun void printArray(float arr[]) { for (int i;i<arr.cap();i++) { <<<arr[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 <john.cr...@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 > 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