This file is indexed.

/usr/share/SuperCollider/HelpSource/Classes/Function.schelp is in supercollider-common 1:3.6.3~repack-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
class::Function
summary::Implements a function
categories::Core>Kernel

description::
A Function is a reference to a FunctionDef and its defining context Frame. When a FunctionDef is encountered in your code it is pushed on the stack as a Function. A Function can be evaluated by using the 'value' method. See the Functions help file for a basic introduction.

Because it inherits from AbstractFunction, Functions respond to math operations by creating a new Function.

code::
// example
(
var a, b, c;
a = { [100, 200, 300].choose };	// a Function
b = { 10.rand + 1 };	// another Function
c = a + b; 	// c is a Function.
c.value.postln;	// evaluate c and print the result
)
::

See AbstractFunction for function composition examples.

Because Functions are such an important concept, here some examples from related programming languages with functions as first class objects:

code::
// returning the first argument itself:
{ |x| x }.value(1) // SuperCollider
[:x | x ] value: 1 // Smalltalk
((lambda (x) x) 1) // Lisp
::

classMethods::

private::new

instancemethods::

subsection::Access

method::def

Get the definition ( FunctionDef ) of the Function.

method::isClosed

returns true if the function is closed, i.e. has no external references and can thus be converted to a compile string safely.

subsection::Evaluation

method::value

Evaluates the FunctionDef referred to by the Function. The Function is passed the args given.

code::
{ |a, b| (a * b).postln }.value(3, 10);
{ arg a, b; (a * b).postln }.value(3, 10); // different way of expressing the same
::

method::valueArray

Evaluates the FunctionDef referred to by the Function. If the last argument is an Array or List, then it is unpacked and appended to the other arguments (if any) to the Function. If the last argument is not an Array or List then this is the same as the 'value' method.

code::
{ |a, b, c| ((a * b) + c).postln }.valueArray([3, 10, 7]);

{ |a, b, c, d| [a, b, c, d].postln }.valueArray([1, 2, 3]);

{ |a, b, c, d| [a, b, c, d].postln }.valueArray(9, [1, 2, 3]);

{ |a, b, c, d| [a, b, c, d].postln }.valueArray(9, 10, [1, 2, 3]);
::

A common syntactic shortcut:

code::
{ |a, b, c| ((a * b) + c).postln }.value(*[3, 10, 7]);
::

method::valueEnvir

As value above. Unsupplied argument names are looked up in the current Environment.

code::
(
Environment.use({
~a = 3;
~b = 10;
{ |a, b| (a * b).postln }.valueEnvir;
});
)
::

method::valueArrayEnvir

Evaluates the FunctionDef referred to by the Function. If the last argument is an Array or List, then it is unpacked and appended to the other arguments (if any) to the Function. If the last argument is not an Array or List then this is the same as the 'value' method. Unsupplied argument names are looked up in the current Environment.


method::valueWithEnvir

Evaluate the function, using arguments from the supplied environment
This is slightly faster than valueEnvir and does not require replacing the currentEnvironment

code::
(
e = Environment.make({ ~a = 3; ~b = 10 });
{ |a, b| (a * b) }.valueWithEnvir(e);
)
::

method::functionPerformList

For Function, this behaves the same as valueArray(arglist). It is used  where Functions and other objects should behave differently to value, such as in the objecr prototyping implementation of Environment.


method::performWithEnvir

code::
a = { |a, b, c| postf("% plus % plus % is %\n", a, b, c, a + b + c); "" };
a.performWithEnvir(\value, (a: 1, c: 3, d: 4, b: 2));
::

argument::selector
A Symbol representing a method selector.
argument::envir
The remaining arguments derived from the environment and passed as arguments to the method named by the selector.

method::performKeyValuePairs

code::
a = { |a, b, c| postf("% plus % plus % is %\n", a, b, c, a + b + c); "" };
a.performKeyValuePairs(\value, [\a, 1, \b, 2, \c, 3, \d, 4]);
::

