Quantcast

Why are local variables preferable to global ones?

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Why are local variables preferable to global ones?

deepbluesome
This post has NOT been accepted by the mailing list yet.
I found it in lots of examples written by experienced supercollider programmers.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Nathan Ho

deepbluesome wrote
I found it in lots of examples written by experienced supercollider programmers.
Hi deepbluesome,

please note the yellow banner "This message has NOT been accepted by the mailing list yet." This means that your message is only visible to the web interface and doesn't get delivered to subscribers' inboxes, limiting the number of people who can see it. To fix this problem, click on the link that says "Add an address to sc-users-acl" in the header. (This subscription just lets you post to the list and won't clutter your inbox.)

in general, the injunction on global variables isn't unique to supercollider -- it's a well-known principle in the programming world that if a variable is only needed in one particular block of code, it should only be scoped to that block of code. use of global variables can easily lead to bugs. simple example:

(
// prints integers starting from 1 and waiting 1 second between pritns
x = 0;
Routine.run {
    loop {
        x = x + 1;
        x.postln;
        1.wait;
    };
};
)

it appears to work... until you try to run two concurrent counters, and they interfere with each other. in general, asking the question "what if you need to run multiple copies of this" should give you an idea of why local variables are better.

there are other reasons not to use global variables, and there's a good amount of information on the web about this. however, supercollider has its own twists. if you are executing code out of a document, you often need persistent state between executions of different blocks of code. ~tilde variables are the best for this. they aren't global, but unless you're working with Environment objects like in JITlib, they pretty much behave like global variables. some people, however, like to use them to get out of typing "var" statements, which is a bad practice.

the lowercase letters a-z are truly global, technically instance variables of Interpreter objects (run "Interpreter.openCodeFile"). imo, these were a mistake in sclang. like the ~tilde variables, people use them to get out of typing "var" statements. even worse, they encourage use of cryptic variable names -- i want to cry when i see "SynthDef(\foo, { s = SinOsc.ar; e = Env.perc; ... }).add".

they should not be used except for quickie demonstration purposes, like if you want to run "x = Synth(\wubwubwub);" and "x.free" to test out your dubstep bassline. they should never, ever be used in class library code.

sorry for soapboxing a bit, hope this helps.


nathan
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

julian.rohrhuber
Just to add to Nathan’s good advice:

the use of variables in programming is one of the most controversial topic in programming. As you have noticed, SuperCollider offers you a number of possibilities, and it depends on your style which you prefer. More than that, it depends on what you are actually working on. But it’s good advice to use declared variables when it is easy.

- declared variables (var x) are used most of the time, and wherever need *lexical scoping*.
- environment variables (~x) are used in a number of specific cases, and wherever you need *dynamic scoping*.
- interpreter variables (x and all letters a-z) are used for interactive programming, and in making examples *short and easy to mess with*

You have to always decide whether you need things locally or globally, or somewhere inbetween.


P.S.

The proxy objects, like Ndef always have also an object that just uses local variables. Instead of Ndef(\x) you can make your own var x = NodeProxy.new, or use a ProxySpace. Databases like Archive and SynthDescLib are special, but also offer you the global - local distinction.



> On 11.05.2017, at 04:46, [hidden email] wrote:
>
>
>
> deepbluesome wrote
>> I found it in lots of examples written by experienced supercollider
>> programmers.
>
> Hi deepbluesome,
>
> please note the yellow banner "This message has NOT been accepted by the
> mailing list yet." This means that your message is only visible to the web
> interface and doesn't get delivered to subscribers' inboxes, limiting the
> number of people who can see it. To fix this problem, click on the link that
> says "Add an address to sc-users-acl" in the header. (This subscription just
> lets you post to the list and won't clutter your inbox.)
>
> in general, the injunction on global variables isn't unique to supercollider
> -- it's a well-known principle in the programming world that if a variable
> is only needed in one particular block of code, it should only be scoped to
> that block of code. use of global variables can easily lead to bugs. simple
> example:
>
> (
> // prints integers starting from 1 and waiting 1 second between pritns
> x = 0;
> Routine.run {
>    loop {
>        x = x + 1;
>        x.postln;
>        1.wait;
>    };
> };
> )
>
> it appears to work... until you try to run two concurrent counters, and they
> interfere with each other. in general, asking the question "what if you need
> to run multiple copies of this" should give you an idea of why local
> variables are better.
>
> there are other reasons not to use global variables, and there's a good
> amount of information on the web about this. however, supercollider has its
> own twists. if you are executing code out of a document, you often need
> persistent state between executions of different blocks of code. ~tilde
> variables are the best for this. they aren't global, but unless you're
> working with Environment objects like in JITlib, they pretty much behave
> like global variables. some people, however, like to use them to get out of
> typing "var" statements, which is a bad practice.
>
> the lowercase letters a-z are truly global, technically instance variables
> of Interpreter objects (run "Interpreter.openCodeFile"). imo, these were a
> mistake in sclang. like the ~tilde variables, people use them to get out of
> typing "var" statements. even worse, they encourage use of cryptic variable
> names -- i want to cry when i see "SynthDef(\foo, { s = SinOsc.ar; e =
> Env.perc; ... }).add".
>
> they should not be used except for quickie demonstration purposes, like if
> you want to run "x = Synth(\wubwubwub);" and "x.free" to test out your
> dubstep bassline. they should never, ever be used in class library code.
>
> sorry for soapboxing a bit, hope this helps.
>
>
> nathan
>
>
>
> --
> View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Why-are-local-variables-preferable-to-global-ones-tp7632244p7632246.html
> Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.
>
> _______________________________________________
> sc-users mailing list
>
> info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

