Multiple code blocks

why can we interpret this in one go:

(
1.postln
);
(
().play
)

but not this:

(
666.postln;
);
(
var a = 5;
().play
). // ERROR: syntax error, unexpected VAR, expecting ')'

is this documented behavior or a bug? Sclang says "syntax error" but if I copy the file contents into sclang manually it works · Issue #6314 · supercollider/supercollider · GitHub

this works…

(
555.postln;
);
{
	var a = 5;
	().play
}.()

In the last code example, the var declaration is at the top of a function block. In the non-working example, it isn’t.

(
... this is a region ...
)

{
    ... this is a function ...
}

A region isn’t a SuperCollider syntactic construct – it’s really just an indication to the editor to locate selectable regions.

When you run code in SC, the language effectively wraps the whole code block in {} and compiles the whole block as a single function. So if you select a single region, you might get the idea that a region is always treated as a function. This isn’t true – when you select multiple regions, it’s just one function, and vars have to go at the top.

hjh

Sorry to revive this thread but this is one of the few explanations I’ve found that explains this. Is this why

> (
> var test = 2;
> test.squared.postln;
> )

works but

(
(
var test = 2;
test.squared.postln;
)
)

gives this error:

ERROR: syntax error, unexpected VAR, expecting ')'

I’ve often found myself wondering why i can’t execute with multiple code blocks (not functions) with independent variables. As a non coder i would have expected the code below to work as the variables are within their own code blocks but alas no.

(
(
var test = 2;
test.squared.postln;
);

(
var test = 3;
test.squared.postln;
)

You’ve answered your own question: because they’re not functions.

There is no concept of a “code block” in SC language. It doesn’t exist. As stated above, a “code block” is a convenience provided by the editor to make it easier to select a unit of code. But as far as the language compiler is concerned, the parentheses only delimit an expression sequence and this syntactic construct does not support variable declarations.

Variable declarations in a “code block” result from the fact that the compiler wraps every code string in a function – "1+1".compile returns a function matching the definition { 1+1 }. Vars are allowed at the beginning of this string but nowhere else except inside real function braces. If you saw { (var a; a = 10.rand); (var b; b = 10.rand) } I think you’d understand immediately that something is wrong (while acknowledging that it would be nice if the SC compiler would join us in 2024 and allow inline var declaration). It’s just as wrong when the surrounding function braces are implicit.

hjh

3 Likes

it would be nice to be able to nest regions though - and have key commands to send the inner and outer regions! I have built something like this for myself in Nvim…

3 Likes

I also had thought it would be nice if this example works. However, I do as follows:

(
{
var test = 2;
test.squared.postln;
}.();

{
var test = 3;
test.squared.postln;
}.()
)

I think implementing code blocks from the compiler side is impossible because we do not have more parentheses:

  • ( ): used
  • { }: used
  • [ ]: used

unless combining () with other symbols as follows:

(
(_
var test = 2;
test.squared.postln;
_);

(_
var test = 3;
test.squared.postln;
_)
)
1 Like

hi semiquaver
can you post your nvim code for this? :slight_smile:
thx in advance!

In my case I’m looking for block of code that start with a constructor P.someMethod(

So I have a vimscript (would probably do this in lua now!):

function! SelectPart ()
	call search('\(P.tune\|P.still\|P\|P.rpp\|P.synthV\|P.synthVs\|P.double\|P.lazyV\|P.lazyDouble\)(',"b")
	execute "normal 0V%"
	call feedkeys(":call SetPartCursorToNil()\<CR>")
endfunction

then i map

map ,< :call SelectPart()<CR><Plug>(scnvim-send-block)

I have some other interface bits that use the construction:

:call v:lua.require'scnvim'.send("arbitrary sclang code to be interpreted")

and you could very easily combine yanking to registers with scnvim.send for another approach!

1 Like

Thanks so much for all the responses! And apologies for not acknowledging the input earlier.

I’m a little surprised I’ve not recognized this reality earlier when working with larger scale code. Most tutorials I’ve encountered wth over the past year and a half are evaluations of small segments and rarely does I encounter examples with larger blocks of code. In fact some of the brilliant tutorials I’ve found helpful seem to suggest using Supercollider exclusively by evaluating shorter blocks sequentially. For instance https://bzoennchen.github.io/supercollider-book/chapters/supercollider/basics/1-code-execution.html states

The idea is to execute code incrementally as you develop. Instead of writing a complete program all at once, you’re encouraged to run small code snippets. Each code execution alters your environment, that is, the state of your program. This dynamic interaction is especially evident in live coding, but it’s also a useful practice when learning and exploring SuperCollider in general.

Good to hear about your contrastin experiences and techniques! Thanks.