argument::selector
A Symbol representing a method selector.
argument::pairs
Array or List with key-value pairs.


method::loop

Repeat this function. Useful with Task and Clocks.

code::
t = Task({ { "I'm loopy".postln; 1.wait;}.loop });
t.start;
t.stop;
::

method::defer

Delay the evaluation of this Function by code::delta:: in seconds on AppClock.

This is equivalent to code::AppClock.sched(0, function):: unless code::delta:: is code::nil::. In that case the function is only scheduled if current code is not running on AppClock, otherwise the function is evaluated immediately.

code::
{ "2 seconds have passed.".postln; }.defer(2);

(
{ "chicken".postln }.defer(0); // schedules on the AppClock
{ "egg".postln }.defer // evaluates immediately
)

(
fork { // schedules on a TempoClock
    { "chicken".postln }.defer // schedules on the AppClock
};
{ "egg".postln }.defer // evaluates immediately
)
::

method::dup

Return an Array consisting of the results of n evaluations of this Function.

code::
x = { 4.rand; }.dup(4);
x.postln;
::

method::!

equivalent to dup(n)

code::
x = { 4.rand } ! 4;
x.postln;
::

method::sum

return the sum of n values produced.

code::
{ 4.rand }.sum(8);
::

method::choose

evaluates the function. This makes it polymorphic to SequenceableCollection, Bag and Set.

code::
[{ 100.rand }, [20, 30, 40]].collect(_.choose);
::

method::bench

Returns the amount of time this function takes to evaluate. print is a boolean indicating whether the result is posted. The default is true.

code::
{ 1000000.do({ 1.0.rand }); }.bench;
::

method::fork

Returns a Routine using the receiver as it's function, and plays it in a TempoClock.

code::
{ 4.do({ "Threadin...".postln; 1.wait;}) }.fork;
::

method::forkIfNeeded

If needed, creates a new Routine to evaluate the function in, if the message is called within a routine already, it simply evaluates it.

code::
f = { 4.do({ "Threadin...".postln; 1.wait;}) };
f.forkIfNeeded;
{ "we are now in a routine".postln; 1.wait; f.forkIfNeeded }.fork;
::

method::block

Break from a loop. Calls the receiver with an argument which is a function that returns from the method block. To exit the loop, call .value on the function passed in. You can pass a value to this function and that value will be returned from the block method.

code::
block {|break|
	100.do {|i|
		i.postln;
		if (i == 7) { break.value(999) }
	};
}
::

method::thunk

Return a Thunk, which is an unevaluated value that can be used in calculations

code::
x = thunk { 4.rand };
x.value;
x.value;
::

method::flop

Return a function that, when evaluated with nested arguments, does multichannel expansion by evaluting the receiver function for each channel. A flopped function responds like the "map" function in languages like Lisp.

code::
f = { |a, b| if(a > 0) { a + b } { -inf } }.flop;
f.value([-1, 2, 1, -3.0], [10, 1000]);
f.value(2, 3);
::


method::envirFlop

like flop, but implements an environment argument passing (valueEnvir).
Less efficient in generation than flop, but not a big difference in evaluation.

code::
f = { |a| if(a > 0) { a + 1 } { -inf } }.envirFlop;
e = (a: [20, 40]);
e.use { f.value }
::


method::inEnvir

returns an "environment-safe" function. See Environment for more details.

code::
// prints nil because ~a is read from topEnvironment, not e
e = (a: "got it", f: { { ~a.postln }.defer(0.5) });
e.use { e.f };

// prints "got it" because { ~a.postln } is now bound to the e environment
e = (a: "got it", f: { { ~a.postln }.inEnvir.defer(0.5) });
e.use { e.f };
::


method::case

Function implements a case method which allows for conditional evaluation with multiple cases. Since the receiver represents the first case this can be simply written as pairs of test functions and corresponding functions to be evaluated if true. Unlike Object-switch, this is inlined and is therefore just as efficient as nested if statements.