daniel-mayer
In reply to this post by Nathan Ho

Many sensible things have been said by Nathan and Julian.
Just one add: if you need globals and want to avoid cluttering
the current (topEnvironment's) namespace, define your own Dictionary/Environment/Event

From Event help:


Event as a name space for keeping objects
Because of this simple syntax, Events are often used as name space for keeping objects:
// using an event to store values

q = (n: 10, x: [1, 2, 3]);
q[\y] = q[\x] * q[\n];    // similar to ~y = ~x * ~n, but in a separate name space
q.y = q.x * q.n;    // shorter way to do the same (pseudo-methods)
q.y;            // [ 100, 200, 300 ]


If you want to store Functions, you have to be a bit more careful, see 



Regards

Daniel

-----------------------------
www.daniel-mayer.at
-----------------------------

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

daniel-mayer
In reply to this post by Nathan Ho

Am 11.05.2017 um 04:46 schrieb [hidden email]:

> the lowercase letters a-z are truly global, technically instance variables
> of Interpreter objects (run "Interpreter.openCodeFile").

> imo, these were a mistake in sclang.

As another add, I'd like to disagree with the last sentence.
As Julian pointed out, their main use is interactive programming.

This can be a short demo, but also the starting point of a larger project.
From my own work I can say that quite often I start
with a code block which uses interpreter variables and extend it step by step.

I very much appreciate it that I don't have to use a stiff variable syntax from the
beginning, which forces additional typing.

At some point I might exchange interpreter variables, but this depends on the size of the code involved,
also on the decision if I want to combine this with other stuff which uses a number of variables too.

Everything depends: it might be a crucial difference, if you want to use code in a live performance or not.
In the latter case you might want to spontanously combine unlrelated code blocks and want
to go sure that variables are independent - clean variable management is a must then !

Also consider the possibility of dynamic scoping:
I do this a lot and a number of my extension classes (PLx patterns) use this.

E.g. an expression like

Pfunc { ~a ** 2 - 1 }

doesn't refer to a "global" ~a, Streams, which are made from this Pattern,
will refer to the value of ~a in the Environment, where they are made.
This is not a mess, but quite practical.
However, as with scoping in general, you have to know what you are doing,
otherwise it can definitely become one :)

