Why predeclared variables?


Does anyone know why sclang requires you to declare variables at the top of functions instead of inline? I’d be interested to know if there’s something about the interpreter or whatever that means its necessary? I’m not an expert on programming languages or interpreters, so I’d have a tough time reading the source code, but I’m just curious about this as it’s not necessary in C any more.


I think the technical term is “hoisted” - javascript automatically hoists var declarations, meaning it treats them as if they were placed at the beginning of a function. This makes for some weird and awful things - you can “var foo” declare a variable after you do foo = 10, for example :face_vomiting:.

SuperCollider does not do this - I don’t know of a specific reason. I’ve tried to add this a couple times before, but it seems extra tricky due to some particulars of the language.

If anyone wants to try to be a hero and tackle this feature - or just wants to learn a little bit about how sclang is parsed, or how parsers work in general… The sclang parser lives in the lang11d file here. The make_parser.sh script uses the lang11d to generate actual C++ code for the parser, which will turn source code into AST nodes that are then compiled. Adding “hoisted var declarations” support would most likely be a parser change, plus possibly a little C++ to keep track of variable declarations collected during the course of a function. If you change the parser and run make_parser.sh it will generate the corresponding .h and .cpp files, or notify you if for some reason you made a change that isn’t logically consistent (this is usually what happens). Bison parser syntax is pretty well documented, and it’s not so hard to play around with the lang11d to make minor modifications and see what you get.


as a real-time interpreted language, declaring a var requires memory, and memory allocation (and setting aside of space) is costly. Bunching it all together means you can figure out how much memory it will take all at once.
Also - this was put in place in the late '90s, early 2000s when this was a pretty common practice. It may be possible to change this now, but it would likely be a lot of work.


Heh, the tantalizing thing is, it’s NOT a lot of work - I would guess it’s on the order of a ~10-20 line change to the parser and some PyrParseNode code. And, it wouldn’t even have a big testing impact, since it only affects one narrow part of the parser and would have no effect on functionality once something is compiled. It’s just that - the change required takes a deep-ish understanding of the parser and the language, which few of us have. It’s one of those “two weeks to research, ten minutes to make the change” sort of things.


Hmm, mighty interesting. As I say, I have only a passing knowledge of how interpreters work (e.g. made a toy lisp once, but not much further) but this is quite an intriguing challenge. Might try to understand it a bit if the urge strikes. Thanks for your post.


Wow yeah a brief read looks like nothing I’ve seen before. Seems I’d have to learn quite a lot about Bison to understand this. Oh well, could be a fun weekend project to learn about that.


if you’d like to familiarize yourself with this part of sclang but want to try something considerably easier, this issue is perfect:

incidentally it’s the oldest open issue in the SC github repository. this is okay:

Foo { }
+ SinOsc { }

this is invalid syntax:

+ SinOsc { }
Foo { }

and i doubt there’s any good reason for that other than laziness when the parser was being written.

if you or anyone else reading wants to take this on, it would be super appreciated!!


But maybe the worst thing about parsing in SuperCollider is math, no ???

1 - 1/2         ->  0         //// hm ?
1/2 - 1/2      ->  -0.25  ////  ....

I mean, SuperCollider is essentially about doing this kind of thing. I tend to love SC syntax, and hoisting is far behind the math problem, IMO.

Also, good conditional management could be a good improvement, in order to do this very noble

if (10 < x < 20) 

without parenthesis ! And I suspect it would be the same problem as math priorities.

Would it be very hard to change that ?


yes. it would be very hard to change that.