code::
(
var i, x, z;
z = [0, 1, 1.1, 1.3, 1.5, 2];
i = z.choose;
x = case
	{ i == 1 }   { \no }
	{ i == 1.1 } { \wrong }
	{ i == 1.3 } { \wrong }
	{ i == 1.5 } { \wrong }
	{ i == 2 }   { \wrong }
	{ i == 0 }   { \true };
x.postln;
)
::

method::matchItem

Interface shared with other classes that implements pattern matching. See also: matchItem.
Function.matchItem evaluates the function with the item as argument, expecting a Boolean as reply.

code::
{ |x| x > 5 }.matchItem(6); // true
::

performDegreeToKey(scaleDegree, stepsPerOctave = 12, accidental = 0)

use a function as a conversion from scale degree to note number. See also SequenceableCollection and Scale

code::
// a strange mapping
(
var f = {|degree, stepsPerOctave, acc|
	(1.8 ** (degree % stepsPerOctave) + acc).postln
};
Pbind(
	\scale, f,
	\degree, Pseq([0, 1, 2b, 3s, 4s, 6, 14, [0, 2, 4], [1, 3, 6]], inf)
).play
)
::

subsection::Exception Handling


For the following two methods a return ^ inside of the receiver itself cannot be caught. Returns in methods called by the receiver are OK.


method::try

Executes the receiver. If an exception is thrown the catch function handler is executed with the error as an argument. handler itself can rethrow the error if desired.

method::protect

Executes the receiver. The cleanup function handler is executed with an error as an argument, or nil if there was no error. The error continues to be in effect.

subsection::Audio

method::play

This is probably the simplest way to get audio in SC3. It wraps the Function in a SynthDef (adding an Out ugen if needed), creates and starts a new Synth with it, and returns the Synth object. A Linen is also added to avoid clicks, which is configured to allow the resulting Synth to have its \gate argument set, or to respond to a release message. Args in the function become args in the resulting def.

code::
x = { |freq = 440| SinOsc.ar(freq, 0, 0.3) }.play; // this returns a Synth object;
x.set(\freq, 880); // note you can set the freq argument
x.defName; // the name of the resulting SynthDef (generated automatically in a cycle of 512)
x.release(4); // fadeout over 4 seconds
::

Many of the examples make use of the Function.play syntax.
Note that reusing such code in a SynthDef requires the addition of an Out ugen.

code::
// the following two lines produce equivalent results
{ SinOsc.ar(440, 0, 0.3) }.play(fadeTime: 0.0);
SynthDef(\help_FuncPlay, { Out.ar(0, SinOsc.ar(440, 0, 0.3))}).play;
::

Function.play is often more convienent than SynthDef.play, particularly for short examples and quick testing. The latter does have some additional options, such as lagtimes for controls, etc. Where reuse and maximum flexibility are of greater importance, SynthDef and its various methods are usually the better choice.

argument::target
a Node, Server, or Nil. A Server will be converted to the default group of that server. Nil will be converted to the default group of the default Server.
argument::outbus
the output bus to play the audio out on. This is equivalent to Out.ar(outbus, theoutput). The default is 0.
argument::fadeTime
a fadein time. The default is 0.02 seconds, which is just enough to avoid a click. This will also be the fadeout time for a release if you do not specify.
argument::addAction
see Synth for a list of valid addActions. The default is \addToHead.
argument::args
arguments

method::scope

As play above, and calls Server-scope to open a scope window in which to view the output.

code::
{ FSinOsc.ar(440, 0, 0.3) }.scope(1)
::

argument::numChannels
The number of channels to display in the scope window, starting from outbus. The default is 2.
argument::outbus
The output bus to play the audio out on. This is equivalent to Out.ar(outbus, theoutput). The default is 0.
argument::fadeTime
A fadein time. The default is 0.02 seconds, which is just enough to avoid a click.
argument::bufsize
The size of the buffer for the ScopeView. The default is 4096.
argument::zoom
A zoom value for the scope's X axis. Larger values show more. The default is 1.

