

What's an Environment? What's a Closure? What's a Continuation? What's a Scope? - naughtysriram

Can somebody explain me,<p>What's an Environment?
What's a Closure?
What's a Continuation?
What's a Scope?<p>I get confused while reading stuff on scheme as they all somehow sync to 'scope'. Thanks in advance.
======
lukesandberg
An environment is basically a mapping of variables to their values. Its
relative to a certain point in time of you program execution. So if you can
(legally) reference a variable at some point in your scheme program the it
must be part of your environment.

A scope is relative to a variable. (i.e. the variables scope). It is
essentially the set of program locations in which that variable is in the
environment.

A closure is just an environment plus a lambda. So that when the lambda
executes it still has access to the environment in which it was created (aka
all that environments variables are still in scope). You can use closures to
essentially extend the scope of variables so you can access them later.

A continuation is a little trickier. Basically a continuation is more about
control flow than visibility. A continuation is what happens after a lambda
returns. In most languages continuations are implictly managed by the program
stack (and the return keyword). So you don't even think its anything special.
But in scheme there is special support to help reify the continuation concept
and make it available to the programmer.

I hope I didn't make things any more confusing.

~~~
lukesandberg
With concepts like these it can sometimes be difficult to form an appropriate
mental model of how the machine is actually working (aka the implementations
of the algorithm).

So if you were to implement a scheme interpreter heres how i would represent
these things.

scope: map from symbols to objects.

environment: linked list of scopes, where each scope is linked to its parent
scope.

(so to look up a variable value you just walk up the scope chain looking for
where the symbol is defined).

closure: pair of environment and lambda. where the environment is the one in
which the lambda was defined.

(so to execute a closure you just link the lambda scope to the given
environment and then run the lambda)

continuation: just a closure. continuations would most likely be implemented
by rewriting the code after the method call as a lambda and passing the
closure as the continuation.

if you really want to see how the bits fit together you can read this blog
series: <http://michaux.ca/index#Scheme%20from%20Scratch> and check out the
corresponding github implementations:

<https://github.com/petermichaux/bootstrap-scheme>

<https://github.com/lukesandberg/bootstrap-scheme> (shameless plug for my
implementation)

------
dkersten
As I understand these terms:

A _scope_ is the duration (in code, not time) during which an identifier
(name) is bound to a value (thus becoming a variable). When a variable is said
to "go out of scope", what is meant is that the execution leaves the scope in
which the name is bound, rendering it invalid (which is why, eg, in C++
automatic (local/stack) variables get destructed when execution leaves their
scope - it is invalid and can no longer be accessed.

C++:

    
    
        { // In C++ we can create arbitrary "scopes"
            int a = 5; // Bind the name 'a' to some variable
            ...
        } // 'a' is not accessible after here, because the scope is terminated by the }
    

Clojure:

    
    
        (let [a 10] ; Bind the identifier 'a' to the value '10'
            ; 'a' can be accessed here
            ...) ; This ')' closes the scope, so 'a' is no longer accessible
    

An _environment_ is a special kind of scope that includes functions,
variables, classes etc. In some languages this distinction is more important
than others (ie, languages with first class functions, normal function-level
scopes may contain function definition, whereas languages like C++ do not
allow this). I think generally an environment can be thought of as a table of
functions and values (usually named, eg, think of shell environment variables)
which can be accessed in the current execution context (what is currently
being executed). A language may define an environment to have different
things, such as I/O functions, state etc, or a language may not have a notion
of environment outside of a global collection of names/identifiers bound to
something.

A _closure_ is a function (anonymous or named) which "closes over" (captures)
the variables in the environment or scope in which it is defined, essentially
capturing those variables and/or values. The distinction between variable and
value is important here. Eg, Python captures the _variable_ , so if the
variable is assigned a different value between when the closure captures it
and when the closure is evaluated (called as a function), the closure will see
the new value. If it were instead to capture the _value_ , then the changes
will not be visible. Java, for example, only allows final (constant) variables
to be used in locally defined classes - Java captures the _variable_ but
enforces _value_ capture semantics by forcing the variables to be constant.

A _continuation_ is a representation of the programs execution. You could
think of a continuation as a jmp_buf used with C's longjmp and setjmp
functions. The _current continuation_ is a representation of the next point of
execution.

For example:

    
    
        function foo (a, continuation){
            // do something with a
            // call continuation
            continuation();
        }
        ...
        1: call_with_current_continuation(foo, 10); // call/cc function foo
        1:
    

Line 1 calls the function foo, passing the _current continuation_ as the last
argument. foo calls the continuation at the end, which essentially returns
program execution to the continuation, which is line 2. Used in this way, a
continuation is the same as a return statement or function. Of course, you can
use continuations to jump anywhere, not just the caller. For example, you can
use continuations to implement coroutines or exception handling.

