Back with a basic question

I just don’t get it :frowning: , have to accept that code is just chinese to me
Here’s from the help file

f = { arg a; a.value + 3 };    // call 'value' on the arg; polymorphism awaits!
f.value(3);            // 3.value = 3, so this returns 3 + 3 = 6
g = { 3.0.rand; };
f.value(g);            // here the arg is a Function. Cool, huh?
f.value(g);            // try it again, different result

Our first variable f is assigned a function , inside the function , arg a , a.value +3
Arg a doesn’t have value yet , so value can’t be called , so we go the next line .
f.value(3) , what does this mean , that f now has a value of 3 , or does it give this value to arg a ?
Wasn’t .value just calling the value of that variable , so in this case a function , so why does it give the value 3 to f ( or a ) ??
We assign a new value to f when it’s already a function ?
Seems like it since the result is 6

So I think I get it , been playing around


~test ={ arg a ,b,c;(a+b+c)*a};
~test.value(4,5,6);

result :60
The .value assigns that value( or values ) to the corresponding argument(s) inside the function .
Sorry , but the manual is totally not clear about that , one could make that conclusin from the example but at least I didn’t .

f is a function that takes an argument then 1) sends .value to the argument and then 2) adds 3 to the result.

g is a function that returns a random number between 0 and 3.0 when you send .value to it.

so when you send .value to f passing g as an argument f will…

  1. send .value to g - you get a random number then 2) add 3

every time you send .value to f, f sends .value to g (giving a different random number each time) and adding 3.

aFunction.value just tells aFunction to evaluate itself and give us the return value.
.aFunctionvalue(args) tells aFunction to evaluate itself passing in the args in the parens

Yes , it’s clear now
The confusing part is that value calls value on an object and the next thing you read is that it can also send values to the arguments in a function , without explecitly explaing that .

It’s not calling value on the argument a.

It’s calling value on the object that a is referring to at the time (which was supplied from outside).

Methods are never, ever called on variables (or arguments, which are just variables whose values can be set from outside the function). A method can be called only on an object. a refers to an object, and it’s this object that is used.

(Edit: Initially wrote g, but the argument name is really a.)

hjh

1 Like

check out the method .value in the help for Function:

.value( … args)

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

{ |a, b| (a * b).postln }.value(3, 10);

the help for Function, Object and Array make great reading…

1 Like

First, sorry for misunderstanding your question – I see what it is now.

Second – you have a point – the tutorial jumps directly from value without arguments, directly to a “meta-” black-belt advanced usage. Indeed it would be helpful to have a normal argument example in between.

hjh

1 Like

If methods are never called on variables , how come we can do this ?
Surely the Play method works on variable c ( free does not )

c={SinOsc.ar(88,mul:0.1)!2;}


c.play
c.free

Your example is not calling play on c.

It’s calling play on the object to which c refers – i.e. the function. (In the class library, you can find an implementation of play for the Function class. You can’t find any implementation of play for variables.)

For convenience, when we talk about code, we might say as a shortcut that we’re calling xyz on a variable – but, in SC, this is never actually what it means.

Any usage of a variable in an expression always resolves the variable to its referent before applying methods. a = 1; b = 2; a + b isn’t a + b – the operation performed is 1 + 2. The + operator literally never knows that the values came from a and b. It knows only the values.

Variables are pointers to objects. They aren’t objects themselves.

I think this has been discussed before, right…?

c = { SinOsc.ar(88, mul:0.1) ! 2 };
-> a Function

// cool, now the variable c points to a Function

c.play;
-> Synth('temp__2' : 1002)

// the result of c.play was not c's Function!
// it's a different object

// but c refers to the Function, not to the new thing
// so 'c.free' will not talk to the new thing

c.free;

// nuclear option...
CmdPeriod.run;

d = c.play;

// a Synth, but now saved in a different variable

d.free;  // and this works

hjh