method::plot

Calculates duration in seconds worth of the output of this function, and plots it in a GUI window. Unlike play and scope it will not work with explicit Out Ugens, so your function should return a UGen or an Array of them. The plot will be calculated in realtime.

code::
{ SinOsc.ar(440) }.plot(0.01, bounds: Window.screenBounds);

{ {|i| SinOsc.ar(1 + i)}.dup(7) }.plot(1);
::


argument::duration
The duration of the function to plot in seconds. The default is 0.01.
argument::server
The Server on which to calculate the plot. This must be running on your local machine, but does not need to be the internal server. If nil the default server will be used.
argument::bounds
An instance of Rect or Point indicating the bounds of the plot window.
argument::minval
the minimum value in the plot. Defaults to -1.0.
argument::maxval
the maximum value in the plot. Defaults to 1.0.
argument::parent
a window to place the plot in. If nil, one will be created for you.

subsection::Conversion

method::asSynthDef

Returns a SynthDef based on this Function, adding a Linen and an Out ugen if needed.

argument::rates
An Array of rates and lagtimes for the function's arguments (see SynthDef for more details).
argument::prependArgs
arguments
argument::outClass
The class of the output ugen as a symbol. The default is \Out.
argument::fadeTime
a fadein time. The default is 0.
argument::name
the name of the SynthDef

method::asDefName

Performs asSynthDef (see above), sends the resulting def to the local server and returns the SynthDefs name. This is asynchronous.

code::
x = { SinOsc.ar(440, 0, 0.3) }.asDefName; // this must complete first
y = Synth(x);
::

method::asRoutine

Returns a Routine using this as its func argument.

method::r

Returns a Routine using this as its func argument.

code::
a = r { 5.do { |i| i.rand.yield } };
a.nextN(8);
::

method::p

Returns a Prout using this as its func argument.

code::
a = p { 5.do { |i| i.rand.yield } };
x = a.asStream;
x.nextN(8);
::

This is useful for using ListComprehensions in Patterns:

code::
Pbind(\degree, p {:[x, y].postln, x<-(0..10), y<-(0..10), (x + y).isPrime }, \dur, 0.3).play;
::

examples::

subsection::Exception Handling

code::
// no exception handler
value { 8.zorg; \didnt_continue.postln; }

try { 8.zorg } {|error| error.postln; \cleanup.postln; }; \continued.postln;

protect { 8.zorg } {|error| error.postln; }; \didnt_continue.postln;
::

code::
try { 123.postln; 456.throw; 789.postln } {|error| [\catch, error].postln };

try { 123.postln; 789.postln } {|error| [\catch, error].postln };

try { 123.postln; nil.throw; 789.postln } {|error| [\catch, error].postln };

protect { 123.postln; 456.throw; 789.postln } {|error| [\onExit, error].postln };

protect { 123.postln; 789.postln } {|error| [\onExit, error].postln };

(
try {
	protect { 123.postln; 456.throw; 789.postln } {|error| [\onExit, error].postln };
} {|error| [\catch, error].postln };
)

value { 123.postln; 456.throw; 789.postln }

value { 123.postln; Error("what happened?").throw; 789.postln }
::

code::
(
a = [\aaa, \bbb, \ccc, \ddd];
a[1].postln;
a[\x].postln;
a[2].postln;
)

(
try {
	a = [\aaa, \bbb, \ccc, \ddd];
	a[1].postln;
	a[\x].postln;
	a[2].postln;
} {|error| \caught.postln; error.dump }
)

(
try {
	a = [\aaa, \bbb, \ccc, \ddd];
	a[1].postln;
	a[\x].postln;
	a[2].postln;
} {|error| \caught.postln; error.dump; error.throw }
)

(
protect {
	a = [\aaa, \bbb, \ccc, \ddd];
	a[1].postln;
	a[\x].postln;
	a[2].postln;
} {|error| \caught.postln; error.dump }
)
::