Regards

Daniel

-----------------------------
www.daniel-mayer.at
-----------------------------



_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Nathan Ho
On 2017-05-13 15:24, [hidden email] wrote:

> This can be a short demo, but also the starting point of a larger
> project.
> From my own work I can say that quite often I start
> with a code block which uses interpreter variables and extend it step
> by step.
>
> I very much appreciate it that I don't have to use a stiff variable
> syntax from the
> beginning, which forces additional typing.
>
> At some point I might exchange interpreter variables, but this depends
> on the size of the code involved,
> also on the decision if I want to combine this with other stuff which
> uses a number of variables too.
>
> Everything depends: it might be a crucial difference, if you want to
> use code in a live performance or not.
> In the latter case you might want to spontanously combine unlrelated
> code blocks and want
> to go sure that variables are independent - clean variable management
> is a must then !

i would probably object somewhat less to the globals if they weren't
arbitrarily restricted to single letters. i don't have an alternate
proposal, but the design choice of exactly 26 global variables is just
weird as hell to me.


nathan

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

julian.rohrhuber
>
> i would probably object somewhat less to the globals if they weren't arbitrarily restricted to single letters. i don't have an alternate proposal, but the design choice of exactly 26 global variables is just weird as hell to me.

it is really easy to remember which ones are exactly these 26 variables.
_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Shivers Null
I'm not sure anyone indicated that remembering the 26 global variables was difficult.  However, I have to agree, coming to supercollider after programming in c++ for 20 years and having written a language myself... this sort of thing is really weird and rather irksome.  I'm not complaining, I LOVE sc and am glad to work in it, but come on...

On Sun, May 14, 2017 at 11:49 AM <[hidden email]> wrote:
>
> i would probably object somewhat less to the globals if they weren't arbitrarily restricted to single letters. i don't have an alternate proposal, but the design choice of exactly 26 global variables is just weird as hell to me.

it is really easy to remember which ones are exactly these 26 variables.
_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Josh Parmenter
keep in mind, they are actually Environment Variables, and they are the ones the Interpreter sets up for you.
They are handy for quick prototyping of things. 
IF you really want something with full Environment scope, you should use ~envVariables which can have however many letters, and can be more descriptive. 

But - I would argue against it. I’m not going to go into those details. Just pointing out what a-z really are, and that there actually is more than just those if you really want them:

(

~noVarDelcarationNeededOrSingleLetter = 42;
b = 42;
~noVarDelcarationNeededOrSingleLetter.postln;

( b == ~noVarDelcarationNeededOrSingleLetter).postln;

nil;
)

^ valid SC code.

Josh

On May 14, 2017, at 9:22 PM, [hidden email] wrote:

I'm not sure anyone indicated that remembering the 26 global variables was difficult.  However, I have to agree, coming to supercollider after programming in c++ for 20 years and having written a language myself... this sort of thing is really weird and rather irksome.  I'm not complaining, I LOVE sc and am glad to work in it, but come on...

On Sun, May 14, 2017 at 11:49 AM <[hidden email]> wrote:
>
> i would probably object somewhat less to the globals if they weren't arbitrarily restricted to single letters. i don't have an alternate proposal, but the design choice of exactly 26 global variables is just weird as hell to me.

it is really easy to remember which ones are exactly these 26 variables.
_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Nathan Ho
In reply to this post by Shivers Null
On 2017-05-14 21:22, [hidden email] wrote:
> I'm not sure anyone indicated that remembering the 26 global variables
> was difficult.  However, I have to agree, coming to supercollider
> after programming in c++ for 20 years and having written a language
> myself... this sort of thing is really weird and rather irksome.  I'm
> not complaining, I LOVE sc and am glad to work in it, but come on...

