5
$\begingroup$

Closures are functions that borrow the environment in which they are declared and can use and modify its variables at any times indipendently from where they're called, like in this example:

function createclosure(x)
    return function() --Anonymous closure
        print(x) --The variable x is caught and can be used anywhere
    end
end

myclosure = createclosure(123)

myclosure() --prints "123"

What I am looking for is quite the opposite: functions that borrow the environment in which they are called and can use and modify its variables:

function anti_closure()
    x = x + 10 --x is borrowed from the environment in which the function is called
    print(x)
end

function environment(x)
    print(x)
    anti_closure()
    x = x - 5
    print(x)
end

environment(23) --prints "23", "33" (from the anticlosure) and then "28" (because x was permanently modified in the anticlosure)

Is there a name for these type of functions? Are there languages that implement them? If not, why?

$\endgroup$
  • $\begingroup$ @Evil awww it sounded like a new thing to me because neither Lua nor Lisp and Python let me do that. I guess you are right then $\endgroup$ – user6245072 Jul 17 '16 at 21:05
  • $\begingroup$ @Evil I just tried and C++ doesn't let me do it too. $\endgroup$ – user6245072 Jul 17 '16 at 21:19
  • $\begingroup$ @Evil the link you provided is basically a closure. Imagine a function in which you need an helper function that changes the local variables of the outer function. With closures you would have to declare it each time the function is called, from inside the outer function. While with anti closures you could just declare it once and it will work every time because it can modify the variables of the outer function whitout being declared inside it. $\endgroup$ – user6245072 Jul 18 '16 at 4:57
  • $\begingroup$ @Evil I don't know about prototyping in Javascript, but yes, it's that. Meanwhile, where can I find the differences between dynamic and static scoping? $\endgroup$ – user6245072 Jul 18 '16 at 5:24
  • $\begingroup$ @Evil Oh i get it. $\endgroup$ – user6245072 Jul 18 '16 at 5:51
5
$\begingroup$

You are talking about static vs. dynamic scoping of variables. Most langauges today have static scoping, but famously the early LISP had dynamic scoping.

Scoping is a general feature of a programming language and is not something that a closure does (although I suppose one could organize things so that it does). In any case, look up "dynamic" and "static" scoping.

$\endgroup$
  • $\begingroup$ Why is it? Why do languages mostly use static scoping? $\endgroup$ – user6245072 Jul 18 '16 at 9:51
  • 1
    $\begingroup$ Because in most situations static scoping is what is needed in practice. There are few cases where dynamic scoping is the correct one. $\endgroup$ – Andrej Bauer Jul 18 '16 at 14:33
  • $\begingroup$ I'm confused as to which of the two scopings in question is called dynamic. In the accepted answer in this post, stackoverflow.com/questions/958983/…, dynamic scoping is refered to as the second case here (borrow the environment from where you are called), whereas static scoping is refered to as "lexical scoping" (which, to my understanding, means that the bindings are determined based on the code structure, more syntax less semantics). $\endgroup$ – Ariel Jul 18 '16 at 16:12
  • $\begingroup$ I vaguely remember that dynamic scoping refers to the first case here (borrow the environment from where you are created). It seems there are three terms, what is the accepted terminology? $\endgroup$ – Ariel Jul 18 '16 at 16:12
1
$\begingroup$

You are interested in Dynamic scoping. The pure dynamic scoping gives confusion about execution so opposite to static scope you cannot easily read code and be sure how it will execute or in case of languages that support anonymous functions and first-class citizens it is non-trivial task.
With static scope you have to bind function to environment it is called in by declaring it there, binding or using call for function.
In dynamic scope the anti_closure should work, but some mechanism were implemented to avoid it in general. Some languages require to mark scope (like perl with local) or explicitly define dynamic scoping like Clojure.

Generally this scheme is avoided due to shadowing, saving context of environment and making every variable global (in fact Clojure does that, every variable is global in this case).

Static scope gives the ability to resolve connection between variables at compile time, in dynamic one this gives late binding or a form of function stubs, delegates - which cannot be optimized fully during compile time.

If you substitute anti_closure with global function taking parameter by reference then such helper function works in static scope, without downsides of copying environment.

Why this is avoided? If you are able to introduce new function at any place that is anti_closure then you must have access to tree of environments of all declared variables so it is equivalent to static scope with all variables being global, but still the second one is easier to compile.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.