|
49 | 49 | <ul class='toc'></ul></ul><li class='toc1'><a href='#Audio%20Control%20Structures:%20Do%20not%20use%20.if%20etc.%20in%20Synths!'>Audio Control Structures: Do not use .if etc. in Synths!</a></li> |
50 | 50 | <ul class='toc'></ul><li class='toc1'><a href='#Syntax%20of%20conditional%20expressions'>Syntax of conditional expressions</a></li> |
51 | 51 | <ul class='toc'><li class='toc2'><a href='#Trailing%20argument%20blocks'>Trailing argument blocks</a></li> |
52 | | -<ul class='toc'><li class='toc3'><a href='#Return%20values%20(.if,%20.case,%20.switch)'>Return values (.if, .case, .switch)</a></li> |
| 52 | +<ul class='toc'><li class='toc3'><a href='#Receiver%20blocks%20(.case,%20.while)'>Receiver blocks (.case, .while)</a></li> |
| 53 | +<ul class='toc'></ul><li class='toc3'><a href='#Return%20values%20(.if,%20.case,%20.switch)'>Return values (.if, .case, .switch)</a></li> |
53 | 54 | <ul class='toc'></ul></ul></ul></ul></div><div id='menubar'></div> |
54 | 55 | <div class='contents'> |
55 | 56 | <div class='header'> |
@@ -451,23 +452,41 @@ <h3><a class='anchor' name='Trailing%20argument%20blocks'>Trailing argument bloc |
451 | 452 | <p>The above C-like syntax is enabled in SuperCollider by a syntactic mechanism called "trailing argument blocks". A <strong>block</strong> is any expression enclosed in curly brackets, e.g. <code>{ trueFuncBody }</code>. The syntax <code>receiver.method { expr1 } { expr2 }</code> is equivalent to <code>receiver.method({ expr1 }, { expr2 })</code>. That is, the round brackets and comma are omitted. This can be combined with the function call syntax such that we can write <code>method(receiver) { expr1 } { expr2 }</code>; this in turn gives the above form of the if-statement in function call notation with trailing argument block. |
452 | 453 | <p>However, even if the curly brackets now indicate where one argument ends and where the next one starts, they also retain their usual role of showing that the enclosed expression should serve as the definition of a <a href="./../Classes/Function.html">Function</a> instance. |
453 | 454 | <p>This means, <strong>first</strong>, that the use of trailing argument syntax implies that <code>expr1</code> and <code>expr2</code> <em>define</em> Functions; <strong>second</strong>, that <code>expr1</code> and <code>expr2</code> should not already <em>be</em> Functions in their own right (unless you intend them to be). |
454 | | -<p>In examples:<div class='codeMirrorContainer'><textarea class='editor'>:: |
455 | | - |
456 | | -subsubsection:: Receiver blocks (.case, .while) |
457 | | - |
458 | | -If the receiver is itself an expression surrounded by curly brackets, a special version of the trailing argument block syntax can be used: |
459 | | -Here, not only the arguments can be written as trailing {}-enclosed blocks, but also the receiver itself. |
460 | | -For instance, code::{ funcBody }.fork:: is often written as code::fork { funcBody }::. |
461 | | - |
462 | | -When the method takes arguments, these arguments must also be written as {}-enclosed blocks, and follow the receiver: |
463 | | - |
464 | | -code:: method { receiverFuncBody } { arg1FuncBody } { arg2FuncBody }:: |
465 | | - |
466 | | -Among the conditional expressions discussed here, this applies to .while and .case (because they are methods of link::Classes/Function::.) |
| 455 | +<p>In examples:<div class='codeMirrorContainer'><textarea class='editor'>if(condition, trueFunc, falseFunc) |
| 456 | +// is NOT equivalent to |
| 457 | +if (condition) { |
| 458 | + trueFunc //trueFunc is distinct from trueFuncBody above! |
| 459 | +} { |
| 460 | + falseFunc //similarly here |
| 461 | +} |
| 462 | +// however, when we write |
| 463 | +t = { trueFuncBody }; |
| 464 | +f = { falseFuncBody }; |
| 465 | +// then indeed the following two expressions are equivalent |
| 466 | +// (though only the latter will inline): |
| 467 | +if(condition, t, f); |
| 468 | +if (condition) { |
| 469 | + trueFuncBody |
| 470 | +} { |
| 471 | + falseFuncBody |
| 472 | +} |
| 473 | +// On the other hand, the following cases are either wrong |
| 474 | +// or do different things than if(condition, t, f) |
| 475 | +if(condition) t f; //Syntax Error: |
| 476 | +// there are no curly brackets here that could indicate that t and f are arguments to if; |
| 477 | +if(condition) {t} {f}; //permissible but it may not be what you want to do. |
| 478 | +// equivalent to if(condition, {t}, {f}); |
| 479 | +// i.e.will return t rather than t.value as usually intended. |
| 480 | +if(condition, trueFuncBody, falseFuncBody); // the bodies are expressions, not Function objects; |
| 481 | +// whether this works depends on how those expressions respond to the .value method.</textarea> |
| 482 | +<button class='copy-button' aria-label='Copy code'><span class='copy-ico'>⧉</span><span class='check-ico'>✔</span></button></div> |
| 483 | +<h4><a class='anchor' name='Receiver%20blocks%20(.case,%20.while)'>Receiver blocks (.case, .while)</a></h4> |
467 | 484 |
|
468 | | -Example: |
469 | | -code:: |
470 | | -//function call notation with receiver block and trailing argument block |
| 485 | +<p>If the receiver is itself an expression surrounded by curly brackets, a special version of the trailing argument block syntax can be used: Here, not only the arguments can be written as trailing {}-enclosed blocks, but also the receiver itself. For instance, <code>{ funcBody }.fork</code> is often written as <code>fork { funcBody }</code>. |
| 486 | +<p>When the method takes arguments, these arguments must also be written as {}-enclosed blocks, and follow the receiver: |
| 487 | +<p><code>method { receiverFuncBody } { arg1FuncBody } { arg2FuncBody }</code> |
| 488 | +<p>Among the conditional expressions discussed here, this applies to .while and .case (because they are methods of <a href="./../Classes/Function.html">Function</a>.) |
| 489 | +<p>Example:<div class='codeMirrorContainer'><textarea class='editor'>//function call notation with receiver block and trailing argument block |
471 | 490 | while { testFuncBody } { loopFuncBody }; |
472 | 491 | // abbreviation of function call notation with trailing argument block |
473 | 492 | while ({ testFuncBody }) { loopFuncBody }; |
|
0 commit comments