yeah exactly. my objection is not that they're hard to remember or
anything, but that it's asymmetrical. local variables can use any valid
identifier string, environment variables can use any valid identifier
string, but globals? sorry pal, you're stuck with single letters.

what if there was a different syntax for globals? :foo?


nathan

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

alberto.decampo

> On 15/05/2017, at 07:49 , [hidden email] wrote:
>
> On 2017-05-14 21:22, [hidden email] wrote:
>> I'm not sure anyone indicated that remembering the 26 global variables
>> was difficult.  However, I have to agree, coming to supercollider
>> after programming in c++ for 20 years and having written a language
>> myself... this sort of thing is really weird and rather irksome.  I'm
>> not complaining, I LOVE sc and am glad to work in it, but come on...
>
> yeah exactly. my objection is not that they're hard to remember or anything, but that it's asymmetrical. local variables can use any valid identifier string, environment variables can use any valid identifier string, but globals? sorry pal, you're stuck with single letters.
>
> what if there was a different syntax for globals? :foo?

One common practice is to make a interpreter global var a dictionary, and use that for arbitrary names:

q = q ? ();
q.myDescriptivelyNamedVar1 = (1..8);

etc


>
>
> nathan
>
> _______________________________________________
> sc-users mailing list
>
> info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

adam.a.juraszek
I'd like to weigh in on this issue and show something I've been working on over the weekend
what I like to do is manage different environments and use a system of 'importing' other .scd files into the current context
so for example let's say I have a module.scd file with some environment variables defined, their scope is in that file module.scd
If I start working in another file in the same directory I can do 'module'.import; and then all of those variables inside are accessible like this ~module.var1, ~module.var2 etc etc
I use this because it's useful for me to split things up like that into separate files, and I can make sure that each module always has the resources like buffers or patterns that it needs to do its thing. If I'm working on a large piece for example with many different parts, I can load just that one module and tweak things in isolation without starting the whole piece from scratch
https://github.com/Endut/myLib here it is, maybe it could be useful for someone else too this kind of python style import statement
I still would like to make it work interactively with Document so the environment of a module changes if that document is edited and some part of it is executed but if anyone would give it a try and give me some advice I would be very grateful
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

Eric Lyon
Interesting conversation. The fact that a particular language feature could be misused, or looks weird, does not seem to me sufficient reason to remove it, especially if it affords some convenience.

-Eric




On Mon, May 15, 2017 at 5:41 AM, <[hidden email]> wrote:
I'd like to weigh in on this issue and show something I've been working on over the weekend
what I like to do is manage different environments and use a system of 'importing' other .scd files into the current context
so for example let's say I have a module.scd file with some environment variables defined, their scope is in that file module.scd
If I start working in another file in the same directory I can do 'module'.import; and then all of those variables inside are accessible like this ~module.var1, ~module.var2 etc etc
I use this because it's useful for me to split things up like that into separate files, and I can make sure that each module always has the resources like buffers or patterns that it needs to do its thing. If I'm working on a large piece for example with many different parts, I can load just that one module and tweak things in isolation without starting the whole piece from scratch
https://github.com/Endut/myLib here it is, maybe it could be useful for someone else too this kind of python style import statement
I still would like to make it work interactively with Document so the environment of a module changes if that document is edited and some part of it is executed but if anyone would give it a try and give me some advice I would be very grateful

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Aw: Re: [sc-users] Why are local variables preferable to global ones?

daniel-mayer
In reply to this post by alberto.decampo

> Gesendet: Montag, 15. Mai 2017 um 10:40 Uhr
> Von: [hidden email]
> An: [hidden email]

> One common practice is to make a interpreter global var a dictionary, and use that for arbitrary names:
>
> q = q ? ();
> q.myDescriptivelyNamedVar1 = (1..8);
>
> etc


