Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lexical scope vs. dynamic scope

25 views
Skip to first unread message

J. Winter

unread,
Feb 24, 2009, 3:35:18 PM2/24/09
to
Is there anything really important to loose if you use only lexical
scope such as in scheme. (I've been learning CL again after twenty years.)

-- jw

J. Winter

unread,
Feb 24, 2009, 3:39:20 PM2/24/09
to
J. Winter kirjoitti:

> Is there anything really important to loose if you use only lexical
> scope such as in scheme. (I've been learning CL again after twenty years.)
>
> -- jw

Sorry, my fingers works faster than my brain. (loose shoude be lose).

-jw

Kenneth Tilton

unread,
Feb 24, 2009, 4:11:39 PM2/24/09
to
J. Winter wrote:
> J. Winter kirjoitti:
>> Is there anything really important to loose if you use only lexical
>> scope such as in scheme. (I've been learning CL again after twenty
>> years.)
>

Hang on. I knew Scheme gave CL the idea for lexical scope, but... they
yanked dynamic /completely/ at the same time? Puzzled...

kt

Kaz Kylheku

unread,
Feb 24, 2009, 4:12:53 PM2/24/09
to
On 2009-02-24, J. Winter <jwi@dlc_NO_SPAM_.fi.invalid> wrote:
> Is there anything really important to loose if you use only lexical
> scope such as in scheme.

There is something important lost if the programming language only supports
lexical scope.

You don't lose anything by only using lexical scope, if lexical scope solves
your problem, and lends an adequate expressiveness to your solution.

Dynamic scope gives us an alternate way to invisibly pass an indefinite number
of parameters to a function, through any number of intermediate callers which
are not aware of this. That's a kind of transparency that is not available in
lexical scope, which provides a different mode of transparency.

For instance, *standard-output* is a dynamic variable in Lisp, which allows us
to pass a different standard output stream to all output functions, even
without the cooperation of intermediate functions.

Example: capture output as a string.

(defun leaf ()
(format t "hello, world"))

(defun intermediate ()
(leaf))

(with-output-to-string (*standard-output*)
(intermediate))

-> "hello, world"

This is impossible with lexical scope, whose purpose it is to rule out this
kind of interaction.

Note how cooperation is not required from INTERMEDIATE or LEAF; they don't
have any parameters for specifying the output stream, and the FORMAT
call specifies the stream as T, which tells it to use *STANDARD-OUTPUT*.

*STANDARD-OUTPUT* is redefined as a string stream, but only within the dynamic
scope of the WITH-OUTPUT-TO-STRING form. Once that form terminates, the
redefinition lapses to whatever it was in the surrounding scope.

It may look like an assignment to a global variable, but it's actually quite
different, due to the discipline of automatic saving and restoring. Also, in
implementations that support multiple threads, each thread has its own dynamic
scope.

J. Winter

unread,
Feb 24, 2009, 4:20:34 PM2/24/09
to
Kaz Kylheku kirjoitti:

Thank you, I got the idea.

-- jw

Kaz Kylheku

unread,
Feb 24, 2009, 4:24:44 PM2/24/09
to

They were brilliant fools searching for the holy grail of scope, falling into
the trap of dualistic thinking: a scope is either good or bad, and we must only
support the best one.

Also I recall reading that for a time there were some Lisps that had both
scope, but in an ill-defined way: dynamic for interpreted code, but lexical for
compiled. Making everything one scope could be a possible knee-jerk reaction to
such a state of affairs: i.e. two incompatible things don't get along, so throw
out one of them.

You know, it occurs to me that ``transparency'' is a loaded word sometimes used
in discussing scopes. Lexical scope is ``referentially transparent''. But
dynamic scope lets us create interaction between distant functions without the
involvement of intermediate layers, so it is also transparent.

Transparency isn't absolute, because if everything is transparent, you see
nothing. Transparency is always defined with respect to some objects that are
intended to be seen, embedded in some medium which is to be unseen. Those
objects always block transparency.

Next time someone spouts nonsense about transparency, I will be sure to open up
this little can of whoop-ass.

Pascal Costanza

unread,
Feb 24, 2009, 4:25:03 PM2/24/09
to

No, there are exactly two special variables in R5RS, current-input-port
and current-output-port - but no way to define your own special variables.

Well, there is dynamic-wind...


Pascal

--
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/

Pascal Costanza

unread,
Feb 24, 2009, 4:26:47 PM2/24/09
to
J. Winter wrote:
> Is there anything really important to loose if you use only lexical
> scope such as in scheme. (I've been learning CL again after twenty years.)

To a certain extent, you can simulate dynamic scoping with lexical
scoping (but not really).

It seems to me that Scheme didn't include dynamic scoping because it's
hard to get the interaction with first-class continuations right. R5RS
introduced dynamic-wind, which is apparently considered a solution.

Kenneth Tilton

unread,
Feb 24, 2009, 4:45:42 PM2/24/09
to
Kaz Kylheku wrote:
> On 2009-02-24, Kenneth Tilton <kent...@gmail.com> wrote:
>> J. Winter wrote:
>>> J. Winter kirjoitti:
>>>> Is there anything really important to loose if you use only lexical
>>>> scope such as in scheme. (I've been learning CL again after twenty
>>>> years.)
>> Hang on. I knew Scheme gave CL the idea for lexical scope, but... they
>> yanked dynamic /completely/ at the same time? Puzzled...
>
> They were brilliant fools searching for the holy grail of scope, falling into
> the trap of dualistic thinking: a scope is either good or bad, and we must only
> support the best one.

Oh, my. Global variables at least? So we can do the save-set-restore
tango*?

I feel a Law coming on.

kt

* Or is that the foxtrot?

Thomas F. Burdick

unread,
Feb 24, 2009, 5:25:31 PM2/24/09
to
On 24 fév, 22:45, Kenneth Tilton <kentil...@gmail.com> wrote:
> Kaz Kylheku wrote:
> > On 2009-02-24, Kenneth Tilton <kentil...@gmail.com> wrote:
> >> Hang on. I knew Scheme gave CL the idea for lexical scope, but... they
> >> yanked dynamic /completely/ at the same time? Puzzled...
>
> > They were brilliant fools searching for the holy grail of scope, falling into
> > the trap of dualistic thinking: a scope is either good or bad, and we must only
> > support the best one.
>
> Oh, my. Global variables at least? So we can do the save-set-restore
> tango*?
>
> I feel a Law coming on.

They have a nice, well thought out system of lexical variables. What
does a global lexical mean, anyhow? So you sort of have globals, but
they can be limited to the world you're in. Think of an infinite set
of lexical bindings, with a global environment always one level up,
unless someone makes one yet one level higher. It seems to be a win in
terms of having several sets of unrelated code coexist in the same
image.

But dynamic variables? They just left them out. But kind of like how
you can just type "(defmacro ..." in a non-toy scheme, in practice you
can just type "(fluid-let ((..." in a serious implementation.

> * Or is that the foxtrot?

They both involve dancing with a partner. I think this is more of a
one-man jig.

Thomas F. Burdick

unread,
Feb 24, 2009, 5:27:14 PM2/24/09
to
On 24 fév, 22:25, Pascal Costanza <p...@p-cos.net> wrote:
> Kenneth Tilton wrote:
> > J. Winter wrote:
> >> J. Winter kirjoitti:
> >>> Is there anything really important to loose if you use only lexical
> >>> scope such as in scheme. (I've been learning CL again after twenty
> >>> years.)
>
> > Hang on. I knew Scheme gave CL the idea for lexical scope, but... they
> > yanked dynamic /completely/ at the same time? Puzzled...
>
> No, there are exactly two special variables in R5RS, current-input-port
> and current-output-port - but no way to define your own special variables.
>
> Well, there is dynamic-wind...

Last I looked those were both functions to get the current (input|
output) port. And you bind it with call-with-... silliness. Those
aren't special variables, they're ugly hacks around the lack thereof.

Thomas F. Burdick

unread,
Feb 24, 2009, 5:30:22 PM2/24/09
to
On 24 fév, 22:26, Pascal Costanza <p...@p-cos.net> wrote:
> J. Winter wrote:
> > Is there anything really important to loose if you use only lexical
> > scope such as in scheme. (I've been learning CL again after twenty years.)
>
> To a certain extent, you can simulate dynamic scoping with lexical
> scoping (but not really).
>
> It seems to me that Scheme didn't include dynamic scoping because it's
> hard to get the interaction with first-class continuations right. R5RS
> introduced dynamic-wind, which is apparently considered a solution.

Except it's not hard. Much like how continuations are easy to model if
you just decide that your VM's semantics are that of having CPS-
transformed your code, dynamic scope is easy in a scheme if you pass
current-dynamic-environment around the same way you do current-
continuation.

Pascal Costanza

unread,
Feb 24, 2009, 6:21:58 PM2/24/09
to

It's a bit more complicated when you want to combine this with
continuations, and also want to capture "behavior."

Consider:

(with-open-file (*standard-input* some-file)
...)

If you capture the current continuation somewhere in the dynamic extent
of this with-open-file, and later invoke that continuation somewhere
outside of that dynamic extent, you probably want to reopen that file at
the correct position, or so.

OK, admittedly a weird example, but dynamic-wind allows you to express
capturing such behavioral aspects of the dynamic environment. Just
capturing the "static" dynamic environment is often not enough.

In Common Lisp, we can normally safely ignore such problems, because we
don't have call/cc.

Thomas Munro

unread,
Feb 24, 2009, 6:39:46 PM2/24/09
to
On Feb 24, 10:25 pm, "Thomas F. Burdick" <tburd...@gmail.com> wrote:
> But dynamic variables? They just left them out. But kind of like how
> you can just type "(defmacro ..." in a non-toy scheme, in practice you
> can just type "(fluid-let ((..." in a serious implementation.

Nitpicking, but I think most serious Schemes now provide dynamic scope
binding via SRFI-39 parameters which generalise the idea from
"(current-input-port)" and "(current-output-port)", and therefore use
"(parameterize ((..." rather than "(fluid-let ((..." from SRFI-15
which was withdrawn. Also I think "(define-macro ..." is more common
that "(defmacro ..." since schemers don't like to mince their words.

Barry Margolin

unread,
Feb 24, 2009, 8:06:48 PM2/24/09
to
In article <200903031...@gmail.com>,
Kaz Kylheku <kkyl...@gmail.com> wrote:

> They were brilliant fools searching for the holy grail of scope, falling into
> the trap of dualistic thinking: a scope is either good or bad, and we must
> only
> support the best one.

Scheme was designed for pedagogical purposes, and one of the goals was
to allow for detailed analysis of program behavior. Dynamic scope is
like GOTO, in that the effects are non-local, making such analysis
extremely difficult.

Of course, the same can be said about global variables in general, but
they didn't throw that baby out with the bathwater.

>
> Also I recall reading that for a time there were some Lisps that had both
> scope, but in an ill-defined way: dynamic for interpreted code, but lexical
> for
> compiled. Making everything one scope could be a possible knee-jerk reaction
> to
> such a state of affairs: i.e. two incompatible things don't get along, so
> throw
> out one of them.

Maclisp was like this. This was where the SPECIAL declaration came
from. The idea was that for "ordinary" variables, it didn't really
matter what kind of binding was used; yes, problems with dynamic
variable shadowing could occur, but they were extremely unlikely if you
used good variable names, and in practice it wasn't a problem. But
there were some variables that you needed to ensure had dynamic scope,
and that's what made them "special". Since Maclisp didn't have
closures, it was never the case that you needed to force lexical scoping.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

Kaz Kylheku

unread,
Feb 24, 2009, 8:25:59 PM2/24/09
to
On 2009-02-25, Barry Margolin <bar...@alum.mit.edu> wrote:
> In article <200903031...@gmail.com>,
> Kaz Kylheku <kkyl...@gmail.com> wrote:
>
>> They were brilliant fools searching for the holy grail of scope, falling into
>> the trap of dualistic thinking: a scope is either good or bad, and we must
>> only
>> support the best one.
>
> Scheme was designed for pedagogical purposes, and one of the goals was
> to allow for detailed analysis of program behavior. Dynamic scope is
> like GOTO, in that the effects are non-local, making such analysis
> extremely difficult.
>
> Of course, the same can be said about global variables in general, but
> they didn't throw that baby out with the bathwater.

So they threw out the baby and retained the bathwater. :)

Kenneth Tilton

unread,
Feb 24, 2009, 10:59:15 PM2/24/09
to

Well I have come up with the law and I am pretty excited about it:

The proof is in the pudding.

ta-dummmmm

kt

Kaz Kylheku

unread,
Feb 25, 2009, 12:02:31 AM2/25/09
to
On 2009-02-25, Kenneth Tilton <kent...@gmail.com> wrote:
> Well I have come up with the law and I am pretty excited about it:
>
> The proof is in the pudding.

Yobbo, you mean, ``The proof of the pudding is in the eating''.

Kenneth Tilton

unread,
Feb 25, 2009, 2:14:55 AM2/25/09
to

No, I mean there is no hope for you:

http://ask.yahoo.com/20020903.html

Your apology here: _______________________________________

kt

Majorinc Kazimir

unread,
Feb 25, 2009, 5:01:07 AM2/25/09
to

Oh yes. Dynamic scope is important for processing FORMULAS, or more
generally any kind of data that has syntax and semantics. Take a look on
this function call:

(INTEGRATE '(+ (sin (* t x) ... ) 'x 0 1)

Very natural, isn't it? But, in the statically scoped language, formula
'(+ (sin ... )) that arrived to INTEGRATE is stripped of its semantics
and INTEGRATE is unable to determine what is the value of the t. There
are ways around it, of course - but neither one is really good. Scheme
and Common Lisp lost a lot of expressive power of original Lisp by
introduction of lexical scope.

Marco Antoniotti

unread,
Feb 25, 2009, 10:02:02 AM2/25/09
to

What's so SPECIAL about dynamic (or lexical) scope?

Cheers
--
Marco

Raffael Cavallaro

unread,
Feb 25, 2009, 10:57:12 AM2/25/09
to
On Feb 25, 2:14 am, Kenneth Tilton <kentil...@gmail.com> wrote:
> Kaz Kylheku wrote:
> > On 2009-02-25, Kenneth Tilton <kentil...@gmail.com> wrote:
> >> Well I have come up with the law and I am pretty excited about it:
>
> >>      The proof is in the pudding.
>
> > Yobbo, you mean, ``The proof of the pudding is in the eating''.
>
> No, I mean there is no hope for you:
>
>    http://ask.yahoo.com/20020903.html
>
> Your apology here: _______________________________________
>
> kt

"These days, some people shorten the phrase to simply "proof of the
pudding." Even the American Heritage Dictionary of the English
Language trims it down. Occasionally, it is even further abbreviated
to "proof in pudding," irritating purists who argue that the shortened
versions don't mean anything on their own."

Which would make Kaz a purist, and you someone who repeats a
bastardization that has no meaning on its own.

Kaz Kylheku

unread,
Feb 25, 2009, 11:42:35 AM2/25/09
to

The wording looks adequate. Can I use some of that space to add a signature, or
does it go below?

Kaz Kylheku

unread,
Feb 25, 2009, 11:59:19 AM2/25/09
to
On 2009-02-25, Majorinc Kazimir <fa...@email.address> wrote:
> J. Winter wrote:
>> Is there anything really important to loose if you use only lexical
>> scope such as in scheme. (I've been learning CL again after twenty years.)
>>
>> -- jw
>
> Oh yes. Dynamic scope is important for processing FORMULAS, or more
> generally any kind of data that has syntax and semantics.
> Take a look on this function call:
>
> (INTEGRATE '(+ (sin (* t x) ... ) 'x 0 1)
>
> Very natural, isn't it? But, in the statically scoped language, formula
> '(+ (sin ... )) that arrived to INTEGRATE is stripped of its semantics
> and INTEGRATE is unable to determine what is the value of the t.

This problem doesn't require dynamic scope, because INTEGRATE can take
an additional environment parameter, through which it can resolve
the symbol T. The environment could be lexical or dynamic.

There is no reason why the environment that integrate uses to
determine T must be /implicitly/ inherited from the caller.

INTEGRATE could could receive the lexical environment implicitly too,
by being a special operator.

What makes dynamic scope useful is situations where you do want the implicit
environment passing, because it's not practical to add environment-passing
parameters to third party functions that sit between two pieces of code.

> There
> are ways around it, of course - but neither one is really good.

But, as someone who evangelizes NewLisp, your idea of what is ``good'' is a
little bit out of whack with reality.

> Scheme and Common Lisp lost a lot of expressive power of original Lisp by
> introduction of lexical scope.

Common Lisp didn't lose anything, since it has retained dynamic scope.

If you prefer dynamic scope, you can exclusively use it in your Common Lisp
programs. You can even design your programs in such a way that the choice is
forced onto others who want to integrate with them.

Pillsy

unread,
Feb 25, 2009, 10:39:47 PM2/25/09
to
On Feb 25, 5:01 am, Majorinc Kazimir <fa...@email.address> wrote:
[...]

> Take a look on this function call:

> (INTEGRATE '(+ (sin (* t x) ... ) 'x 0 1)

> Very natural, isn't it? But, in the statically scoped language, formula
> '(+ (sin ... )) that arrived to INTEGRATE is stripped of its semantics
> and INTEGRATE is unable to determine what is the value of the t. There
> are ways around it, of course - but neither one is really good.

Is this supposed to be a symbolic routine? If so, you're probably
going to
want to explicitly pass, manage and inspect the environment that
you're
trying to simplify the integration in. At the very least, you're going
to
have to be checking to see whether symbols are BOUNDP or FBOUNDP
while
walking the expression you're trying to integrate; once you're doing
that,
why limit yourself to the basics provided by dynamic scoping?

If, on the other hand, it's a numeric routine, lexical scoping is
perfectly
adequate because you can always pass in a closure. Which is especially
nice
because then you can actually get efficient compilation, which is
always
nice when you need to stick something inside an inner loop.

Cheers,
Pillsy

Xah Lee

unread,
Feb 26, 2009, 5:08:21 AM2/26/09
to
On Feb 24, 12:35 pm, "J. Winter" <jwi@dlc_NO_SPAM_.fi.invalid> wrote:
> Is there anything really important to loose if you use only lexical
> scope such as in scheme. (I've been learning CL again after twenty years.)

the short answer is, no.

tech geekers make a lot fuzz about scope. In general, the more
smattering knowledge they have about compilers, the more stupid their
opinion becomes about languages.

For a explication of scope monster, see the section:
The Rise of “Access Specifiers” (or, the Scoping Complexity of OOP)

in

• What are OOP's Jargons and Complexities
http://xahlee.org/Periodic_dosage_dir/t2/oop.html

Here's a plain text excerpt:

---------------------------------------------

The Rise of “Access Specifiers” (or, the Scoping Complexity of OOP)

In programing, a variable has a scope — meaning where the variable can
be seen. Normally, there are two basic models: dynamically scoped and
lexically scoped. Dynamic scoping is basically a time based system,
while lexical scoping is text based (like “what you see is what you
get”). For example, consider the following code:

subroutine f() {return y}
{y=3; print f();}

In dynamic scoping, the printed result is 3, because during evaluation
of the block all values of y is set to 3. In lexical scoping, a
undefined “y” is printed because the two “y” in the code are
considered different because they are in separate blocks of curly
brackets. With regards to language implementation, Dynamic Scoping is
the no-brainer of the two, and is the model used in earlier languages.
Most of the time, lexical scoping is more natural and desired because
it corresponds to the code as it appears.

Scoping is also applicable to subroutines. That is to say, where
subroutines can be seen. A subroutine's scope is usually at the level
of source file (or a concept of a module/package/library), because
subroutines are often used in the top level of a source file, as
opposed to inside a code block like variables.

In general, the complexity of scoping is really just how deeply nested
a name appears. For example see in the following code:

name1; // top level names. Usually subroutines, or global
variables.
{
name2 // second level names. Usually variables inside
subroutines.
{
name3 // deeper level names. Less often used in structured
programing.
// sometimes used in nested loops
}
}

If a programing language uses only one single file of commands in
sequence as in the early languages such as BASIC, there would be no
scoping concept. The whole program is of one single scope.

OOP has created a immense scoping complexity because its mode of
computing is calling nested subroutines (methods) inside subroutines
(classes). We detail some aspects in the following.

In OOP, variables inside subroutines (class variables) can also be
accessed thru a reference the subroutine is assigned to (that is, a
object). In OOP parlance: a variable in a class has a scope, while the
same variable when the class is instantiated (a objet) is a different
scoping issue. In other words, OOP created a new entity “variable thru
reference” that comes with its own scoping issue. For example:

class a_surface() {
coordinates={...}; // a variable
...
}

class main {
mySurface = new a_surface();
mySurface.coordinates = {...}; // accessing the “same” variable
}

In the above code, the variable “coordinates” appears in two places.
Once as defined inside a_surface, and once as a instantiated version
of a_surface (a object). The variable as thru the object reference
apparently has a entirely different scoping issue than the same
variable inside the subroutine (class) definition. The question for
OOP language designers is: what should the scope be for variables
referred thru objects? Lexically within the class the object is
created? Lexically within the class the variable is defined??
globally? (and what about inherited classes? (we will cover OOP
inheritance later))

As we've seen, methods are just inner-subroutines, and creating
objects to call methods is OOP's paradigm. In this way, names at the
second-level programing structure often associated with variables (and
inner-subroutines), is now brought to the forefront. This is to say,
the scoping of subroutines are raised to a level of complexity as the
scoping of variables. (they are now both in the 2nd level of names (or
deeper).)

Further: In a class definition, variables are lexically scoped. But
the ability for a object to refer/change a class variable is
essentially a model of dynamic scope. Thus, OOP created a complexity
of mixing these 2 scoping models.

All in all, the scoping complexities of OOP as applied to different
OOP entities (classes, class variables, class's methods, object
variables and methods) is manifested as access specifiers in Java. In
Java, access specifiers are keywords “private”, “protected”, “public”,
used to declare the scope of a entity. Together with a default scope
of no-declaration, they create 4 types of scope, and each of these
keywords has entirely different effects depending whether they are
used on a variable, a method, a constructor, or a class.

See this tutorial of Java's access specifiers for detail: Java's
Access Specifiers.


Xah
http://xahlee.org/


Majorinc Kazimir

unread,
Feb 26, 2009, 9:02:23 AM2/26/09
to
Pillsy wrote:

>
> Is this supposed to be a symbolic routine?

It is not supposed that it is either symbolic or numeric. In general
case it is both. That is one of the reasons I picked that example.

> If so, you're probably

> going to want to explicitly pass, manage and inspect the environment you're


> trying to simplify the integration in.

Don't hurry. You need something stronger than "probably."

Vend

unread,
Feb 26, 2009, 11:18:57 AM2/26/09
to
On 24 Feb, 22:26, Pascal Costanza <p...@p-cos.net> wrote:
> J. Winter wrote:
> > Is there anything really important to loose if you use only lexical
> > scope such as in scheme. (I've been learning CL again after twenty years.)
>
> To a certain extent, you can simulate dynamic scoping with lexical
> scoping (but not really).
>
> It seems to me that Scheme didn't include dynamic scoping because it's
> hard to get the interaction with first-class continuations right. R5RS
> introduced dynamic-wind, which is apparently considered a solution.

Would that work?

(define-syntax let-dynamic
(syntax-rules ()
((let-dynamic ((var bind) ...) expr ...)
(let ((val bind) ...)
(let ((prev-val var) ...)
(dynamic-wind
(lambda ()
(set! prev-val var) ...
(set! var val) ...)
(lambda ()
expr ...)
(lambda ()
(set! val var) ...
(set! var prev-val) ...)))))))

assuming that the variables are already defined.

Pillsy

unread,
Feb 26, 2009, 12:58:12 PM2/26/09
to
On Feb 26, 9:02 am, Majorinc Kazimir <fa...@email.address> wrote:

> Pillsy wrote:

> > Is this supposed to be a symbolic routine?

> It is not supposed that it is either symbolic or numeric. In general
> case it is both.

No, it isn't.

If I pass an expression to a numeric routine, I'll be happy to get
back an approximate answer found via Gaussian quadrature or whatever.
If I pass an expression to a symbolic routine and I get that kind of
answer back, I'll be filing a really snarky bug report.

> > If so, you're probably going to want to explicitly pass, manage and
> > inspect the environment you're trying to simplify the integration in.

> Don't hurry. You need something stronger than "probably."

If you'd read the rest of the paragraph, you'd have noticed that I
said you already need to explicitly *inspect* the dynamic environment
(what do you think BOUNDP and FBOUNDP do, anyway?) At that point, why
deny yourself the additional functionality you'd be able to get by
explicitly handling the environment?

Cheers,
Pillsy

Majorinc Kazimir

unread,
Feb 26, 2009, 2:58:18 PM2/26/09
to

> If you'd read the rest of the paragraph,

I've read whole post.
We just didn't agreed, Pillsy.

Thomas F. Burdick

unread,
Feb 26, 2009, 4:28:22 PM2/26/09
to

Sure, but that example doesn't actually have anything to do with
dynamic-scope variables; it's completely about exposing continuations.
If the example were with a lexial variable whose value got passed
around, your point would stand unchanged. Dynamic and lexical lookup
are all about associating variables with values; what those values
mean in the case of reentrant continuations is a problem no matter
what the lookup regime.

Actually, I think there is an interesting question that continuations
pose with regards to dynamic variables: should the continuation
function (assuming no multiple values) take one argument or two? That
is, should it close over the dynamic environment it was created in, or
should that be an argument.

> In Common Lisp, we can normally safely ignore such problems, because we
> don't have call/cc.

That's not the least of it; what do you do when, mid-initialize-
instance method you reinvoke the macro-expansion function's
continuation that created the call to make-instance ... only this time
returning nil? It's really not hard to come up with situations where
continuations just make for insane semantic questions (although I seem
to be especially qualified in imagining these situations :-)

Xah Lee

unread,
Feb 26, 2009, 6:40:53 PM2/26/09
to
On Feb 24, 1:12 pm, Kaz Kylheku <kkylh...@gmail.com> wrote:

> On 2009-02-24, J. Winter <jwi@dlc_NO_SPAM_.fi.invalid> wrote:
>
> > Is there anything really important to loose if you use only lexical
> > scope such as in scheme.
>
> There is something important lost if the programming language only supports
> lexical scope.
>
> You don't lose anything by only using lexical scope, if lexical scope solves
> your problem, and lends an adequate expressiveness to your solution.
>
> Dynamic scope gives us an alternate way to invisibly pass an indefinite number
> of parameters to a function

what a idiocracy.

i do wonder, if any reputable computer scientist would blub out such
idiotic things as this thread's lispers have been.

Let me give a lucid account on the gist of dynamic scope and lexical
scope.

Dynamic scope, is when computers are still slow (1960s, 1970s),
there's no such thing as so-called “computer science” yet, and
mathematicians at the time have little idea what they are doing on the
computers.

When after a few decades, mathematicians got some whiff of the math of
computer languages, lexical was born. But by this time, mathematicians
have gone. What's left are so called computer scientist, typically
morons.

From a mathematical and practical perspective, everything about
dynamic scope is just global vars. Like closure, there's nothing
useful these things add from practical software developement
perspective.

Xah
http://xahlee.org/

TomSW

unread,
Feb 26, 2009, 7:18:46 PM2/26/09
to
On Feb 27, 12:40 am, Xah Lee <xah...@gmail.com> wrote:
> > Dynamic scope gives us an alternate way to invisibly pass an indefinite number
> > of parameters to a function
>
> what a idiocracy.

aka "Confederacy of Dunces"

Javier

unread,
Feb 26, 2009, 7:21:16 PM2/26/09
to
Kaz Kylheku escribió:

> They were brilliant fools searching for the holy grail of scope, falling into

> the trap of dualistic thinking: _SOMETHING_ is either good or bad, and we must only
> support the best one.

Ummmmm, this sounds familiar....

Pascal Costanza

unread,
Feb 27, 2009, 10:01:01 AM2/27/09
to

Not quite: With lexical scope, you get indefinite extent, while with
dynamic scope you get dynamic extent. Indefinite extent and first-class
continuations seem to match better than dynamic extent and first-class
continuations. (First-class continuations, at least how they are modeled
in Scheme, assume that the underlying program is transformed to CPS, and
CPS and dynamic extent are at odds with each other.)

Maybe the example is not the best one to illustrate this, though.

> Actually, I think there is an interesting question that continuations
> pose with regards to dynamic variables: should the continuation
> function (assuming no multiple values) take one argument or two? That
> is, should it close over the dynamic environment it was created in, or
> should that be an argument.

In RnRS, with n>=5, the idea is that call/cc captures the dynamic
environment (the dynamic-wind thunks); with n<5 there is no
dynamic-wind, so the dynamic environment is not captured. (In R1RS or
R2RS, there was a captured dynamic environment, but that somehow got
scrapped in R3RS.)

Dynamic-wind is apparently a controversial feature in Scheme, some
Scheme implementations offer a lower level call/cc where dynamic-wind
thunks are not captured.

I would agree with the latter, I think dynamic environment and
continuations should be kept separate.

Shameless plug: The current repository for ContextL actually contains an
extension to support first-class dynamic environments that capture both
dynamic variables and a lower level dynamic-wind construct. However,
this is not combined with any form of call/cc, instead the idea is that
ContextL's dynamic environments can be combined with any of the existing
continuation frameworks that exist for Common Lisp, if one feels so
inclined.

Furthermore, ContextL's dynamic-wind is defined in such a way that it
better meshes with the existing dynamic-extent constructs that already
exist in Common Lisp. Here is one cool example of what you can express:

(defun foo () (capture-dynamic-environment))

(setq *env* (dynamic-wind
(handler-case (proceed (foo))
(error () (format t "I caught an error.")))))

(with-dynamic-environment (*env*)
(error "boo!"))

This will catch the error "boo!" with the exception handler that prints
"I caught an error.", because the with-dynamic-environment form
reestablished the exception handler from the previous form. (The proceed
macro delimits the parts of the dynamic-wind macro that should and
shouldn't be captured, respectively.)

>> In Common Lisp, we can normally safely ignore such problems, because we
>> don't have call/cc.
>
> That's not the least of it; what do you do when, mid-initialize-
> instance method you reinvoke the macro-expansion function's
> continuation that created the call to make-instance ... only this time
> returning nil? It's really not hard to come up with situations where
> continuations just make for insane semantic questions (although I seem
> to be especially qualified in imagining these situations :-)

Indeed, call/cc is a wild beast. ;)

Pascal Costanza

unread,
Feb 27, 2009, 10:38:32 AM2/27/09
to

Not quite, because your let-dynamic doesn't create a new binding, but
"just" assigns to the same binding of the given variable. This may not
work that well in multi-threaded implementations of Scheme.

Pillsy

unread,
Feb 27, 2009, 11:40:31 AM2/27/09
to
On Feb 26, 6:40 pm, Xah Lee <xah...@gmail.com> wrote:
[...]

> Like closure, there's nothing useful these things add from
> practical software developement perspective.

I must have been hallucinating all those times I thought I typed
things like,

Map[something[#, bar]&, {a, b, c, ...}]

while doing practical software development. Maybe I got ergotism from
the dodgy cafeteria pizza.

Cheers,
Pillsy

Vend

unread,
Feb 27, 2009, 2:27:04 PM2/27/09
to

That would require a per-thread variable.

Vend

unread,
Feb 27, 2009, 2:33:19 PM2/27/09
to

How does dynamic-wind interact with CPS transformation?
Without dnamic-wind, CPS continuation objects can be just ordinary
closures that get tail-called. I suppose that with dynamic-wind you
need to pass another object or use a stack.

<snip>

Pascal Costanza

unread,
Feb 27, 2009, 5:12:33 PM2/27/09
to
Vend wrote:
> How does dynamic-wind interact with CPS transformation?
> Without dnamic-wind, CPS continuation objects can be just ordinary
> closures that get tail-called. I suppose that with dynamic-wind you
> need to pass another object or use a stack.

I don't know. It's maybe better to ask this in comp.lang.scheme.

Pascal Costanza

unread,
Feb 27, 2009, 5:12:57 PM2/27/09
to


Indeed.

Pascal Costanza

unread,
Feb 27, 2009, 5:13:40 PM2/27/09
to

...but what if you pass the continuation to a different thread and
invoke it there?

William James

unread,
Feb 28, 2009, 1:56:22 AM2/28/09
to
TomSW wrote:

> On Feb 27, 12:40=A0am, Xah Lee <xah...@gmail.com> wrote:
> > > Dynamic scope gives us an alternate way to invisibly pass an indefinite=


> number
> > > of parameters to a function
> >
> > what a idiocracy.
>
> aka "Confederacy of Dunces"

The novel with that title is pretty good.

Vend

unread,
Feb 28, 2009, 6:10:34 AM2/28/09
to

You put a continuation barrier between threads. :D

Pascal Costanza

unread,
Feb 28, 2009, 6:34:20 AM2/28/09
to

Oh my god, they can't be serious... ;)

Raffael Cavallaro

unread,
Feb 28, 2009, 1:05:47 PM2/28/09
to

Funny you should mention novels; I generally prefer your brother
Henry's novels to your writing here :)

0 new messages