Exactly: with use of only *one* global interpreter variable you get an unlimited namespace by just *one* additional character ('.'). You can even get an unlimited number of unlimited namespaces (q.projectX). There's also Library and Archive, would there really be the need for another type of global variable building ? It would introduce further confusion in the variable discussion.

Point is that many people are not aware of the already existing possibilities of Environment, Event etc., this is obvious as the same questions are coming up again and again. IMO this is clearly another documentation problem.

At the moment things are spread, e.g. there's the chapter on "Event as a name space for keeping objects" in Event help and on "Using Environments as object prototypes" in Environment help, but no general guidelines or recommendations on variable use or only more neutral: a listing of variable possibilities.

The three lines, sketched by Julian above in this thread, could be a starting point for such a document, no ?

- declared variables (var x) are used most of the time, and wherever need *lexical scoping*.
- environment variables (~x) are used in a number of specific cases, and wherever you need *dynamic scoping*.
- interpreter variables (x and all letters a-z) are used for interactive programming, and in making examples *short and easy to mess with*

Regards

Daniel

-------------------------
http://daniel-mayer.at
-------------------------


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

julian.rohrhuber
In reply to this post by Nathan Ho

> On 15.05.2017, at 07:49, [hidden email] wrote:
>
> On 2017-05-14 21:22, [hidden email] wrote:
>> I'm not sure anyone indicated that remembering the 26 global variables
>> was difficult.  However, I have to agree, coming to supercollider
>> after programming in c++ for 20 years and having written a language
>> myself... this sort of thing is really weird and rather irksome.  I'm
>> not complaining, I LOVE sc and am glad to work in it, but come on...
>
> yeah exactly. my objection is not that they're hard to remember or anything, but that it's asymmetrical.

yes, I understood of course. I was just kidding: you asked why and I told you why.

> local variables can use any valid identifier string, environment variables can use any valid identifier string, but globals? sorry pal, you're stuck with single letters.

I think that was the original intention: nothing should really be global, so if you have to, please use only for really simple things.


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why are local variables preferable to global ones?

ddw_music
julian.rohrhuber wrote
> local variables can use any valid identifier string, environment variables can use any valid identifier string, but globals? sorry pal, you're stuck with single letters.

I think that was the original intention: nothing should really be global, so if you have to, please use only for really simple things.
Perhaps the discussion is being derailed a bit by overlooking the distinction between "global" and "persistent" variables.

You don't really need global variables, not really ... and if you ever tried to debug a medium-complex classic BASIC program (where all variables were global), you know exactly why global variables are generally not to be relied on for anything serious.

But... since SC is based on a read-eval-print-loop, we do need variables that are accessible outside the scope of a code block submitted to the interpreter as a unit: persistent variables.

What have been called "global variables" here are really "interpreter variables," offered as a convenience but, as Julian said, not meant to support any kind of serious architecture.

Environment variables are persistent, and for many users, they are practically global. But ProxySpace confounds that: once you push a ProxySpace, you can use environment variables only for NodeProxies, and nothing else. So it would be hasty to say that there is no use for a "persistent variable" concept separate from environment variables.

The suggestion of an alternate syntax for "globals," e.g. :name, offers no syntactic benefit over environment variables, and some functional benefit. The functional benefit is independence from whatever environment is currently being "use"d (or has been "push"ed). In simple, interactive "messing around" sessions, I'd argue that the benefit of non-environment, persistent variables is largely cosmetic. In larger architectures, there are better solutions for persistence -- dedicated storage objects, for instance, allow each "piece" to have its own namespace, making it easier to grow from one-piece-at-a-time performances into longer, continuous sets than if one began with globals and then had to retool because of namespace collisions that one didn't anticipate at first.

Globals would make it easier for some users to get started... but it also means those users would hit certain roadblocks sooner. The present situation may offend some sensibilities, but it also might not be so awful.

Admitting to a bit of devil's-advocacy in the above...
hjh
Loading...