From: Dave Roberts
Subject: State machine representation
Date: 
Message-ID: <Sn1Tb.154045$5V2.806622@attbi_s53>
So I'm learning CL and trying to write various programs. One thing that I'm
interested in is communications protocols, so I figured that I'd try some
practice projects in that area. Being that I have a hardware engineering
background and protocols are often designed in terms of state machines, I
tend to write reactive, event-driven state machine systems frequently.

So, in the course of my practice, a natural question came up: What's the
"best" way to represent a state machine in CL, and why? Obviously, the
question is loaded and there is no right answer. I'm looking for
experienced opinions here. The various possible solutions I have toyed with
include:

1. Just represent state machines simply with an integer or symbol state
variable and a case or cond form which switches on the current state. The
forms associated with any case/cond clause then determine the next state.

2. Represent each state with a different function, bound at top-level. The
state machine can then be represented as a list or structure, with those
functions operating on it.

3. Represent the state machine with a closure. Basically:
(defun make-state-machine ....
  (let ((statevar1)
        (statevar2)
        (current-state))
    (flet ((state1 (input) ...)
           (state2 (input) ...))
      (setq current-state state1)
      (lambda (input) (funcall current-state input)))))

This is sort of "object-oriented" in the sense that the enclosure
encapsulates the total state and outsiders can't get into it without the
state machine itself exposing the state.

4. Finally, you could obviously do this with full CLOS objects, with the
machine being an object and states being represented by either additiona
CLOS objects or by a combination of variables and functions.

So, a question for all the Lisp Wizards: What is your favorite technique for
state machines.

Thanks,

-- Dave

From: Kenny Tilton
Subject: Re: State machine representation
Date: 
Message-ID: <Vk3Tb.169001$4F2.20113811@twister.nyc.rr.com>
Dave Roberts wrote:

> So I'm learning CL and trying to write various programs. One thing that I'm
> interested in is communications protocols, so I figured that I'd try some
> practice projects in that area. Being that I have a hardware engineering
> background and protocols are often designed in terms of state machines, I
> tend to write reactive, event-driven state machine systems frequently.
> 
> So, in the course of my practice, a natural question came up: What's the
> "best" way to represent a state machine in CL, and why? Obviously, the
> question is loaded and there is no right answer. I'm looking for
> experienced opinions here. The various possible solutions I have toyed with
> include:
> 
> 1. Just represent state machines simply with an integer or symbol state
> variable and a case or cond form which switches on the current state. The
> forms associated with any case/cond clause then determine the next state.

That's what I have done with some simple machines. Symbols definitely, 
for readability, plus numbers would not work with CASE.

> 
> 2. Represent each state with a different function, bound at top-level. The
> state machine can then be represented as a list or structure, with those
> functions operating on it.
> 
> 3. Represent the state machine with a closure. Basically:
> (defun make-state-machine ....
>   (let ((statevar1)
>         (statevar2)
>         (current-state))
>     (flet ((state1 (input) ...)
>            (state2 (input) ...))
>       (setq current-state state1)
>       (lambda (input) (funcall current-state input)))))

Not bad.

kt
From: Matthew Danish
Subject: Re: State machine representation
Date: 
Message-ID: <20040201115211.GG8667@mapcar.org>
On Sun, Feb 01, 2004 at 09:07:01AM +0000, Kenny Tilton wrote:
> That's what I have done with some simple machines. Symbols definitely, 
> for readability, plus numbers would not work with CASE.

Not true; numbers do work with CASE, since CASE compares as if with EQL.
If the equality operator is not specified (as with CASE), then EQL is
the default, according to the definition of /same/ in the glossary.  The
Hyperspec even has an example of CASE on numbers.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Kenny Tilton
Subject: Re: State machine representation
Date: 
Message-ID: <OxaTb.170865$4F2.20209204@twister.nyc.rr.com>
Matthew Danish wrote:

> On Sun, Feb 01, 2004 at 09:07:01AM +0000, Kenny Tilton wrote:
> 
>>That's what I have done with some simple machines. Symbols definitely, 
>>for readability, plus numbers would not work with CASE.
> 
> 
> Not true; numbers do work with CASE, since CASE compares as if with EQL.

Oops. I forgot that the problem is if the key is not a literal since the 
key is not evaluated, so if the OP wanted to use defconstant to set up 
symbolic forms for the states (using literals would be madness) then 
they would have to use #.FSM-INITIAL and #.FSM-BUILDING-INTEGER.

kt

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <fSbTb.156975$sv6.865734@attbi_s52>
Kenny Tilton wrote:

> Oops. I forgot that the problem is if the key is not a literal since the
> key is not evaluated, so if the OP wanted to use defconstant to set up
> symbolic forms for the states (using literals would be madness) then
> they would have to use #.FSM-INITIAL and #.FSM-BUILDING-INTEGER.

This seems like one of the areas where CL sort of botched this up. I keep
encountering lots of places I need #', and by implication #. (like in
apply, funcall, etc.). Scheme seems to have gotten this right. It's simple
philosophy that symbols just evaluate to one thing really helps. You just
use "define" and then things evaluate correctly.

As a question, is there some hidden power that CL's system provides, or is
it largely a waste of time? I'm sure somebody could create a contrived
example of where I might want it, but does it really come up all that
often? Most of the example code I have read doesn't make use of the power
that might be there, so I'm seriously questioning it.

-- Dave
From: Erann Gat
Subject: Re: State machine representation
Date: 
Message-ID: <gNOSPAMat-0102041218530001@192.168.1.51>
In article <·······················@attbi_s52>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Kenny Tilton wrote:
> 
> > Oops. I forgot that the problem is if the key is not a literal since the
> > key is not evaluated, so if the OP wanted to use defconstant to set up
> > symbolic forms for the states (using literals would be madness) then
> > they would have to use #.FSM-INITIAL and #.FSM-BUILDING-INTEGER.
> 
> This seems like one of the areas where CL sort of botched this up. I keep
> encountering lots of places I need #', and by implication #. (like in
> apply, funcall, etc.). Scheme seems to have gotten this right. It's simple
> philosophy that symbols just evaluate to one thing really helps. You just
> use "define" and then things evaluate correctly.

There are good reasons why CL does it the way it does, but you will find
that people around here will be reluctant to explain them to you if you
open by proclaiming that "CL sort of botched this up".

E.
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <vleTb.74491$U%5.407905@attbi_s03>
Erann Gat wrote:

> In article <·······················@attbi_s52>, Dave Roberts
> <·····@re-move.droberts.com> wrote:
> 
>> Kenny Tilton wrote:
>> 
>> > Oops. I forgot that the problem is if the key is not a literal since
>> > the key is not evaluated, so if the OP wanted to use defconstant to set
>> > up symbolic forms for the states (using literals would be madness) then
>> > they would have to use #.FSM-INITIAL and #.FSM-BUILDING-INTEGER.
>> 
>> This seems like one of the areas where CL sort of botched this up. I keep
>> encountering lots of places I need #', and by implication #. (like in
>> apply, funcall, etc.). Scheme seems to have gotten this right. It's
>> simple philosophy that symbols just evaluate to one thing really helps.
>> You just use "define" and then things evaluate correctly.
> 
> There are good reasons why CL does it the way it does, but you will find
> that people around here will be reluctant to explain them to you if you
> open by proclaiming that "CL sort of botched this up".

Okay, fair enough. I wasn't trying to be inflamitory, as I replied to Erik
Naggum. I was just expressing an (incorrect, as I now find out)
observation.

Anyway, please educate me. I want to learn. I read Matthew Danish's posts
and some by Pascal Costanza. I'm now reading a Gabriel & Pitman article
that Pascal pointed to in one of his other posts
(http://www.dreamsongs.com/Separation.html), which seems to explain a lot
of it (though I'm still reading through it as I write this).

So, in summary, I apologize for stepping in somebody's oatmeal. I'm just
working through probably all the standard newbie issues. When I see
something like I saw, my own tendency is to say, "This looks goofy." Please
feel free to reply, "Dave, you're a clueless newbie. Here's why it's really
smart, not goofy: ..."

-- Dave
From: Pascal Costanza
Subject: Re: State machine representation
Date: 
Message-ID: <bvk221$qh7$1@newsreader2.netcologne.de>
Dave Roberts wrote:

> So, in summary, I apologize for stepping in somebody's oatmeal. I'm just
> working through probably all the standard newbie issues.

I have also been through this before not so long ago. You might want to 
take a look at http://www.pascalcostanza.de/lisp/guide.html for a report 
on what I have learned.

Another suggestion: Before getting into arguments with some regulars 
here about off topic issues you might want to google for previous 
discussions and flame wars to see whether it's worth your time.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <WGhTb.208117$na.340158@attbi_s04>
Pascal Costanza wrote:

> 
> Dave Roberts wrote:
> 
>> So, in summary, I apologize for stepping in somebody's oatmeal. I'm just
>> working through probably all the standard newbie issues.
> 
> I have also been through this before not so long ago. You might want to
> take a look at http://www.pascalcostanza.de/lisp/guide.html for a report
> on what I have learned.
> 
> Another suggestion: Before getting into arguments with some regulars
> here about off topic issues you might want to google for previous
> discussions and flame wars to see whether it's worth your time.

Actually, Pascal, I did that a few weeks ago. In fact, it was one of the
documents that convinced me to spend the time to learn CL. ;-)

Thanks for putting it together. A very good overview of the language, its
benefits, and pointers to other documentation.

-- Dave
From: Kenny Tilton
Subject: Re: State machine representation
Date: 
Message-ID: <SYjTb.170933$4F2.20370112@twister.nyc.rr.com>
Dave Roberts wrote:

> Pascal Costanza wrote:
> 
> 
>>Dave Roberts wrote:
>>
>>
>>>So, in summary, I apologize for stepping in somebody's oatmeal. I'm just
>>>working through probably all the standard newbie issues.
>>
>>I have also been through this before not so long ago. You might want to
>>take a look at http://www.pascalcostanza.de/lisp/guide.html for a report
>>on what I have learned.
>>
>>Another suggestion: Before getting into arguments with some regulars
>>here about off topic issues you might want to google for previous
>>discussions and flame wars to see whether it's worth your time.
> 
> 
> Actually, Pascal, I did that a few weeks ago. In fact, it was one of the
> documents that convinced me to spend the time to learn CL. ;-)

Sh*T! Costanza qualifies as one of the Roads to Lisp before I do?! There 
is no justice.

kenny

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Jens Axel Søgaard
Subject: Re: State machine representation
Date: 
Message-ID: <401dfebc$0$295$edfadb0f@dread12.news.tele.dk>
Kenny Tilton wrote:

> Sh*T! Costanza qualifies as one of the Roads to Lisp before I do?! There 
> is no justice.

But has McCarthy used his laptop?

-- 
Jens Axel S�gaard
From: Pascal Costanza
Subject: Re: State machine representation
Date: 
Message-ID: <bvlaq5$ljt$1@newsreader2.netcologne.de>
Jens Axel S�gaard wrote:
> Kenny Tilton wrote:
> 
>> Sh*T! Costanza qualifies as one of the Roads to Lisp before I do?! 
>> There is no justice.
> 
> But has McCarthy used his laptop?

No, but I am working on this.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <g1ITb.212125$xy6.1100036@attbi_s02>
Pascal Costanza wrote:

> 
> Jens Axel Søgaard wrote:
>> Kenny Tilton wrote:
>> 
>>> Sh*T! Costanza qualifies as one of the Roads to Lisp before I do?!
>>> There is no justice.
>> 
>> But has McCarthy used his laptop?
> 
> No, but I am working on this.

Maybe I can step on his toes while he's using your laptop. You know, ask him
annoying stuff like his stance on continuations...

-- Dave
From: Matthew Danish
Subject: Re: State machine representation
Date: 
Message-ID: <20040201191457.GH8667@mapcar.org>
On Sun, Feb 01, 2004 at 06:48:43PM +0000, Dave Roberts wrote:
> Kenny Tilton wrote:
> 
> > Oops. I forgot that the problem is if the key is not a literal since the
> > key is not evaluated, so if the OP wanted to use defconstant to set up
> > symbolic forms for the states (using literals would be madness) then
> > they would have to use #.FSM-INITIAL and #.FSM-BUILDING-INTEGER.
> 
> This seems like one of the areas where CL sort of botched this up. I keep
> encountering lots of places I need #', and by implication #. (like in
> apply, funcall, etc.). Scheme seems to have gotten this right. It's simple
> philosophy that symbols just evaluate to one thing really helps. You just
> use "define" and then things evaluate correctly.
> 
> As a question, is there some hidden power that CL's system provides, or is
> it largely a waste of time? I'm sure somebody could create a contrived
> example of where I might want it, but does it really come up all that
> often? Most of the example code I have read doesn't make use of the power
> that might be there, so I'm seriously questioning it.

I'm not sure why you connect #' and #. as they are completely different
constructions.  #'foo becomes (FUNCTION foo) and #.foo means ``evaluate
foo at read-time.''  Since CASE expects all of the keys to be statically
determinable, you need to use #. to sneak in the value of a variable
(and then only at read-time).

As for #'foo, I suggest that you read my 3 recent posts in the ``Lisp's
future'' thread, as they address your question asked by someone else.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <NzcTb.160649$nt4.732141@attbi_s51>
Matthew Danish wrote:

> I'm not sure why you connect #' and #. as they are completely different
> constructions.  #'foo becomes (FUNCTION foo) and #.foo means ``evaluate
> foo at read-time.''  Since CASE expects all of the keys to be statically
> determinable, you need to use #. to sneak in the value of a variable
> (and then only at read-time).

Okay, my mistake. I have only had to deal with #' so far. I assumed that #.
was for retrieving the values of constants. I understand what it does now
and I can see the value of that.

> As for #'foo, I suggest that you read my 3 recent posts in the ``Lisp's
> future'' thread, as they address your question asked by someone else.

Great. I'll take a look.

Thanks,

-- Dave
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <R9eTb.157415$sv6.872388@attbi_s52>
Matthew Danish wrote:

> As for #'foo, I suggest that you read my 3 recent posts in the ``Lisp's
> future'' thread, as they address your question asked by someone else.

Okay, so I just read those. Thanks! That helped a lot. The summary, from my
side is, I just wasn't seeing the larger issues. Your posts and Pascal
Costanza's really helped me see why this actually makes sense and isn't
just a random wart.

If it helps, understand that my earliest introduction to Lisp was via Scheme
in 1989 or so. I still have a fondness for the clean syntax of Scheme. Like
I said in my post to Erik Naggum, there are two reasons for things like
this in a language: either they are warts left behind as evolution grinds
through language design (think about large parts of C++, for instance) and
you want to keep compatibility with old code, or there are really good
reasons for it and I as the original poster just wasn't seeing it. In this
case, it was the latter.

Your post showed why there are larger issues to consider. In fact, I can
plainly see that while Scheme's simplistic treatment of this issue works
better for teaching and general programming usage, it would suffer
tremendously when trying to "program in the large" for sizable projects.

Anyway, thanks. That helped. A lot. ;-)

- Dave
From: Erik Naggum
Subject: Re: State machine representation
Date: 
Message-ID: <2004-032-742-KL2065E@naggum.no>
* Dave Roberts
| This seems like one of the areas where CL sort of botched this up.

  Why do you need to make this kind of comment?

-- 
Erik Naggum | Oslo, Norway                                      2004-032

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <8MdTb.157308$sv6.871544@attbi_s52>
Erik Naggum wrote:

> * Dave Roberts
> | This seems like one of the areas where CL sort of botched this up.
> 
>   Why do you need to make this kind of comment?

Sorry, just making an observation. I wasn't trying to provoke, if that's
what you're implying. Specifically, I was comparing CL's way of handling
functions bound to symbols with that of Scheme, which honestly does seem
cleaner, in my not so educated opinion. There are many places where this
sort of crops up. In general, Scheme seems more clean and streamlined
("regular" ?). CL seems to have a few more peculiarities earned from more
years of doing more serious large-scale programming (now I'll offend the
Scheme guys by implying that Scheme hasn't done anything serious--again,
that's not what I'm saying).

Anyway, there are typically a couple of reasons for peculiarities like this
in a language. They are:

1. The language just sort of evolved, and this is one of the places where
that shows. We couldn't go back and clean up every last nit of syntactic
irregularity, because that would break too much code.

2. There is a very good reason that this works the way it is. You're just
missing it, Mr. Roberts, because you're a newbie. Again, if this is the
case, please educate me. It's easier to tolerate certain irregularities if
there is a good reason for them.

Anyway, I was not trying to offend. If you believe there is a lot of
advantage in CL's way of doing things, please share. I want to understand
if there is something I may have missed.

-- Dave
From: Matthew Danish
Subject: Re: State machine representation
Date: 
Message-ID: <20040201211615.GI8667@mapcar.org>
Just a few pre-emptive clarifications:

The ideas of a variable bound to a value and a symbol bound to a value
are separate.  Symbols are only bound to values incidentally through the
SYMBOL-VALUE slot of the symbol object.  Lexical variables, for example,
have nothing to do with the values contained in symbols.  The only
relation lexical variables have to symbols is that symbols name
variables.  And generally compiled code discards that relationship.

The other thing: there is nothing preventing a variable from being bound
to a function object.  You can do:

(let ((a (lambda (x) x)))
  (funcall a 1))

And feel somewhat Scheme-y.

CL also has a namespace for variables that are to be bound exclusively
to functions.  In the above example, the symbol A names a variable bound
to a function.  In the following example, the symbol A names a function
variable bound to a function:

(flet ((a (x) x))
  (a 1))

By default, in the arguments of a function call, CL expects that symbols
will name ordinary variables.  If you want a symbol to name the function
variable in the alternate namespace, then you use #'A.

(let ((a (lambda (x) x)))  ; ordinary variable binding declaration
  (flet ((a (x) x))  ; function variable binding declaration
    (foo a)  ; A names the ordinary variable
    (foo #'a)))  ; #'A names the function variable

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Dave Roberts
Subject: Understanding #' and function variables
Date: 
Message-ID: <GAeTb.161070$nt4.733919@attbi_s51>
Matthew Danish wrote:

> Just a few pre-emptive clarifications:
> 
> The ideas of a variable bound to a value and a symbol bound to a value
> are separate.  Symbols are only bound to values incidentally through the
> SYMBOL-VALUE slot of the symbol object.  Lexical variables, for example,
> have nothing to do with the values contained in symbols.  The only
> relation lexical variables have to symbols is that symbols name
> variables.  And generally compiled code discards that relationship.

Matt, first let me say that your posts are really helping me work through.

That said, I don't think I understand the above paragraph. Part of it is
that I'm struggling with the various CL terminology for "cell," "object,"
"symbol," "variable," and "binding." I'm coming from a C->C++->Java sort of
background and so that's clouding my thinking. What may help me is to sort
of describe a simplistic implementation of this in C terms, so I can make
the translation. I have bits and pieces of it, and just when I think I'm
making some headway, I read something like the paragraph above that shows
that I don't yet have it. ;-)
 
> The other thing: there is nothing preventing a variable from being bound
> to a function object.  You can do:
> 
> (let ((a (lambda (x) x)))
>   (funcall a 1))
> 
> And feel somewhat Scheme-y.

Yes, and this is one thing that confuses me. So what is happening in this
case? By my probably incorrect notion of what's happening under the hood,
the LET form is creating a new local symbol(?) named "a," and then binding
the value portion(?) of that symbol to the lamba expression object. Is that
right? So what's a variable as opposed to a symbol/binding?

> CL also has a namespace for variables that are to be bound exclusively
> to functions.  In the above example, the symbol A names a variable bound
> to a function.  In the following example, the symbol A names a function
> variable bound to a function:
> 
> (flet ((a (x) x))
>   (a 1))

So is the best way to think about this as two different variables, one
capable of holding functions and the other values, or is it better to think
of a single named symbol ("A"), that has pointers/references, one to a
value and the other to and object. In other words, a symbol is implemented
as a structure with these things along with a reference to a property list
and all the other things that a symbol has.

> By default, in the arguments of a function call, CL expects that symbols
> will name ordinary variables.  If you want a symbol to name the function
> variable in the alternate namespace, then you use #'A.
> 
> (let ((a (lambda (x) x)))  ; ordinary variable binding declaration
>   (flet ((a (x) x))  ; function variable binding declaration
>     (foo a)  ; A names the ordinary variable
>     (foo #'a)))  ; #'A names the function variable

So this brings up a good question: If these are implemented as the same
symbol with two "slots" (not to be confused with CLOS slots), then it seems
like this would cause problems. If these are really two separate symbols in
two separate namespaces (like if I was doing name mangling internally or
something to value-A and function-A), that would seem to be better. The
binding for "function-A" would go away as the FLET form was exited, while
that would still leave "value-A" around until the LET form exited. If these
are the same symbol, "A," with just two slots, I'm not sure how it would be
handled when the FLET form went out of scope and yet I was still in the LET
scope.

-- Dave
From: Matthew Danish
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <20040201221328.GK8667@mapcar.org>
On Sun, Feb 01, 2004 at 09:54:46PM +0000, Dave Roberts wrote:
> > The other thing: there is nothing preventing a variable from being bound
> > to a function object.  You can do:
> > 
> > (let ((a (lambda (x) x)))
> >   (funcall a 1))
> > 
> > And feel somewhat Scheme-y.
> 
> Yes, and this is one thing that confuses me. So what is happening in this
> case? By my probably incorrect notion of what's happening under the hood,
> the LET form is creating a new local symbol(?) named "a," and then binding
> the value portion(?) of that symbol to the lamba expression object. Is that
> right? So what's a variable as opposed to a symbol/binding?

No; it is creating a new variable which is /named by/ the symbol A.  The
variable is bound to the function.  The symbol A is an entirely separate
object in its own right, and in this context it is only being used to
name the variable.  Remember, Lisp programs are syntactically described
by Lisp data such as lists and symbols, etc.

> So is the best way to think about this as two different variables, one
> capable of holding functions and the other values, or is it better to think
> of a single named symbol ("A"), that has pointers/references, one to a
> value and the other to and object. In other words, a symbol is implemented
> as a structure with these things along with a reference to a property list
> and all the other things that a symbol has.

It is two different variables.  However, there is a confusing part:
symbols really do have SYMBOL-VALUE and SYMBOL-FUNCTION accessors.  But
these have nothing to do with lexical variables (they are relevant to
special variables).


P.S. It is better not to think in C terms w/regard to this.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <oefTb.200596$I06.2213924@attbi_s01>
Matthew Danish wrote:

> On Sun, Feb 01, 2004 at 09:54:46PM +0000, Dave Roberts wrote:
>> > The other thing: there is nothing preventing a variable from being
>> > bound
>> > to a function object.  You can do:
>> > 
>> > (let ((a (lambda (x) x)))
>> >   (funcall a 1))
>> > 
>> > And feel somewhat Scheme-y.
>> 
>> Yes, and this is one thing that confuses me. So what is happening in this
>> case? By my probably incorrect notion of what's happening under the hood,
>> the LET form is creating a new local symbol(?) named "a," and then
>> binding the value portion(?) of that symbol to the lamba expression
>> object. Is that right? So what's a variable as opposed to a
>> symbol/binding?
> 
> No; it is creating a new variable which is /named by/ the symbol A.  The
> variable is bound to the function.  The symbol A is an entirely separate
> object in its own right, and in this context it is only being used to
> name the variable.  Remember, Lisp programs are syntactically described
> by Lisp data such as lists and symbols, etc.

Okay, I think I'm getting there. Maybe an implementation example to clarify
a bit:

So a simplistic implementation of a variable might be:
struct variable {
        lisp_object * value;
        symbol * symbol;
}

Is that sort of right? So a symbol really is an atomic object (yea, I know,
that's probably when they call them atoms... ;-). The key point is, rather
than a symbol refering to a value, it's really that a variable refers to
both a value as well as the name of the variable, right?

So what's a binding versus variable? What I had previously in my head was
that a binding was sort of like what I just wrote above as a structure for
variable.

So if that's right, then additional quesitons are:

1. How does the system map between symbols and variables? Seems like it
would be inefficient to search through a set of variables to find one with
the same symbol name, rather than starting at the symbol name and following
pointers to the value.

2. How are function and value variables different?

>> So is the best way to think about this as two different variables, one
>> capable of holding functions and the other values, or is it better to
>> think of a single named symbol ("A"), that has pointers/references, one
>> to a value and the other to and object. In other words, a symbol is
>> implemented as a structure with these things along with a reference to a
>> property list and all the other things that a symbol has.
> 
> It is two different variables.  However, there is a confusing part:
> symbols really do have SYMBOL-VALUE and SYMBOL-FUNCTION accessors.  But
> these have nothing to do with lexical variables (they are relevant to
> special variables).
> 
> 
> P.S. It is better not to think in C terms w/regard to this.

I'm not really trying to think in terms of C, but really the implementation.
Put another way, I'm a hardware guy and I think in terms of bytes and
pointers and such. If you want to give an assembly-language definition,
that would help. I'm not going for a language comparison here with C, just
trying to understand the implementation, and C is an easy language to
describe that implementation (where C = "high level assembly language").

-- Dave
From: Harald Hanche-Olsen
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <pcoekteo11y.fsf@thoth.math.ntnu.no>
+ Dave Roberts <·····@re-move.droberts.com>:

| I'm not really trying to think in terms of C, but really the
| implementation.

I think that is a mistake.  CL provides a set of abstractions that are
best understood precisely as abstractions.  If you get too involved in
how these abstractions are implemented, I think you will lose the very
essence of the language.  I think this is what Erik was hinting at
when he suggested elsewhere that you should not compare CL with other
languages.  If you try to think of one language in another language's
terms, you lose.  "Real programmers write Fortran in any language."

(Boy, I have posted more responses to you than I usually post to this
newsgroup in a month.  I'm really a lurker here.  But now it really is
bedtime on my side of the globe, so it's time for me to fade back into
obscurity.)

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <WNhTb.201636$I06.2220290@attbi_s01>
Harald Hanche-Olsen wrote:

> + Dave Roberts <·····@re-move.droberts.com>:
> 
> | I'm not really trying to think in terms of C, but really the
> | implementation.
> 
> I think that is a mistake.  CL provides a set of abstractions that are
> best understood precisely as abstractions.  If you get too involved in
> how these abstractions are implemented, I think you will lose the very
> essence of the language.  I think this is what Erik was hinting at
> when he suggested elsewhere that you should not compare CL with other
> languages.  If you try to think of one language in another language's
> terms, you lose.  "Real programmers write Fortran in any language."

Hmmm... I typically find this works out better for me. Again, I'm not
looking for specifically a C comparison versus CL, just a naive description
of how this *might* be implemented. That probably isn't descriptive of how
an efficient implementation works; that's fine, I just need to get hold of
the mental model for this. Again, if somebody feels it's easier to describe
the naive implementation in CL syntax, rather than C or something, I'm fine
with that. I just don't understand enough CL right now, being a newbie, so
I'm trying to cast the description in something I know better. But if CL
works better, that's fine.

Even if you just want to say: A symbol is basically a structure that
holds... blah, blah, blah, that would help.

> (Boy, I have posted more responses to you than I usually post to this
> newsgroup in a month.  I'm really a lurker here.  But now it really is
> bedtime on my side of the globe, so it's time for me to fade back into
> obscurity.)
> 

Go to sleep. Thanks for the help. I appreciate it. ;-)

-- Dave
From: Frode Vatvedt Fjeld
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2h8yjl50jz.fsf@vserver.cs.uit.no>
Dave Roberts <·····@re-move.droberts.com> writes:

> Okay, I think I'm getting there. Maybe an implementation example to clarify
> a bit:
>
> So a simplistic implementation of a variable might be:
> struct variable {
>         lisp_object * value;
>         symbol * symbol;
> }

This is quite incorrect. A variable is an association between (from) a
name (in the variable name-space) and a value. This association can be
of many kinds, neither of which match your struct very well, to my
knowledge.

If you must think of this in terms of other languages (and this is
discouraged for good reasons), the Common Lisp

  (defun foo ()
    (let ((variable 'value))
      ...)

where the name variable is associated with value using a lexical
binding, maps approximately to the following pseudo-C:

  foo () {
    lisp_object variable = 'value;
    ...
  }

In both cases, what a variable "is" is a poor question from a
beginner. It's best to accept the abstraction on its own terms and
just understand what it provides and how you use it. Later on you
might learn e.g. how gcc compiles that function into assembly:
sometimes variable will denote a register, sometimes a piece of the
stack-frame, a boolean bit somewhere, or what have you. It's pretty
much the same with the Common Lisp version.

-- 
Frode Vatvedt Fjeld
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87llnlmidm.fsf@thalassa.informatimago.com>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
> > Okay, I think I'm getting there. Maybe an implementation example to clarify
> > a bit:
> >
> > So a simplistic implementation of a variable might be:
> > struct variable {
> >         lisp_object * value;
> >         symbol * symbol;
> > }
> 
> This is quite incorrect. A variable is an association between (from) a
> name (in the variable name-space) and a value. This association can be
> of many kinds, neither of which match your struct very well, to my
> knowledge.

I think  this is  wrong, a  variable is not  an association  between a
_name_  and a  value.  In  my undestanding,  a variable  is  a _place_
(where values can be referenced from).

A symbol has five places (name, package, value, function and plist).

A cons has two places (car, cdr) oops, I mean (first, rest), ah, it's
the same, the name does not matter!

A lexical  variable has one place.   For a lexical variable,  we use a
symbol to  name it  (or its  place).  The name  of a  lexical variable
exists only in  the source up to the compile  time.  At run-time, this
name is not remembered.


> In both cases, what a variable "is" is a poor question from a
> beginner. It's best to accept the abstraction on its own terms and
> just understand what it provides and how you use it.

Indeed.

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041053370001@k-137-79-50-101.jpl.nasa.gov>
In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
<····@thalassa.informatimago.com> wrote:

> A symbol has five places (name, package, value, function and plist).

Two nits:

Calling the second place "home package" is more strictly correct.  A
symbol can be interned in many packages, but can have only one home
package.

Also, a symbol can have one value place per thread, plus a global value
place, so to count them up and come up with a total of five places is
misleading.

E.
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ektdkm59.fsf@thalassa.informatimago.com>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
> <····@thalassa.informatimago.com> wrote:
> 
> > A symbol has five places (name, package, value, function and plist).
> 
> Two nits:
> 
> Calling the second place "home package" is more strictly correct.  A
> symbol can be interned in many packages, but can have only one home
> package.

Indeed.

 
> Also, a symbol can have one value place per thread, plus a global value
> place, so to count them up and come up with a total of five places is
> misleading.

I'm  not sure  to understand  the rationnal  for having  one  place by
thread for special variables.

I've understood that  the purpose of special variables  was to be free
from lexical scoping.


;; without threads:

(defvar *common-parameter* :do-it-one-way

(defun fun1 ()
    (if (eq *common-parameter* :do-it-one-way)
        (do-it-one-way)
        (do-it-the-other-way)))

(defun fun2 ()
    (let ((*common-parameter* :do-it-the-other-way))
          (do ((start-time (get-universal-time))
               (end-time   (get-universal-time) (get-universal-time)))
             ((> (- end-time start-time) 40))
           (fun1))))


;; with threads:

(defvar *common-parameter* :do-it-one-way

(defun fun1 ()
    (if (eq *common-parameter* :do-it-one-way)
        (do-it-one-way)
        (do-it-the-other-way)))

(defun fun2 ()
    (let ((*common-parameter* :do-it-the-other-way))
        (sleep 40))

(process-run-function (lambda () (loop (fun1))))
(process-run-function fun2)


Keeping one  place per thread would  defeat this obvious  (at least to
me)  idiom.  That  is, I'd  expect global  stuff to  be common  to all
threads, and special variables like common-lisp:*print-circle* to need
special, explicit  handling (mutex) when  I start to use  non standard
stuff like threads.



-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041942360001@192.168.1.51>
In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
<····@thalassa.informatimago.com> wrote:

> I'm  not sure  to understand  the rationnal  for having  one  place by
> thread for special variables.

Consider:

Thread 1:
  (let ( (*print-base* 8) ) (with-open-file (f "file1") (print-stuff)...

Thread 2:
  (let ( (*print-base* 16) ) (with-open-file (f "file2") (print-stuff)...

If there were not a separate place per thread for the binding of
*print-base* then the results would be unpredictable (there would be a
race condition) and almost certainly not what you intended.

> 
> I've understood that  the purpose of special variables  was to be free
> from lexical scoping.

Hm, that's an interesting way to put it.  I'd phrase it differently:
special variables are used when you want dynamic bindings.


> ;; without threads:
> 
> (defvar *common-parameter* :do-it-one-way
> 
> (defun fun1 ()
>     (if (eq *common-parameter* :do-it-one-way)
>         (do-it-one-way)
>         (do-it-the-other-way)))
> 
> (defun fun2 ()
>     (let ((*common-parameter* :do-it-the-other-way))
>           (do ((start-time (get-universal-time))
>                (end-time   (get-universal-time) (get-universal-time)))
>              ((> (- end-time start-time) 40))
>            (fun1))))
> 
> 
> ;; with threads:
> 
> (defvar *common-parameter* :do-it-one-way
> 
> (defun fun1 ()
>     (if (eq *common-parameter* :do-it-one-way)
>         (do-it-one-way)
>         (do-it-the-other-way)))
> 
> (defun fun2 ()
>     (let ((*common-parameter* :do-it-the-other-way))
>         (sleep 40))
> 
> (process-run-function (lambda () (loop (fun1))))
> (process-run-function fun2)
> 
> 
> Keeping one  place per thread would  defeat this obvious  (at least to
> me)  idiom.  That  is, I'd  expect global  stuff to  be common  to all
> threads, and special variables like common-lisp:*print-circle* to need
> special, explicit  handling (mutex) when  I start to use  non standard
> stuff like threads.

"Global stuff" as you put it *is* common to all threads.  So if you did:

(defun fun2 ()
  (setf *common-parameter* ...)
  ...)

instead of using LET it would work the way you expect.  But using globals
this way is generally frowned upon (or if it isn't it ought to be).

In your fun2, you are not changing the global value of *common-parameter*,
you are creating a new dynamic binding for it.  Within the scope of this
new binding, the global binding is no longer accessible -- unless, of
course, the implementation provides an extension to allow you to access
it.  There's nothing in principle that prevents this, but I don't know of
any implementation that offers this "feature".  (It's actually possible to
implement this "feature" yourself if you really want it.  Figuring out how
is left as an excercise.  Hint: it involves shadowing DEFVAR and using
DEFINE-SYMBOL-MACRO.)

Did that make sense?

E.
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87llnkju34.fsf@thalassa.informatimago.com>
·········@jpl.nasa.gov (Erann Gat) writes:
> In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
> <····@thalassa.informatimago.com> wrote:
> 
> > I'm  not sure  to understand  the rationnal  for having  one  place by
> > thread for special variables.
> 
> Consider:
> 
> Thread 1:
>   (let ( (*print-base* 8) ) (with-open-file (f "file1") (print-stuff)...
> 
> Thread 2:
>   (let ( (*print-base* 16) ) (with-open-file (f "file2") (print-stuff)...
> 
> If there were not a separate place per thread for the binding of
> *print-base* then the results would be unpredictable (there would be a
> race condition) and almost certainly not what you intended.
>
> [...]
>
> "Global stuff" as you put it *is* common to all threads.  So if you did:
> 
> (defun fun2 ()
>   (setf *common-parameter* ...)
>   ...)
> 
> instead of using LET it would work the way you expect.  But using globals
> this way is generally frowned upon (or if it isn't it ought to be).
> 
> In your fun2, you are not changing the global value of *common-parameter*,
> you are creating a new dynamic binding for it.  Within the scope of this
> new binding, the global binding is no longer accessible -- unless, of
> course, the implementation provides an extension to allow you to access
> it.  There's nothing in principle that prevents this, but I don't know of
> any implementation that offers this "feature".  (It's actually possible to
> implement this "feature" yourself if you really want it.  Figuring out how
> is left as an excercise.  Hint: it involves shadowing DEFVAR and using
> DEFINE-SYMBOL-MACRO.)
> 
> Did that make sense?

Perfectly. Thank you.

dynamic, global      --> defvar,                    setf special variable
dynamic, per-thread  --> defvar or declare special, let (binding)
static, lexical      --> no defvar,                 let (binding)


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0302040829120001@192.168.1.51>
In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
<····@thalassa.informatimago.com> wrote:

> > Did that make sense?
> 
> Perfectly. Thank you.

Whew!  :-)

One minor nit:

> dynamic, global      --> defvar,                    setf special variable
> dynamic, per-thread  --> defvar or declare special, let (binding)
> static, lexical      --> no defvar,                 let (binding)
                           ^^^^^^^^^
and no (declare/proclaim/declaim (special ...)).

It is IMHO an unfortunate design choice that lexical scoping in Common
Lisp can only be obtained by insuring the absence of things.

E.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <G7QTb.209792$I06.2321693@attbi_s01>
Erann Gat wrote:

> In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
> <····@thalassa.informatimago.com> wrote:
> 
>> I'm  not sure  to understand  the rationnal  for having  one  place by
>> thread for special variables.
> 
> Consider:
> 
> Thread 1:
>   (let ( (*print-base* 8) ) (with-open-file (f "file1") (print-stuff)...
> 
> Thread 2:
>   (let ( (*print-base* 16) ) (with-open-file (f "file2") (print-stuff)...
> 
> If there were not a separate place per thread for the binding of
> *print-base* then the results would be unpredictable (there would be a
> race condition) and almost certainly not what you intended.

Yes, but you *could* cure that with mutexs and such. That's what C or Java
would do and the solution works well and is well known. Now, whether this
is correct for Lisp or not depends highly on the definition of a special
variable and its semantics. I'm still learning those, so I'll stop here. My
only point is to say that Pascal's view isn't necessarily wrong when viewed
in the context of the broad set of programming languages and idioms, though
it may not be the direction that Lisp would take. As I said in another
response, it's the naive direction I would probably take.

>> Keeping one  place per thread would  defeat this obvious  (at least to
>> me)  idiom.  That  is, I'd  expect global  stuff to  be common  to all
>> threads, and special variables like common-lisp:*print-circle* to need
>> special, explicit  handling (mutex) when  I start to use  non standard
>> stuff like threads.
> 
> "Global stuff" as you put it *is* common to all threads.  So if you did:
> 
> (defun fun2 ()
>   (setf *common-parameter* ...)
>   ...)
> 
> instead of using LET it would work the way you expect.  But using globals
> this way is generally frowned upon (or if it isn't it ought to be).

So there is a concept of a global independent of a special variable? Okay,
this just keeps getting more interesting.

> 
> In your fun2, you are not changing the global value of *common-parameter*,
> you are creating a new dynamic binding for it.  Within the scope of this
> new binding, the global binding is no longer accessible -- unless, of
> course, the implementation provides an extension to allow you to access
> it.  There's nothing in principle that prevents this, but I don't know of
> any implementation that offers this "feature".  (It's actually possible to
> implement this "feature" yourself if you really want it.  Figuring out how
> is left as an excercise.  Hint: it involves shadowing DEFVAR and using
> DEFINE-SYMBOL-MACRO.)
> 
> Did that make sense?

Sort of. So truthfully, according to standard ANSI CL, there is no such
thing as a true global variable, only special variables that have dynamic
scope. Thus, if you were to add extensions to allow threads and keep the
same semantics, you really have to have a dynamic value for each special
per thread. That does then beg the question of how one implements global
state. I guess you'd have to do it with a shared heap structure like a list
or vector, right?

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0302040908550001@192.168.1.51>
In article <························@attbi_s01>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Erann Gat wrote:
> 
> > In article <··············@thalassa.informatimago.com>, Pascal Bourguignon
> > <····@thalassa.informatimago.com> wrote:
> > 
> >> I'm  not sure  to understand  the rationnal  for having  one  place by
> >> thread for special variables.
> > 
> > Consider:
> > 
> > Thread 1:
> >   (let ( (*print-base* 8) ) (with-open-file (f "file1") (print-stuff)...
> > 
> > Thread 2:
> >   (let ( (*print-base* 16) ) (with-open-file (f "file2") (print-stuff)...
> > 
> > If there were not a separate place per thread for the binding of
> > *print-base* then the results would be unpredictable (there would be a
> > race condition) and almost certainly not what you intended.
> 
> Yes, but you *could* cure that with mutexs and such.

Not if you want to run these two threads in parallel on a multiprocessor
you can't.

> So there is a concept of a global independent of a special variable? Okay,
> this just keeps getting more interesting.

Yes and no.  Strictly speaking it is not possible to create a global
binding for a variable without also declaring it special.  In practice
most implementations do allow this.

But yes, there are three kinds of bindings: global, dynamic, and lexical. 
Global bindings are visible across all threads.  Dynamic bindings are
visible only in the thread in which they were created.  And lexical
bindings are visible only in the lexical form in which they were created.

> > In your fun2, you are not changing the global value of *common-parameter*,
> > you are creating a new dynamic binding for it.  Within the scope of this
> > new binding, the global binding is no longer accessible -- unless, of
> > course, the implementation provides an extension to allow you to access
> > it.  There's nothing in principle that prevents this, but I don't know of
> > any implementation that offers this "feature".  (It's actually possible to
> > implement this "feature" yourself if you really want it.  Figuring out how
> > is left as an excercise.  Hint: it involves shadowing DEFVAR and using
> > DEFINE-SYMBOL-MACRO.)
> > 
> > Did that make sense?
> 
> Sort of. So truthfully, according to standard ANSI CL, there is no such
> thing as a true global variable, only special variables that have dynamic
> scope. Thus, if you were to add extensions to allow threads and keep the
> same semantics, you really have to have a dynamic value for each special
> per thread. That does then beg the question of how one implements global
> state. I guess you'd have to do it with a shared heap structure like a list
> or vector, right?

Wow, you're catching on fast.  Actually, the concept of a global variable
does exist in ANSI CL (look in the glossary) but the distinction between a
global and a dynamic variable only manifests itself when threads are
introduced, and ANSI doesn't concern itself with threads.  So this entire
discussion is predicated on having threads in the picture which means that
what we're really talking about is vendor extensions.  But what I've
described is (as far as I now) the de facto standard.

E.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <H%%Tb.86703$U%5.465879@attbi_s03>
Erann Gat wrote:

> In article <························@attbi_s01>, Dave Roberts
> <·····@re-move.droberts.com> wrote:
>> Yes, but you *could* cure that with mutexs and such.
> 
> Not if you want to run these two threads in parallel on a multiprocessor
> you can't.

?? Why not? Every other threading system does this all the time (C, Java,
etc.). No issues. I just need a simple set of mutex primitives to keep the
threads from access the same state at the same time and then I'm fine.
Whether on single or multiple processors makes no difference. I'm sure you
know this, so maybe I'm misunderstand what you're saying.


> Yes and no.  Strictly speaking it is not possible to create a global
> binding for a variable without also declaring it special.  In practice
> most implementations do allow this.
> 
> But yes, there are three kinds of bindings: global, dynamic, and lexical.
> Global bindings are visible across all threads.  Dynamic bindings are
> visible only in the thread in which they were created.  And lexical
> bindings are visible only in the lexical form in which they were created.

I thought that special = dynamic. Is that not right. You say that global =
special, so those three types would then ben global/special/dynamic,
dynamic, and lexical. How do I reconcile those other two.

Another question would also be, how do I create global/special/dynamic and
any global/non-special variable. DEFVAR for the first, I suppose. How do I
create a non-special global?

>> Sort of. So truthfully, according to standard ANSI CL, there is no such
>> thing as a true global variable, only special variables that have dynamic
>> scope. Thus, if you were to add extensions to allow threads and keep the
>> same semantics, you really have to have a dynamic value for each special
>> per thread. That does then beg the question of how one implements global
>> state. I guess you'd have to do it with a shared heap structure like a
>> list or vector, right?
> 
> Wow, you're catching on fast.  Actually, the concept of a global variable
> does exist in ANSI CL (look in the glossary) but the distinction between a
> global and a dynamic variable only manifests itself when threads are
> introduced, and ANSI doesn't concern itself with threads.  So this entire
> discussion is predicated on having threads in the picture which means that
> what we're really talking about is vendor extensions.  But what I've
> described is (as far as I now) the de facto standard.

Thanks. This stuff isn't really difficult, just different with lots of very
precise terminology if you're coming from a C/Java world. All the
discussion has also allowed about five to ten people provide their slightly
different perspectives, which helps me pick it out fast.

Is the manifestation of the difference between a global and a dynamic
variable really limited to when threads are there? I mean, the SBCL example
I used earlier where a top-level SETQ seems to create what I basically
would consider a global variable, similar to C. Any LET form shadows it,
but doesn't set it in the same way as a dynamic variable. And the example I
ran for myself obviously used only a single thread. Thus, even with a
single thread, you could see the difference between a dynamic/non-dynamic
global.

Also, I looked up in CLHS "global varable." It basically says "global =
dynamic or constant." So, this says to me, there really isn't the
equivalent of a non-constant global, the way I would expect with something
like C. Officially, at least, all globals are really dynamic, or they are
constants.

-- Dave
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvqgtm$ef$1@newsreader2.netcologne.de>
Dave Roberts wrote:

> Also, I looked up in CLHS "global varable." It basically says "global =
> dynamic or constant." So, this says to me, there really isn't the
> equivalent of a non-constant global, the way I would expect with something
> like C. Officially, at least, all globals are really dynamic, or they are
> constants.

In a sense, there is. Since there is the rule in Common Lisp to use 
asterisks to mark special variables (as introduced by DEFVAR), you don't 
get any name collisions with local variables in practice. So you get the 
effect of a global quasi-lexical variable by simply refraining from 
rebinding it.

I have seen only one example so far for the need to have real global 
lexical variables. It's used in a set of macros for simulating 
continuations in Paul Graham's "On Lisp", a concept which isn't very 
wide spread in the Common Lisp community, to put it mildly.

If you really need global lexical variables, you can simulate this with 
DEFINE-SYMBOL-MACRO. AFAIR, there is an example how to do this in the 
HyperSpec.

ISLISP is a Lisp dialect that has both global lexical and dynamic 
variables. ISLISP is very close to Common Lisp in many respects. One can 
actually regard it as a subset of Common Lisp, except for a few minor 
details.

And then of course, for the sake of completeness, it's relatively easy 
to implement dynamic variables on your own once you have understood the 
concept, and most Scheme implementations come with one or more ways to 
support this concept, for examples in the form of parameter objects or 
so-called fluid variables. However, Scheme doesn't standardize this and 
you risk to get different semantics from different Scheme 
implementations for the same construct. (This may or may not important 
to you.)

In my opinion, Common Lisp has gotten this issue right, and ISLISP has 
improved a little on this, but too little for practical purposes.

Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2ilUb.178967$5V2.884236@attbi_s53>
Pascal Costanza wrote:

> 
> Dave Roberts wrote:
> 
>> Also, I looked up in CLHS "global varable." It basically says "global =
>> dynamic or constant." So, this says to me, there really isn't the
>> equivalent of a non-constant global, the way I would expect with
>> something like C. Officially, at least, all globals are really dynamic,
>> or they are constants.
> 
> In a sense, there is. Since there is the rule in Common Lisp to use
> asterisks to mark special variables (as introduced by DEFVAR), you don't
> get any name collisions with local variables in practice. So you get the
> effect of a global quasi-lexical variable by simply refraining from
> rebinding it.

Right. That was the conclusion I came to. You can get the behavior, you just
have to avoid name collisions. I'm guessing that this is probably why the
asterisk naming convention arose--it was harder to accidentally do shadow
yourself with a LET.

-- Dave
From: Damien Kick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ovr7wewr7m.fsf@email.mot.com>
Pascal Costanza <········@web.de> writes:

> I have seen only one example so far for the need to have real global
> lexical variables. It's used in a set of macros for simulating
> continuations in Paul Graham's "On Lisp", a concept which isn't very
> wide spread in the Common Lisp community, to put it mildly.

Actually, Peter Norvig also mentions continuations in _PAIP_ during
his treatment of the subject of implementing Prolog in Lisp.  IIRC,
Paul Graham also uses his continuation macros in his implementation of
Prolog in _On Lisp_.  I currently own merely four books on Common
Lisp: _PAIP_, _Object-Oriented Programming in Common Lisp_, _ANSI
Common Lisp_, and _On Lisp_ (well, I "own" a softcopy).  If it wasn't
for c.l.l, I would've thought that the use of continuations (or
rather, using macros to roll one's own continuations) *was* pretty
wide spread in the Common Lisp community; well, at least in the
Implementing Prolog in Lisp department.

For a while, I used to wonder about CL lacking continuations.  It
seems that CL attempts to be inclusive of programming techniques and
paradigms; it does not seem to exclude anything if there is a chance
that it might be useful.  Surely continuations must be useful in some
contexts, I used to think.  It is mentioned in half the books I own on
CL.  Unfortunately, I am attempting to learn CL on my own and lack an
experienced teacher to help show me the way.  However, at least these
books get accolades on c.l.l.

c.l.l has taught me the dogma regarding those scheming continuations.
I know that there is something regarding the interaction of
UNWIND-PROTECT and continuations but I haven't bothered looking for
Kent Pitman's paper on the subject just yet.  I'm willing to accept
the conventional wisdom on the subject for the moment and I'll look
into the details when I get more time.  However, I still have these
lingering doubts from time to time, especially when I half-remember
that if one had a sufficiently intelligent code walker, one could
convert any CL code into CPS style and so add fully supported
continuations to CL after the fact.  Especially when I see something
like the essay "ConS/Lisp--A MOP-Based Non-Deterministic Lisp" in the
ILC 2002 proceedings which, if I understand it correctly, describes an
implementation of just this technique.  But then I think that the ex
post facto CPS code would run into the same problems with
UNWIND-PROTECT, whatever they are, just as would an attempt to
introduce de facto continuations into CL.  But I try not to think
about it too much because I have lots of actual CL to learn and I'm
not planning on implementing Prologue in CL anytime soon, as this
seems to be continuations' main reason for being <smile>.
From: Gorbag
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <97J1c.733$K6.204@bos-service2.ext.raytheon.com>
"Damien Kick" <······@email.mot.com> wrote in message
···················@email.mot.com...
>  But I try not to think
> about it too much because I have lots of actual CL to learn and I'm
> not planning on implementing Prologue in CL anytime soon, as this
> seems to be continuations' main reason for being <smile>.

Take a look at Screamer, by Siskind.

http://www.ece.purdue.edu/~qobi/software.html
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87n07zhzn2.fsf@thalassa.informatimago.com>
Dave Roberts <·····@re-move.droberts.com> writes:

> Erann Gat wrote:
> 
> > In article <························@attbi_s01>, Dave Roberts
> > <·····@re-move.droberts.com> wrote:
> >> Yes, but you *could* cure that with mutexs and such.
> > 
> > Not if you want to run these two threads in parallel on a multiprocessor
> > you can't.
> 
> ?? Why not? Every other threading system does this all the time (C, Java,
> etc.). No issues. I just need a simple set of mutex primitives to keep the
> threads from access the same state at the same time and then I'm fine.
> Whether on single or multiple processors makes no difference. I'm sure you
> know this, so maybe I'm misunderstand what you're saying.

Given the use of special  variables in COMMON-LISP, it would be really
impratical to have to use mutexes around them.

For example,  since Lisp has (very)  big integers, a  process may well
spend ten  minutes to output such a  number, that is it  would have to
lock *print-base*  for ten minutes! Or taking  *read-base*, you'd need
to lock it  out while reading a whole file: no  more reading two files
in parallel.


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Gareth McCaughan
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <878yji8zpb.fsf@g.mccaughan.ntlworld.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Given the use of special  variables in COMMON-LISP, it would be really
> impratical to have to use mutexes around them.
> 
> For example,  since Lisp has (very)  big integers, a  process may well
> spend ten  minutes to output such a  number, that is it  would have to
> lock *print-base*  for ten minutes! Or taking  *read-base*, you'd need
> to lock it  out while reading a whole file: no  more reading two files
> in parallel.

Why would you have to lock *print-base* for 10 minutes? Why can't
the implementation's code look something like

    (defun write-integer (n stream)
      (let ((base *print-base*))
        ...))

?

-- 
Gareth McCaughan
.sig under construc
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hclUb.225678$xy6.1156798@attbi_s02>
Gareth McCaughan wrote:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
>> Given the use of special  variables in COMMON-LISP, it would be really
>> impratical to have to use mutexes around them.
>> 
>> For example,  since Lisp has (very)  big integers, a  process may well
>> spend ten  minutes to output such a  number, that is it  would have to
>> lock *print-base*  for ten minutes! Or taking  *read-base*, you'd need
>> to lock it  out while reading a whole file: no  more reading two files
>> in parallel.
> 
> Why would you have to lock *print-base* for 10 minutes? Why can't
> the implementation's code look something like
> 
>     (defun write-integer (n stream)
>       (let ((base *print-base*))
>         ...))
> 
> ?
> 

Exactly. That's precisely what you'd do. You'd lock or a *very* short
period, make a local copy if you needed it for longer than that, and go on
your way...
From: Brian Downing
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <4enUb.228753$na.366111@attbi_s04>
In article <························@attbi_s02>,
Dave Roberts  <·····@re-move.droberts.com> wrote:
> > Why would you have to lock *print-base* for 10 minutes? Why can't
> > the implementation's code look something like
> > 
> >     (defun write-integer (n stream)
> >       (let ((base *print-base*))
> >         ...))
> 
> Exactly. That's precisely what you'd do. You'd lock or a *very* short
> period, make a local copy if you needed it for longer than that, and go on
> your way...

Right.  But if you properly implement thread-safe dynamic scoping ONCE,
you don't have to do silly mutex/copying tricks like the above EVERY
TIME you want to use or set a variable.

Seems pretty good then, doesn't it?

http://c2.com/cgi/wiki?OnceAndOnlyOnce

(Besides, what if (as is the case with dynamic scope) I want all the
functions that get called from write-integer to see the new
*print-base*?  How do I do that without locking the whole time?  The
answer is thread-specific data, which is exactly one way you can
implement a threaded CL's dynamic scoping.)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <squUb.98894$U%5.489037@attbi_s03>
Brian Downing wrote:

> In article <························@attbi_s02>,
> Dave Roberts  <·····@re-move.droberts.com> wrote:
>> > Why would you have to lock *print-base* for 10 minutes? Why can't
>> > the implementation's code look something like
>> > 
>> >     (defun write-integer (n stream)
>> >       (let ((base *print-base*))
>> >         ...))
>> 
>> Exactly. That's precisely what you'd do. You'd lock or a *very* short
>> period, make a local copy if you needed it for longer than that, and go
>> on your way...
> 
> Right.  But if you properly implement thread-safe dynamic scoping ONCE,
> you don't have to do silly mutex/copying tricks like the above EVERY
> TIME you want to use or set a variable.
> 
> Seems pretty good then, doesn't it?
> 
> http://c2.com/cgi/wiki?OnceAndOnlyOnce
> 
> (Besides, what if (as is the case with dynamic scope) I want all the
> functions that get called from write-integer to see the new
> *print-base*?  How do I do that without locking the whole time?  The
> answer is thread-specific data, which is exactly one way you can
> implement a threaded CL's dynamic scoping.)

Again, you're taking a worst case on one side and arguing it from there.

I could just as easily answer, "What if you wanted that bignum to be shared
by 100 threads at the same time, with multiple of them both altering its
value and some of them printing it?" We can all craft scenarios that fit a
particular implementation optimization better.

So, I'll say it again: There is no one way that is right in the abstract.
Yes, if you want to preserve dynamic variable semantics, you HAVE to make
things thread-local. That's just the way it has to work. If you don't care
about that property, though, and just want things to be global values,
shared by all threads, you could make other choices. Whether you choose to
or not is a different issue. I get the feeling there that many Lispers
would choose to preserve the dynamic nature of globals. That's fine. But
realize that you'll have to still synchronize somewhere, otherwise you
won't have threads sharing any state.

-- Dave
From: Daniel Barlow
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ekt92zwq.fsf@noetbook.telent.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> I could just as easily answer, "What if you wanted that bignum to be shared
> by 100 threads at the same time, with multiple of them both altering its
> value and some of them printing it?" 

Ignoring for the moment that AFAIK you can't change the value of a
number anyway, then you use SETF instead of LET.  How often do you
need to be told this before you can accept that there is already a
perfectly good way to share state between threads and we don't need to
have LET duplicate it?


-dan

-- 
"please make sure that the person is your friend before you confirm"
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <rBEUb.235227$na.382206@attbi_s04>
Daniel Barlow wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> I could just as easily answer, "What if you wanted that bignum to be
>> shared by 100 threads at the same time, with multiple of them both
>> altering its value and some of them printing it?"
> 
> Ignoring for the moment that AFAIK you can't change the value of a
> number anyway, then you use SETF instead of LET.  How often do you
> need to be told this before you can accept that there is already a
> perfectly good way to share state between threads and we don't need to
> have LET duplicate it?

You only have to tell me once, but you have to let me read the posting
before you jump in and tell me again. It's only fair... ;-) My work
schedule only allows me to debate on nights and weekends.

-- Dave
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <mblUb.95437$U%5.483865@attbi_s03>
Pascal Bourguignon wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> Erann Gat wrote:
>> 
>> > In article <························@attbi_s01>, Dave Roberts
>> > <·····@re-move.droberts.com> wrote:
>> >> Yes, but you *could* cure that with mutexs and such.
>> > 
>> > Not if you want to run these two threads in parallel on a
>> > multiprocessor you can't.
>> 
>> ?? Why not? Every other threading system does this all the time (C, Java,
>> etc.). No issues. I just need a simple set of mutex primitives to keep
>> the threads from access the same state at the same time and then I'm
>> fine. Whether on single or multiple processors makes no difference. I'm
>> sure you know this, so maybe I'm misunderstand what you're saying.
> 
> Given the use of special  variables in COMMON-LISP, it would be really
> impratical to have to use mutexes around them.
> 
> For example,  since Lisp has (very)  big integers, a  process may well
> spend ten  minutes to output such a  number, that is it  would have to
> lock *print-base*  for ten minutes! Or taking  *read-base*, you'd need
> to lock it  out while reading a whole file: no  more reading two files
> in parallel.

Okay, but there is nothing special about Lisp in this respect. Any C or Java
program that deals with bignums would face the same issues, even if it took
more code to play with those bignums. If that's really a problem, a C or
Java program would just make the bignum a thread-local data item and you
would then not synchronize. This issue then becomes whether you can do
that. The fact is, state either wants to be shared between threads or it
doesn't. Obviously, the more it doesn't, the better it is for the speed of
the computation because you and use thread-local variables and introduce no
synchronization. Some state *does* want to be shared, however, and in that
case, you have no choice but to synchronize. Both situations arise. It
seems like people are taking a worst-case scenario and then arguing that
things *must* be done a certain way to handle that scenario. I'm just
arguing that many other systems (this transcends languages) have taken a
different approach and done quite well.

It really all depends on the semantics you want to create for multi-threaded
Lisp programs. If you basically want each thread to look like its own
totally separate world, equivalent to a single-threaded world, then
extending the system such that all globals are thread-local makes perfect
sense. That also brings a benefit of faster performance, but only when
those threads don't need to touch shared state, which they will invariably
have to do at some point. When they do, you'll need to synchronize; there
is no way around it.

-- Dave
From: Daniel Barlow
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87r7xb3qmf.fsf@noetbook.telent.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Erann Gat wrote:
>
>> In article <························@attbi_s01>, Dave Roberts
>> <·····@re-move.droberts.com> wrote:
>>> Yes, but you *could* cure that with mutexs and such.
>> 
>> Not if you want to run these two threads in parallel on a multiprocessor
>> you can't.
>
> ?? Why not? Every other threading system does this all the time (C, Java,
> etc.). No issues. I just need a simple set of mutex primitives to keep the

The key there is _in parallel_.  Mutexes serialise.  With per-thread
bindings you can have

(defvar *foo* 1)

;; thread a
(let ((*foo* 2))
  (do-stuff-with *foo*))

;; thread b
(let ((*foo* 3))
  (do-stuff-with *foo*))

and threads a and b can actually run at the same time and do something
reaonably predictable.  If you don't have per-thread bindings, I can't
think of any meaning to assign to this code more useful than
"undefined".  If you do have per-thread bindings, it gives you a very
natural interface to thread-local data - certainly better than all
that messing around with pthreads "keys"


-dan
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <O0lUb.95373$U%5.484016@attbi_s03>
Daniel Barlow wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> Erann Gat wrote:
>>
>>> In article <························@attbi_s01>, Dave Roberts
>>> <·····@re-move.droberts.com> wrote:
>>>> Yes, but you *could* cure that with mutexs and such.
>>> 
>>> Not if you want to run these two threads in parallel on a multiprocessor
>>> you can't.
>>
>> ?? Why not? Every other threading system does this all the time (C, Java,
>> etc.). No issues. I just need a simple set of mutex primitives to keep
>> the
> 
> The key there is _in parallel_.  Mutexes serialise.  With per-thread
> bindings you can have

Okay, fine. I wasn't reading "parallel" as strictly as you guys were
obviously intending. Obviously, you do serialize in the case I stated. But
equally obviously, this isn't a problem for many classes of interesting
problems. When it is, both C and Java also provide thread-local storage,
which is what you're basically advocating here.

> (defvar *foo* 1)
> 
> ;; thread a
> (let ((*foo* 2))
>   (do-stuff-with *foo*))
> 
> ;; thread b
> (let ((*foo* 3))
>   (do-stuff-with *foo*))
> 
> and threads a and b can actually run at the same time and do something
> reaonably predictable.  If you don't have per-thread bindings, I can't
> think of any meaning to assign to this code more useful than
> "undefined".  If you do have per-thread bindings, it gives you a very
> natural interface to thread-local data - certainly better than all
> that messing around with pthreads "keys"

Yes, it's syntactically much cleaner. No more powerful, however. I mean,
either you have thread-local state that doesn't have to be synchronized, or
you have true global state which does. Both are, in fact, useful,
regardless of implementation language.

-- Dave
From: Daniel Barlow
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <878yjh4nsa.fsf@noetbook.telent.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Yes, it's syntactically much cleaner. No more powerful, however. I mean,
> either you have thread-local state that doesn't have to be synchronized, or
> you have true global state which does. Both are, in fact, useful,
> regardless of implementation language.

And hey, guess what.  We _have_ both.  

- If you have a special variable and you assign to it with SETF, other
threads will see your change.  If you do this for state shared with
threads, you need some kind of locking regime, but any Lisp
implementation with threads will of necessity have suitable locking
primitives.

- If you have a special variable and you rebind it with LET, other
threads will not see your change: thus, thread-local storage, 
no locking needed => no serialisation => actual use of all the CPUs.

What you seem to be proposing as an alternative to this behaviour is 
to make rebinding special variables effectively an shorthand for
SETFing the global value and then setting it back again later.  
If you need this behaviour in a Lisp that has thread-local bindings,
you can emulate it with two SETFs and an UNWIND-PROTECT.  If you need
thread-local behaviour in a Lisp that doesn't have it, faking it is
going to be considerably messier and require changes to any legacy
code you might want to call to use your new thread-local-value
accessors instead of LET.

Technically you're correct that neither is more powerful, but
arguments from Turing equivalence leave me cold.  Thread-local
access is a hell of a lot more expressive.


-dan

-- 
"please make sure that the person is your friend before you confirm"
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <fyEUb.102126$U%5.519464@attbi_s03>
Daniel Barlow wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> Yes, it's syntactically much cleaner. No more powerful, however. I mean,
>> either you have thread-local state that doesn't have to be synchronized,
>> or you have true global state which does. Both are, in fact, useful,
>> regardless of implementation language.
> 
> And hey, guess what.  We _have_ both.

Okay, cool. ;-) That works for me. Again, I wasn't arguing particularly for
a position, just for the existence of an alternative way of doing things.

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0402041637350001@192.168.1.51>
In article <······················@attbi_s03>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Erann Gat wrote:
> 
> > In article <························@attbi_s01>, Dave Roberts
> > <·····@re-move.droberts.com> wrote:
> >> Yes, but you *could* cure that with mutexs and such.
> > 
> > Not if you want to run these two threads in parallel on a multiprocessor
> > you can't.
> 
> ?? Why not?

Because a binding can only have one value at a time.

> Every other threading system does this all the time (C, Java,
> etc.). No issues.

You are mistaken.

> I just need a simple set of mutex primitives to keep the
> threads from access the same state at the same time and then I'm fine.
> Whether on single or multiple processors makes no difference. I'm sure you
> know this, so maybe I'm misunderstand what you're saying.

No, you are understanding what I am saying, but you are badly mistaken
when you say that single or multiple processors makes no difference.  Yes,
you can "solve" the problem using mutexes, but if you do you will defeat
the whole purpose of having a multiprocessor, which is to speed things
up.  It's rather like saying that you can "solve" the problem of too much
adverse torque from a powerful engine in a car by removing half the spark
plugs.

> > Yes and no.  Strictly speaking it is not possible to create a global
> > binding for a variable without also declaring it special.  In practice
> > most implementations do allow this.
> > 
> > But yes, there are three kinds of bindings: global, dynamic, and lexical.
> > Global bindings are visible across all threads.  Dynamic bindings are
> > visible only in the thread in which they were created.  And lexical
> > bindings are visible only in the lexical form in which they were created.
> 
> I thought that special = dynamic.

That's right.

> You say that global = special

Not in the excerpt that you quoted.

What I said was that on a strict reading of the standard it is not
possible to create a global binding for a symbol without also making that
symbol special (which is to say, to cause all bindings to that symbol to
be dynamic bindings), so on that same strict reading, global implies
special/dynamic.  But global and special are not necessarily the same
thing, they just happen to be in a Common Lisp that strictly adheres to
the standard.  Most implementations do allow you to create a global
binding to a symbol without declaring it special (by doing a top-level
setq without a corresponding defvar).

> Another question would also be, how do I create global/special/dynamic and
> any global/non-special variable. DEFVAR for the first, I suppose. How do I
> create a non-special global?

See above.  Also, read up on define-symbol-macro.

> Is the manifestation of the difference between a global and a dynamic
> variable really limited to when threads are there?

Yes.

> I mean, the SBCL example
> I used earlier where a top-level SETQ seems to create what I basically
> would consider a global variable, similar to C. Any LET form shadows it,
> but doesn't set it in the same way as a dynamic variable.

That's right, but that's not a manifestation of the difference between
global and dynamic.  It's a manifestation of the fact that SBCL allows you
to create a global and a lexical binding for the same symbol (which is
contrary to a strict reading of the standard).

> Also, I looked up in CLHS "global varable." It basically says "global =
> dynamic or constant." So, this says to me, there really isn't the
> equivalent of a non-constant global,

Of course there is.  Do you not understand the meaning of the word "or"?

I think your mistake is that you assume that dynamic/special (same thing)
is somehow mutually exclusive with non-constant global.  They aren't.

> Officially, at least, all globals are really dynamic, or they are
> constants.

That's right.

Keep in mind that the standard does not include the concept of threads, so
you have to take what it says with a small grain of salt when threads are
introduced.  When there is only one thread, dynamic and (non-constant)
global are (or can be safely considered to be) the same thing.  When
threads are introduced dynamic becomes a concept distinct from BUT
COMPATIBLE WITH (non-constant) global.

E.
From: Bulent Murtezaoglu
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ekta720u.fsf@cubx.internal>
>>>>> "EG" == Erann Gat <·········@jpl.nasa.gov> writes:
[...]
    DR> ... Is the manifestation of the difference between a global and a
    DR> dynamic variable really limited to when threads are there?

    EG> Yes. [...]

Am I missing something here?  

CL-USER 39 > (defvar *global* :top-binding)
*GLOBAL*

CL-USER 40 > (defun fun1 () (let ((*global* :bound-in-fun1)) (fun2)))
FUN1

CL-USER 41 > (defun fun2 () (format t "*global* is ~a" *global*)) 
FUN2

CL-USER 42 > (fun1)
*global* is BOUND-IN-FUN1
NIL

;; now let's simulate a lexical top level global

CL-USER 45 > (let ((*global2* :top-binding))
  (defun fun1 () (let ((*global2* :bound-in-fun1)) (fun2)))
  (defun fun2 () (format t "*global2* is ~a" *global2*))
  (fun1))

*global2* is TOP-BINDING
NIL

It seems I can tell??

cheers,

BM
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0402042232100001@192.168.1.51>
In article <··············@cubx.internal>, Bulent Murtezaoglu <··@acm.org>
wrote:

> >>>>> "EG" == Erann Gat <·········@jpl.nasa.gov> writes:
> [...]
>     DR> ... Is the manifestation of the difference between a global and a
>     DR> dynamic variable really limited to when threads are there?
> 
>     EG> Yes. [...]
> 
> Am I missing something here?  

One of us is.  I'm not sure if it's you or me.

> 
> CL-USER 39 > (defvar *global* :top-binding)
> *GLOBAL*
> 
> CL-USER 40 > (defun fun1 () (let ((*global* :bound-in-fun1)) (fun2)))
> FUN1
> 
> CL-USER 41 > (defun fun2 () (format t "*global* is ~a" *global*)) 
> FUN2
> 
> CL-USER 42 > (fun1)
> *global* is BOUND-IN-FUN1
> NIL
> 
> ;; now let's simulate a lexical top level global
> 
> CL-USER 45 > (let ((*global2* :top-binding))
>   (defun fun1 () (let ((*global2* :bound-in-fun1)) (fun2)))
>   (defun fun2 () (format t "*global2* is ~a" *global2*))
>   (fun1))
> 
> *global2* is TOP-BINDING
> NIL
> 
> It seems I can tell??

Tell what?  A "simulated lexical top level global" is just that --
sumualted.  It's not a global.

(A better way to "simulate" top-level lexical globals by the way is with
symbol macros.)

Part of the problem may be that the term "global" is used in two different
ways.  One is the way in which is it defined by the standard, and the
other is the way it is used in common usage.  They are not the same.

E.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <rXkUb.178434$sv6.940233@attbi_s52>
Bulent Murtezaoglu wrote:

>>>>>> "EG" == Erann Gat <·········@jpl.nasa.gov> writes:
> [...]
>     DR> ... Is the manifestation of the difference between a global and a
>     DR> dynamic variable really limited to when threads are there?
> 
>     EG> Yes. [...]
> 
> Am I missing something here?
> 
> CL-USER 39 > (defvar *global* :top-binding)
> *GLOBAL*
> 
> CL-USER 40 > (defun fun1 () (let ((*global* :bound-in-fun1)) (fun2)))
> FUN1
> 
> CL-USER 41 > (defun fun2 () (format t "*global* is ~a" *global*))
> FUN2
> 
> CL-USER 42 > (fun1)
> *global* is BOUND-IN-FUN1
> NIL
> 
> ;; now let's simulate a lexical top level global
> 
> CL-USER 45 > (let ((*global2* :top-binding))
>   (defun fun1 () (let ((*global2* :bound-in-fun1)) (fun2)))
>   (defun fun2 () (format t "*global2* is ~a" *global2*))
>   (fun1))
> 
> *global2* is TOP-BINDING
> NIL
> 
> It seems I can tell??

Right. That was exactly my point! You don't need threads to see a difference
between these behaviors.

-- Dave
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <OVkUb.178422$sv6.939765@attbi_s52>
Erann Gat wrote:

> In article <······················@attbi_s03>, Dave Roberts
> <·····@re-move.droberts.com> wrote:
>> Every other threading system does this all the time (C, Java,
>> etc.). No issues.
> 
> You are mistaken.

Mistaken how? Every other threading system I have used does exactly this for
state shared between multiple threads. I have used them quite successfully,
so if I'm too mistaken, I don't get it. ;-) We must be having a semantic or
terminology difference. Now, you can also have thread-local variables, too.
If that's the behavior you want, that's fine.

>> I just need a simple set of mutex primitives to keep the
>> threads from access the same state at the same time and then I'm fine.
>> Whether on single or multiple processors makes no difference. I'm sure
>> you know this, so maybe I'm misunderstand what you're saying.
> 
> No, you are understanding what I am saying, but you are badly mistaken
> when you say that single or multiple processors makes no difference.  Yes,
> you can "solve" the problem using mutexes, but if you do you will defeat
> the whole purpose of having a multiprocessor, which is to speed things
> up.  It's rather like saying that you can "solve" the problem of too much
> adverse torque from a powerful engine in a car by removing half the spark
> plugs.

Well, I think you're now starting to lay out a whole set of unstated
assumptions. Sure, if you want each processor to do as little
synchronization as possible to ensure the highest levels of performance,
then you need state kept local to each thread. But that's not what I said.
I said there was not a *requirement* that this needs to be the model. You
can (it is done all the time in Java and C) use mutexes to deal with global
state. Both Java and C also support thread-local state, too, if you can
break your problem up that way. Note that many times that is distinctly
what you do *not* want, however, and you actually require access to state
shared across multiple threads. When that occurs, you have no choice by to
sychronize, whether in Lisp, Java, or C. Again, pick your model according
to your objectives. There is no magic here. Every language plays by the
same laws of physics.

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0402042242190001@192.168.1.51>
In article <·······················@attbi_s52>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Erann Gat wrote:
> 
> > In article <······················@attbi_s03>, Dave Roberts
> > <·····@re-move.droberts.com> wrote:
> >> Every other threading system does this all the time (C, Java,
> >> etc.). No issues.
> > 
> > You are mistaken.
> 
> Mistaken how?

You are mistaken in your claim that there are "no issues."

> Every other threading system I have used does exactly this for
> state shared between multiple threads. I have used them quite successfully,
> so if I'm too mistaken, I don't get it. ;-) We must be having a semantic or
> terminology difference.

Possibly.  But just because you have not encountered (or noticed) the
issues does not mean they do not exist.

> Now, you can also have thread-local variables, too.
> If that's the behavior you want, that's fine.

It's not a question of what I want.  Thread-local is the only behavior
that makes sense for dynamic binding.

> 
> >> I just need a simple set of mutex primitives to keep the
> >> threads from access the same state at the same time and then I'm fine.
> >> Whether on single or multiple processors makes no difference. I'm sure
> >> you know this, so maybe I'm misunderstand what you're saying.
> > 
> > No, you are understanding what I am saying, but you are badly mistaken
> > when you say that single or multiple processors makes no difference.  Yes,
> > you can "solve" the problem using mutexes, but if you do you will defeat
> > the whole purpose of having a multiprocessor, which is to speed things
> > up.  It's rather like saying that you can "solve" the problem of too much
> > adverse torque from a powerful engine in a car by removing half the spark
> > plugs.
> 
> Well, I think you're now starting to lay out a whole set of unstated
> assumptions. Sure, if you want each processor to do as little
> synchronization as possible to ensure the highest levels of performance,
> then you need state kept local to each thread. But that's not what I said.
> I said there was not a *requirement* that this needs to be the model. You
> can (it is done all the time in Java and C) use mutexes to deal with global
> state.

Of course you can.  You can also take out half the spark plugs to deal
with adverse torque in a powerful engine.

> Both Java and C also support thread-local state, too, if you can
> break your problem up that way. Note that many times that is distinctly
> what you do *not* want, however, and you actually require access to state
> shared across multiple threads.

That's true, but it has nothing to do with the topic at hand, which is
dynamic bindings.

I'll refer you back to some advice you got early on in this discussion:
stop trying to understand Lisp in terms of C.  Just try to understand it
on its own terms.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hdy58pjz.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

> Thread-local is the only behavior that makes sense for dynamic binding.

Not necessarily.  In the default case, yes --- if thread A binds
*print-base* to 8 then thread B should not see the change.  If B
subsequently binds it to 16, A should not see the change.

But suppose I wrote this:

(defun foo (thunk)
  (let ((*print-base* 16))
    (synchronize (process-run-function thunk))))

It may make sense for this process and the spawned process to share
the dynamic binding of *print-base*.


-- 
~jrm
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0502040956240001@k-137-79-50-101.jpl.nasa.gov>
In article <············@comcast.net>, Joe Marshall
<·············@comcast.net> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > Thread-local is the only behavior that makes sense for dynamic binding.
> 
> Not necessarily.  In the default case, yes --- if thread A binds
> *print-base* to 8 then thread B should not see the change.  If B
> subsequently binds it to 16, A should not see the change.
> 
> But suppose I wrote this:
> 
> (defun foo (thunk)
>   (let ((*print-base* 16))
>     (synchronize (process-run-function thunk))))
> 
> It may make sense for this process and the spawned process to share
> the dynamic binding of *print-base*.

I don't think so.

I don't know what SYNCHRONIZE is supposed to do, but I assume it waits
until the process finishes.  In that case, if you want thunk to share
foo's dynamic bindings you would just call thunk.  There is no point in
spawning a process.

If SYNCHRONIZE does something other than wait for the spawned process to
finish then you get unpredictable behavior, which I take as axiomatically
undesirable.

So I don't see any circumstances under which it would be desirable for a
spawned process to share the parent's dynamic bindings.  It might be
desirable for the spawned process to get a *copy* of any dynamic bindings
in the parent at the time the process is created, but to share the same
bindings makes no sense.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ad3x764i.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

> So I don't see any circumstances under which it would be desirable for a
> spawned process to share the parent's dynamic bindings.  

The *default* circumstance is that the child process shares the
parent's binding:  they both use the global binding.  Are you
suggesting that *all* special variables ought to be unshared on all threads?

> It might be desirable for the spawned process to get a *copy* of any
> dynamic bindings in the parent at the time the process is created,
> but to share the same bindings makes no sense.

There is, unfortunately, no mechanism to enumerate the current set of
dynamically bound variables.

-- 
~jrm
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0502041023540001@k-137-79-50-101.jpl.nasa.gov>
In article <············@comcast.net>, Joe Marshall
<·············@comcast.net> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > So I don't see any circumstances under which it would be desirable for a
> > spawned process to share the parent's dynamic bindings.  
> 
> The *default* circumstance is that the child process shares the
> parent's binding:  they both use the global binding.

That is a non-sensical statement.

The default behavior (at least in MCL) is for spawned processes to see the
global bindings of special variables.  But it makes no sense to call these
"the parent's binding".  Global bindings are, well, global.  They do not
belong to any particular thread.

> Are you
> suggesting that *all* special variables ought to be unshared on all threads?

No, of course not.

The current de facto standard seems to be that newly created threads have
no dynamic bindings.  What I am saying is that IF you wanted to change
that model, then the only possible change that makes any sense at all is
for spawned processes to inherit copies of the dynamic bindings that
existed in the parent at the time the process was spawned.

I am NOT taking a position on whether this would be a desirable change or
not.  All I am saying is that these are the only two reasonable
possibilities.

> > It might be desirable for the spawned process to get a *copy* of any
> > dynamic bindings in the parent at the time the process is created,
> > but to share the same bindings makes no sense.
> 
> There is, unfortunately, no mechanism to enumerate the current set of
> dynamically bound variables.

Nothing prevents this from being added as an extension, just as anything
involving threads necessarily is.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <1xp96ll3.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@comcast.net>, Joe Marshall
> <·············@comcast.net> wrote:
>
>> ·········@jpl.nasa.gov (Erann Gat) writes:
>> 
>> > So I don't see any circumstances under which it would be desirable for a
>> > spawned process to share the parent's dynamic bindings.  
>> 
>> The *default* circumstance is that the child process shares the
>> parent's binding:  they both use the global binding.
>
> That is a non-sensical statement.

Not at all.  If a special variable is assigned a global value, and no
process shadows it with a dynamic binding, then assignments to the
variable are seen by all processes.

> What I am saying is that IF you wanted to change
> that model, then the only possible change that makes any sense at all is
> for spawned processes to inherit copies of the dynamic bindings that
> existed in the parent at the time the process was spawned.
>
> I am NOT taking a position on whether this would be a desirable change or
> not.  All I am saying is that these are the only two reasonable
> possibilities.

I understand that.  I'm pointing out another possibility that is
reasonable for *some* circumstances.  

The current model allows for two behaviors:  assignment to a variable
being seen by all processes, or assignment to a variable being seen by
exactly one process.  There are circumstances where you may desire a
*group* of related processes to share a `global' binding where each
process assigns to the variable and all processes in the group see the
change, but processes *outside* the group do not see this binding.
The model is somewhat esoteric, but it is provided by the Lisp machine
through use of EVCPs (external value cell pointers).  As far as I
know, however, Allegro and Lispworks do not implement this behavior.

-- 
~jrm
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0502042159230001@192.168.1.51>
In article <············@comcast.net>, Joe Marshall
<·············@comcast.net> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > In article <············@comcast.net>, Joe Marshall
> > <·············@comcast.net> wrote:
> >
> >> ·········@jpl.nasa.gov (Erann Gat) writes:
> >> 
> >> > So I don't see any circumstances under which it would be desirable for a
> >> > spawned process to share the parent's dynamic bindings.  
> >> 
> >> The *default* circumstance is that the child process shares the
> >> parent's binding:  they both use the global binding.
> >
> > That is a non-sensical statement.
> 
> Not at all.

The non-sensical part is referring to the global binding as "the parent's
binding."

> If a special variable is assigned a global value, and no
> process shadows it with a dynamic binding, then assignments to the
> variable are seen by all processes.

Yes, that true.  But that's just because if there are no dynamic bindings
then the global binding is all there is.  This is true regardless of how
processes are spawned.

> The current model allows for two behaviors:  assignment to a variable
> being seen by all processes, or assignment to a variable being seen by
> exactly one process.  There are circumstances where you may desire a
> *group* of related processes to share a `global' binding where each
> process assigns to the variable and all processes in the group see the
> change, but processes *outside* the group do not see this binding.

Yes, but then you don't want dynamic scope because it necessarily results
in unpredictable behavior.  What you want in this case is a shared lexical
binding.

> The model is somewhat esoteric, but it is provided by the Lisp machine
> through use of EVCPs (external value cell pointers).  As far as I
> know, however, Allegro and Lispworks do not implement this behavior.

I'd be surprised if that's really true.  Or maybe I'm missing something?

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hdy49s9z.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> The non-sensical part is referring to the global binding as "the parent's
> binding."

*Someone* gave it an initial value.  At some point in time, one
individual process created and initialized that binding.

>> The current model allows for two behaviors:  assignment to a variable
>> being seen by all processes, or assignment to a variable being seen by
>> exactly one process.  There are circumstances where you may desire a
>> *group* of related processes to share a `global' binding where each
>> process assigns to the variable and all processes in the group see the
>> change, but processes *outside* the group do not see this binding.
>
> Yes, but then you don't want dynamic scope because it necessarily results
> in unpredictable behavior.  What you want in this case is a shared lexical
> binding.

Sort of.  The problem is that you cannot dynamically bind lexical
variables.  We get either the desired sharing behavior, or the ability
to temporarily override the shared value in a single process, but not
both.

Let me propose a simple scenario where this would be useful.  

A `server' is an object with multple threads.  A `monitor' thread
serially fields requests and calls upon a `worker' thread from a
thread pool to process the request.  The worker handles all the work
for the client.  When it is done, it returns a result to the client
and joins the thread pool.  The monitor thread has an additional task:
when it exits, it waits for the currently running workers to complete
and then reaps all the threads in the pool.  The threads in the pool
are strictly slaves to the monitor.

Since time is of the essence, we create a variable:

(defvar *worker-thread-timeout* 10
   "Time in seconds for a worker thread to finish.  If a result is not
 available within this limit, a timeout is raised within the worker
 process.")

It is global because each worker thread will need to see the value.

Now it is the case that *one particular* request is a long-running one
that takes more than the default 10 second timeout.  The code for
handling that request overrides the default timeout by binding it to a
new value:

   (defconstant +long-timeout+ 120
      "Time necessary for long request.")

   (defun long-request (args)
     (let ((*worker-thread-timeout* +long-timeout+))
       ...process the request....))

Also, there is a server parameter request that allows you to change
the default timeout on the server.

This all works fine, but then one day someone tries to bring up two
servers (perhaps on different ports, but within the same process).
The *worker-thread-timeout* cannot be truly global because it should
not be shared between the two servers.  But it cannot be lexical
because some of the request handlers wish to rebind it.  And it cannot
be dynamic because the server parameter request command needs to make
the change visible to multiple processes.

We need a dynamically bindable lexical value.

>> The model is somewhat esoteric, but it is provided by the Lisp machine
>> through use of EVCPs (external value cell pointers).  As far as I
>> know, however, Allegro and Lispworks do not implement this behavior.
>
> I'd be surprised if that's really true.  Or maybe I'm missing something?

Surprise!

It could be that Allegro 6.2 could emulate this behavior using its
wide binding scheme, but I don't know.  In any case, this would be
a relatively new addition.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0602040912060001@192.168.1.51>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > The non-sensical part is referring to the global binding as "the parent's
> > binding."
> 
> *Someone* gave it an initial value.  At some point in time, one
> individual process created and initialized that binding.

Yes, but that could have been any thread, including a child process that
no longer even exists!  A global binding is not (necessarily) "the
parent's binding" any more than it is any other thread's binding.

> Let me propose a simple scenario where this would be useful.  
> 
> A `server' is an object with multple threads.  A `monitor' thread
> serially fields requests and calls upon a `worker' thread from a
> thread pool to process the request.  The worker handles all the work
> for the client.  When it is done, it returns a result to the client
> and joins the thread pool.  The monitor thread has an additional task:
> when it exits, it waits for the currently running workers to complete
> and then reaps all the threads in the pool.  The threads in the pool
> are strictly slaves to the monitor.
> 
> Since time is of the essence, we create a variable:
> 
> (defvar *worker-thread-timeout* 10
>    "Time in seconds for a worker thread to finish.  If a result is not
>  available within this limit, a timeout is raised within the worker
>  process.")
> 
> It is global because each worker thread will need to see the value.

It would only have to be a global binding if every thread needed to be
able to *change* the value and have every other thread see the change, so
this scenario is already a straw man.  But I'm willing to suspend my
disbelief for a moment.


> Now it is the case that *one particular* request is a long-running one
> that takes more than the default 10 second timeout.  The code for
> handling that request overrides the default timeout by binding it to a
> new value:
> 
>    (defconstant +long-timeout+ 120
>       "Time necessary for long request.")
> 
>    (defun long-request (args)
>      (let ((*worker-thread-timeout* +long-timeout+))
>        ...process the request....))
> 
> Also, there is a server parameter request that allows you to change
> the default timeout on the server.
> 
> This all works fine, but then one day someone tries to bring up two
> servers (perhaps on different ports, but within the same process).
> The *worker-thread-timeout* cannot be truly global because it should
> not be shared between the two servers.  But it cannot be lexical
> because some of the request handlers wish to rebind it.  And it cannot
> be dynamic because the server parameter request command needs to make
> the change visible to multiple processes.
> 
> We need a dynamically bindable lexical value.

No you don't.  This scenario can be easily implemented using
SYMBOL-VALUE-IN-PROCESS and per-thread dynamic binding:

(defun process-request ()
  (let ( (*worker-thread-timeout*
          (symbol-value-in-process
           (parent-process (current-process)) '*worker-thread-timeout)) )
    ...))

(defun monitor ()
  (let ( (*worker-thread-timeout* *worker-thread-timeout*) )
     (create-thread-pool)
     (wait-for-shutdown-request)
     (reap-threads)))

There are better ways to do this also that do not rely on
symbol-value-in-process (like passing the default value within a shared
mutable object as a parameter to every worker thread).  Furthermore, I
think that making this parameter be a timeout value is a red herring,
since most threading extensions provide with-timeout as a primitive, so in
reality you wouldn't need to rebind *worker-thread-timeout* at all.

> >> The model is somewhat esoteric, but it is provided by the Lisp machine
> >> through use of EVCPs (external value cell pointers).  As far as I
> >> know, however, Allegro and Lispworks do not implement this behavior.
> >
> > I'd be surprised if that's really true.  Or maybe I'm missing something?
> 
> Surprise!

What?  Is it my birthday or something?  ;-)

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <7jz0njq4.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

>> Since time is of the essence, we create a variable:
>> 
>> (defvar *worker-thread-timeout* 10
>>    "Time in seconds for a worker thread to finish.  If a result is not
>>  available within this limit, a timeout is raised within the worker
>>  process.")
>> 
>> It is global because each worker thread will need to see the value.
>
> It would only have to be a global binding if every thread needed to be
> able to *change* the value and have every other thread see the change, so
> this scenario is already a straw man.  But I'm willing to suspend my
> disbelief for a moment.

Good.  The reason is that *any* worker thread *does* need to change
the value if the user invokes the special `modify-timeout' function
from a client site.  An arbitrary thread is selected and that's where
the value will change.

>> Now it is the case that *one particular* request is a long-running one
>> that takes more than the default 10 second timeout.  The code for
>> handling that request overrides the default timeout by binding it to a
>> new value:
>> 
>>    (defconstant +long-timeout+ 120
>>       "Time necessary for long request.")
>> 
>>    (defun long-request (args)
>>      (let ((*worker-thread-timeout* +long-timeout+))
>>        ...process the request....))
>> 
>> Also, there is a server parameter request that allows you to change
>> the default timeout on the server.
>> 
>> This all works fine, but then one day someone tries to bring up two
>> servers (perhaps on different ports, but within the same process).
>> The *worker-thread-timeout* cannot be truly global because it should
>> not be shared between the two servers.  But it cannot be lexical
>> because some of the request handlers wish to rebind it.  And it cannot
>> be dynamic because the server parameter request command needs to make
>> the change visible to multiple processes.
>> 
>> We need a dynamically bindable lexical value.
>
> No you don't.  This scenario can be easily implemented using
> SYMBOL-VALUE-IN-PROCESS and per-thread dynamic binding:
>
> (defun process-request ()
>   (let ( (*worker-thread-timeout*
>           (symbol-value-in-process
>            (parent-process (current-process)) '*worker-thread-timeout)) )
>     ...))
>
> (defun monitor ()
>   (let ( (*worker-thread-timeout* *worker-thread-timeout*) )
>      (create-thread-pool)
>      (wait-for-shutdown-request)
>      (reap-threads)))
>
> There are better ways to do this also that do not rely on
> symbol-value-in-process (like passing the default value within a shared
> mutable object as a parameter to every worker thread).  

This version, unfortunately, does not have the behavior that changes
to the timeout are seen by all processes immediately.

> Furthermore, I think that making this parameter be a timeout value
> is a red herring, since most threading extensions provide
> with-timeout as a primitive, so in reality you wouldn't need to
> rebind *worker-thread-timeout* at all.

Fine.  Call the parameter `database open count' or something that
needs to be shared by all worker threads, possibly mutated by any
worker thread, dynamically shadowed in some worker threads, and not
shared by other servers.

>> >> The model is somewhat esoteric, but it is provided by the Lisp machine
>> >> through use of EVCPs (external value cell pointers).  As far as I
>> >> know, however, Allegro and Lispworks do not implement this behavior.
>> >
>> > I'd be surprised if that's really true.  Or maybe I'm missing something?
>> 
>> Surprise!
>
> What?  Is it my birthday or something?  ;-)

No, it's really true.  Lisp machines have EVCPs, Allegro and Lispworks
do not.  This allows you to create `dynamic closures' (a ZetaLisp
feature) which you cannot do in Allegro or Lispworks.  Dynamic
closures are a potential implementation of what I'm talking about.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0602041629120001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> >> Since time is of the essence, we create a variable:
> >> 
> >> (defvar *worker-thread-timeout* 10
> >>    "Time in seconds for a worker thread to finish.  If a result is not
> >>  available within this limit, a timeout is raised within the worker
> >>  process.")
> >> 
> >> It is global because each worker thread will need to see the value.
> >
> > It would only have to be a global binding if every thread needed to be
> > able to *change* the value and have every other thread see the change, so
> > this scenario is already a straw man.  But I'm willing to suspend my
> > disbelief for a moment.
> 
> Good.  The reason is that *any* worker thread *does* need to change
> the value if the user invokes the special `modify-timeout' function
> from a client site.  An arbitrary thread is selected and that's where
> the value will change.

Ah.

> > No you don't.  This scenario can be easily implemented using
> > SYMBOL-VALUE-IN-PROCESS and per-thread dynamic binding:
> >
> > (defun process-request ()
> >   (let ( (*worker-thread-timeout*
> >           (symbol-value-in-process
> >            (parent-process (current-process)) '*worker-thread-timeout)) )
> >     ...))
> >
> > (defun monitor ()
> >   (let ( (*worker-thread-timeout* *worker-thread-timeout*) )
> >      (create-thread-pool)
> >      (wait-for-shutdown-request)
> >      (reap-threads)))
> >
> > There are better ways to do this also that do not rely on
> > symbol-value-in-process (like passing the default value within a shared
> > mutable object as a parameter to every worker thread).  
> 
> This version, unfortunately, does not have the behavior that changes
> to the timeout are seen by all processes immediately.

(defun change-default-timeout (new-value) ; To be called in a worker thread
  (setf (symbol-value-in-process
         (parent-process (current-process)) '*worker-thread-timeout*))
        new-value))

Does that not do what you want?

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <n07v4rlo.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

>
> (defun change-default-timeout (new-value) ; To be called in a worker thread
>   (setf (symbol-value-in-process
>          (parent-process (current-process)) '*worker-thread-timeout*))
>         new-value))
>
> Does that not do what you want?

I'm not sure what that will do for the processes that have shadowed
the value of *worker-thread-timeout* with a new binding.

-- 
~jrm
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c01aod$4me$1@newsreader2.netcologne.de>
Joe Marshall wrote:

> No, it's really true.  Lisp machines have EVCPs, Allegro and Lispworks
> do not.  This allows you to create `dynamic closures' (a ZetaLisp
> feature) which you cannot do in Allegro or Lispworks.  Dynamic
> closures are a potential implementation of what I'm talking about.

This sounds very interesting. Do you happen to have a reference or a 
link at hand where this feature is described in more detail? Googling 
for "dynamic closures" or "ZetaLisp" doesn't help a lot.


Thanks,
Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c01b4d$5co$1@newsreader2.netcologne.de>
Pascal Costanza wrote:

> 
> Joe Marshall wrote:
> 
>> No, it's really true.  Lisp machines have EVCPs, Allegro and Lispworks
>> do not.  This allows you to create `dynamic closures' (a ZetaLisp
>> feature) which you cannot do in Allegro or Lispworks.  Dynamic
>> closures are a potential implementation of what I'm talking about.
> 
> This sounds very interesting. Do you happen to have a reference or a 
> link at hand where this feature is described in more detail? Googling 
> for "dynamic closures" or "ZetaLisp" doesn't help a lot.

Sorry. I have forgotten to check out groups.google.com. There's more 
information about it to be found there.

Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c01ckq$6rs$1@newsreader2.netcologne.de>
Pascal Costanza wrote:

> Pascal Costanza wrote:
> 
>>
>> Joe Marshall wrote:
>>
>>> No, it's really true.  Lisp machines have EVCPs, Allegro and Lispworks
>>> do not.  This allows you to create `dynamic closures' (a ZetaLisp
>>> feature) which you cannot do in Allegro or Lispworks.  Dynamic
>>> closures are a potential implementation of what I'm talking about.
>>
>>
>> This sounds very interesting. Do you happen to have a reference or a 
>> link at hand where this feature is described in more detail? Googling 
>> for "dynamic closures" or "ZetaLisp" doesn't help a lot.
> 
> Sorry. I have forgotten to check out groups.google.com. There's more 
> information about it to be found there.

Sorry again for posting so many times about this issue, but I have 
actually found some code at 
http://groups.google.com/groups?selm=1990Dec28.093020.17301%40Think.COM

(defun make-dynamic-closure (variables function)
   (let ((values (mapcar #'symbol-value variables)))
     #'(lambda ()
         (progv variables values
           (funcall function)))))


Is this what you are thinking about?


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <isij4rid.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Sorry again for posting so many times about this issue, but I have
> actually found some code at
> http://groups.google.com/groups?selm=1990Dec28.093020.17301%40Think.COM
>
> (defun make-dynamic-closure (variables function)
>    (let ((values (mapcar #'symbol-value variables)))
>      #'(lambda ()
>          (progv variables values
>            (funcall function)))))

It's an approximation.  (It doesn't preserve the sharing.)



-- 
~jrm
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c02g0q$qsq$1@newsreader2.netcologne.de>
Joe Marshall wrote:

> Pascal Costanza <········@web.de> writes:
> 
>>Sorry again for posting so many times about this issue, but I have
>>actually found some code at
>>http://groups.google.com/groups?selm=1990Dec28.093020.17301%40Think.COM
>>
>>(defun make-dynamic-closure (variables function)
>>   (let ((values (mapcar #'symbol-value variables)))
>>     #'(lambda ()
>>         (progv variables values
>>           (funcall function)))))
> 
> 
> It's an approximation.  (It doesn't preserve the sharing.)

Is this what you mean?

(defclass forward-cell ()
   ((parent :accessor parent :initarg :parent)
    (value :accessor value :initarg :value)))

(defmethod slot-unbound ((class t) (instance forward-cell) (slot-name 
(eql 'value)))
   (value (parent instance)))

(defmethod slot-unbound ((class t) (instance forward-cell) (slot-name 
(eql 'parent)))
   (error "Unbound forward cell ~A." instance))

(defmacro define-forward-cell (name &optional (initial-value nil 
initial-value-p))
   (let ((dynvar (make-symbol (format nil "*~A*" (symbol-name name)))))
     `(progn
        (setf (get ',name :forward-cell-symbol) ',dynvar)
        (defvar ,dynvar (make-instance 'forward-cell
                          ,@(when initial-value-p (list :value 
initial-value))))
        (define-symbol-macro ,name (value ,dynvar)))))

(defmacro with-captured-forward-cells (cells &body body)
   `(let ,(mapcar (lambda (cell)
                    (cond ((consp cell)
                           (let ((forward-cell-symbol (get (car cell) 
:forward-cell-symbol)))
                             `(,forward-cell-symbol
                               (make-instance 'forward-cell
                                 :parent ,forward-cell-symbol :value 
,(cadr cell)))))
                          ((symbolp cell)
                           (let ((forward-cell-symbol (get cell 
:forward-cell-symbol)))
                             `(,forward-cell-symbol
                               (make-instance 'forward-cell
                                 :parent ,forward-cell-symbol))))
                          (t (error "Wrong use of 
WITH-CAPTURED-FORWARD-CELLS."))))
                  cells)
      ,@body))



? (define-forward-cell test 5)
TEST
? (define-forward-cell foo)
FOO
? test
5
? foo
 > Error: Unbound forward cell #<FORWARD-CELL #x26B5786>.
 > While executing: #<STANDARD-METHOD SLOT-UNBOUND (T FORWARD-CELL (EQL 
PARENT))>
 > Type Command-. to abort.
See the Restarts� menu item for further choices.
1 >
Aborted
? (with-captured-forward-cells (test
                                 (foo 4711))
     (print test)
     (setf test 666)
     (print test)
     (print foo))

5
666
4711
4711
? test
5
? foo
 > Error: Unbound forward cell #<FORWARD-CELL #x26B5786>.
 > While executing: #<STANDARD-METHOD SLOT-UNBOUND (T FORWARD-CELL (EQL 
PARENT))>
 > Type Command-. to abort.
See the Restarts� menu item for further choices.
1 >
Aborted
?


It's harder to demonstrate the sharing of assignments to captured but 
unbound forward cells...

Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c03bjk$g8d$1@newsreader2.netcologne.de>
Pascal Costanza wrote:

> 
> Joe Marshall wrote:
> 
>> Pascal Costanza <········@web.de> writes:
>>
>>> Sorry again for posting so many times about this issue, but I have
>>> actually found some code at
>>> http://groups.google.com/groups?selm=1990Dec28.093020.17301%40Think.COM
>>>
>>> (defun make-dynamic-closure (variables function)
>>>   (let ((values (mapcar #'symbol-value variables)))
>>>     #'(lambda ()
>>>         (progv variables values
>>>           (funcall function)))))
>>
>>
>>
>> It's an approximation.  (It doesn't preserve the sharing.)
> 
> 
> Is this what you mean?
[...]

This part is still missing:

(defun make-dynamic-closure (cells function)
   (let ((values (mapcar (lambda (cell)
                           (symbol-value
                            (get cell :forward-cell-symbol)))
                         cells)))
     (lambda ()
       (progv cells values
         (funcall function)))))


But now I think I have got it...


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <y8rcjm9l.fsf@ccs.neu.edu>
Pascal Costanza <········@web.de> writes:

> This part is still missing:
>
> (defun make-dynamic-closure (cells function)
>    (let ((values (mapcar (lambda (cell)
>                            (symbol-value
>                             (get cell :forward-cell-symbol)))
>                          cells)))
>      (lambda ()
>        (progv cells values
>          (funcall function)))))
>
>
> But now I think I have got it...

The dynamic closure, after it is invoked, needs to preserve the values
that are assigned to the bound specials during the body.  Is that
happening here?  (I'm not exactly sure, but it looks as if you are
fetching the value from the forwarded cell.)
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c08o7k$qtd$1@newsreader2.netcologne.de>
Joe Marshall wrote:
> Pascal Costanza <········@web.de> writes:
> 
> 
>>This part is still missing:
>>
>>(defun make-dynamic-closure (cells function)
>>   (let ((values (mapcar (lambda (cell)
>>                           (symbol-value
>>                            (get cell :forward-cell-symbol)))
>>                         cells)))
>>     (lambda ()
>>       (progv cells values
>>         (funcall function)))))
>>
>>
>>But now I think I have got it...
> 
> 
> The dynamic closure, after it is invoked, needs to preserve the values
> that are assigned to the bound specials during the body.  Is that
> happening here?  (I'm not exactly sure, but it looks as if you are
> fetching the value from the forwarded cell.)

Thanks for your response!

However, now I am really confused. Your two previous comments sound to 
me as if a dynamic closure needs to preserve sharing but shouldn't. This 
doesn't make sense to me, so I am clearly missing something.

Let's see. Here is how I understand your example:


                   worker-1
                  /
          server-1
       	/        \
        /          worker-2
program
        \          worker-3
         \        /
          server-2
                  \
                   worker-4

You would like to be able to change a shared binding from within a 
worker thread that is bound in a server thread, but not in the global 
program thread.


Where do you want to use something like make-dynamic-closure in order to 
achieve this effect? When the program spawns a server thread, or when a 
server thread spawns a worker thread? (or both?)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <u11z90iy.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Thanks for your response!
>
> However, now I am really confused. Your two previous comments sound to
> me as if a dynamic closure needs to preserve sharing but
> shouldn't. This doesn't make sense to me, so I am clearly missing
> something.
>
> Let's see. Here is how I understand your example:
>
>
>                    worker-1
>                   /
>           server-1
>        	/        \
>         /          worker-2
> program
>         \          worker-3
>          \        /
>           server-2
>                   \
>                    worker-4
>
> You would like to be able to change a shared binding from within a
> worker thread that is bound in a server thread, but not in the global
> program thread.

Ok, under `normal' circumstances, a thread will share the top-level
binding of a special variable with all other threads.  Assignments
made by this thread are seen by other threads, and this thread will
see assignments made other threads.  If a thread wants to change the
value in a thread-local way, it simply binds the dynamic value and no
other thread sees it.

Now suppose that server-1 binds a dynamic variable.  This should make
the variable be local to server-1.  The worker threads `under'
server-1 should behave as if that were a global binding.  If worker-1
assigns to the variable, worker-2 will see the change (as will
server-1).  

However, worker-3 and worker-4 will *not* share the binding that
worker-1 and worker-2 see.  They will either share a global value (if
server-2 did nothing) or a binding local to the group (if server-2
dynamically bound the variable).

The goal here is that worker-1 and worker-2 do not need to know
whether server-1 is in fact the only server (and the variable is
`really' global) or whether server-1 is running in parallel with
another server (and the variable is only `global' to the group).

-- 
~jrm
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002041027560001@k-137-79-50-101.jpl.nasa.gov>
In article <············@comcast.net>, Joe Marshall
<·············@comcast.net> wrote:

> Pascal Costanza <········@web.de> writes:
> 
> > Thanks for your response!
> >
> > However, now I am really confused. Your two previous comments sound to
> > me as if a dynamic closure needs to preserve sharing but
> > shouldn't. This doesn't make sense to me, so I am clearly missing
> > something.
> >
> > Let's see. Here is how I understand your example:
> >
> >
> >                    worker-1
> >                   /
> >           server-1
> >               /        \
> >         /          worker-2
> > program
> >         \          worker-3
> >          \        /
> >           server-2
> >                   \
> >                    worker-4
> >
> > You would like to be able to change a shared binding from within a
> > worker thread that is bound in a server thread, but not in the global
> > program thread.
> 
> Ok, under `normal' circumstances, a thread will share the top-level
> binding of a special variable with all other threads.  Assignments
> made by this thread are seen by other threads, and this thread will
> see assignments made other threads.  If a thread wants to change the
> value in a thread-local way, it simply binds the dynamic value and no
> other thread sees it.
> 
> Now suppose that server-1 binds a dynamic variable.  This should make
> the variable be local to server-1.  The worker threads `under'
> server-1 should behave as if that were a global binding.  If worker-1
> assigns to the variable, worker-2 will see the change (as will
> server-1).  
> 
> However, worker-3 and worker-4 will *not* share the binding that
> worker-1 and worker-2 see.  They will either share a global value (if
> server-2 did nothing) or a binding local to the group (if server-2
> dynamically bound the variable).
> 
> The goal here is that worker-1 and worker-2 do not need to know
> whether server-1 is in fact the only server (and the variable is
> `really' global) or whether server-1 is running in parallel with
> another server (and the variable is only `global' to the group).

This model is at odds with the standard, which specifies that a dynamic
binding may not outlive the execution of the form that created it. 
Specifically, it specifies that a dynamic binding has dynamic extent,
which is defined as:

an extent whose duration is bounded by points of establishment and
disestablishment within the execution of a particular form.
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This leaves you with a problem in the following case:

(defun server-fn ()
  (let ( (*dynvar* ...) )
    (spawn-worker)
    ...))

According to the standard, the dynamic binding of *dynvar* becomes
undefined after server-fn returns.  So to make this work you'd have to
change the standard.

I really think you're better off using either a shared lexical binding or
explicit calls to symbol-value-in-process to implement the server-worker
scenario.

E.
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcv7jyu91f1.fsf@famine.OCF.Berkeley.EDU>
·········@jpl.nasa.gov (Erann Gat) writes:

> Specifically, it specifies that a dynamic binding has dynamic extent,
> which is defined as:
> 
> an extent whose duration is bounded by points of establishment and
> disestablishment within the execution of a particular form.
>                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> This leaves you with a problem in the following case:
> 
> (defun server-fn ()
>   (let ( (*dynvar* ...) )
>     (spawn-worker)
>     ...))
> 
> According to the standard, the dynamic binding of *dynvar* becomes
> undefined after server-fn returns.  So to make this work you'd have to
> change the standard.

Well, unless your threading model is disturbingly continuation-like,
and SPAWN-WORKER returns twice, once when the worker is spawned, and
again when the worker thread returns to that point.  While that would
be consistent, it also sounds remarkably like the worst way to do things.

> I really think you're better off using either a shared lexical binding or
> explicit calls to symbol-value-in-process to implement the server-worker
> scenario.

I agree wholeheartedly.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002041312020001@k-137-79-50-101.jpl.nasa.gov>
In article <···············@famine.OCF.Berkeley.EDU>,
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > Specifically, it specifies that a dynamic binding has dynamic extent,
> > which is defined as:
> > 
> > an extent whose duration is bounded by points of establishment and
> > disestablishment within the execution of a particular form.
> >                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > 
> > This leaves you with a problem in the following case:
> > 
> > (defun server-fn ()
> >   (let ( (*dynvar* ...) )
> >     (spawn-worker)
> >     ...))
> > 
> > According to the standard, the dynamic binding of *dynvar* becomes
> > undefined after server-fn returns.  So to make this work you'd have to
> > change the standard.
> 
> Well, unless your threading model is disturbingly continuation-like,
> and SPAWN-WORKER returns twice, once when the worker is spawned, and
> again when the worker thread returns to that point.  While that would
> be consistent,

I don't have time to dig into the details right now, but I'm pretty sure
that would also clash with the evaluation model as it's currently
defined.  The most likely spot to look for trouble if one were so inclined
would probably be unwind-protect.

> it also sounds remarkably like the worst way to do things.

We certainly agree on that.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <llnaabgs.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> This model is at odds with the standard, which specifies that a dynamic
> binding may not outlive the execution of the form that created it. 

Given that the standard doesn't specify what happens under a
multithreading extension, I don't see how it could be violated.

> This leaves you with a problem in the following case:
>
> (defun server-fn ()
>   (let ( (*dynvar* ...) )
>     (spawn-worker)
>     ...))
>
> According to the standard, the dynamic binding of *dynvar* becomes
> undefined after server-fn returns.  So to make this work you'd have to
> change the standard.

There are two solutions to this:  The intended one is that the server
function works more like this:

(defun server-fn ()
  (let ((*dynvar* ...))
    (unwind-protect
          (progn (spawn-workers)
                 (monitor-workers))
       (destroy-workers))))

Second, is simply to allow the other processes to continue to refer to
the shared, but hidden value.

> I really think you're better off using either a shared lexical binding or
> explicit calls to symbol-value-in-process to implement the server-worker
> scenario.

I agree, but suppose you wrote the server (without considering that
two servers may run in the same address space) and I tried to embed
it.  I cannot necessarily get at the internal logic of your server,
but if I can present the illusion that your server has sole owneship
of the dynamic context, then I can run two of them.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002041345390001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > This model is at odds with the standard, which specifies that a dynamic
> > binding may not outlive the execution of the form that created it. 
> 
> Given that the standard doesn't specify what happens under a
> multithreading extension, I don't see how it could be violated.

The standard specifies certain things (like unwind-protect) that are at
least on their face incompatible with certain models of threading (like
continuation-based models).


> > This leaves you with a problem in the following case:
> >
> > (defun server-fn ()
> >   (let ( (*dynvar* ...) )
> >     (spawn-worker)
> >     ...))
> >
> > According to the standard, the dynamic binding of *dynvar* becomes
> > undefined after server-fn returns.  So to make this work you'd have to
> > change the standard.
> 
> There are two solutions to this:  The intended one is that the server
> function works more like this:
> 
> (defun server-fn ()
>   (let ((*dynvar* ...))
>     (unwind-protect
>           (progn (spawn-workers)
>                  (monitor-workers))
>        (destroy-workers))))

Yes, but you can't count on programmers to enforce this discipline so you
have to specify what will happen when they don't -- even if that
specification is that the behavior is undefined.

> Second, is simply to allow the other processes to continue to refer to
> the shared, but hidden value.

But you can't do that (I claim) without modifying (or deciding to ignore)
(certain aspects of) the current standard.

> > I really think you're better off using either a shared lexical binding or
> > explicit calls to symbol-value-in-process to implement the server-worker
> > scenario.
> 
> I agree, but suppose you wrote the server (without considering that
> two servers may run in the same address space) and I tried to embed
> it.  I cannot necessarily get at the internal logic of your server,
> but if I can present the illusion that your server has sole owneship
> of the dynamic context, then I can run two of them.

That's a good point, but that seems to me to just be taking the position
that the whole concept of a global environment is a bad idea.  I do not
necessarily disagree with this, but the concept is woven rather deeply
into the CL standard.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ptclh9gj.fsf@ccs.neu.edu>
[jrm wrote a bunch of stuff]

·········@jpl.nasa.gov (Erann Gat) writes:

> That seems to me to just be taking the position that the whole
> concept of a global environment is a bad idea.  I do not necessarily
> disagree with this, but the concept is woven rather deeply into the
> CL standard.

I disagree with this assessment.  I think that a global environment is
fine, but when you have multiple processes, you may want multiple
global environments.  Each process would behave exactly as if there
were a global environment modulo the visible effects of side-effects
in other processes.  Binding of global variables would be invisible to
any other process.

-------

The popular multithreading model that you find in Lisp these days is a
descendent from the `stack group' model.  I believe that this
originated in Zetalisp on the Lisp Machine (I don't think MACLISP had
stack groups, but I could be mistaken).  A stack group in Zetalisp
consisted of several `pdls' (`push-down lists' aka stacks) --- the
control stack or `regular-pdl', the dynamic binding stack or
`special-pdl', and in later implementations a `bignum pdl' --- and the
associated necessary state.

At a `sequence break', the microcode would swap out the state of the
current stack-group and resume the state of a distinguished stack
group that was the `scheduler'.  The scheduler would find a runnable
process and arrange for that process to be swapped in until the next
sequence break.

This is a fairly low-level multitasking mechanism, and it is rather
crude.  It is sufficient for driving a mouse and a few `listener'
windows, but it is quite difficult to use this model for any sort of
user-level parallelism.

There have been other mechanisms for parallelism put forth.
Halstead's Multilisp was an early one.  It introduced `futures'.  A
`future' was a delayed evaluation that was spawned on a separate
thread.  The current thread would be given a `placeholder' for the
future value and proceed in parallel.  When the separate thread
computed the value, it would update the placeholder.  If the current
thread executed a `strict' primitive, it would pause until the value
became available.

Another early attempt was Gabriel and McCarthy's QLisp which used a
global queue of processes as the computation model.

Connection Machine Lisp implemented fine-grained parallelism within
an array-like structure that supported parallel mapping.

The main issue with parallelism is synchronization.  If the various
threads cannot share data, there is no problem, but if they can, they
must be able to co-ordinate their actions.  The `stack-group' model
provides only a low-level parallelism construct; the synchronization
model must be built upon it.  This is usually done via a mutex and
locking facility.  The `futures' model provides a fine-grained
synchronization through forcing of futures at strict primitives.

Turbak's `Synchrons' raise synchronization barriers to first-class
objects and turns the model on its head:  rather than providing mutual
exclusion barriers, he provides `rendezvous points' where all threads
must meet before any thread proceeds.

Bawden marries linear naming with graph reduction to automatically
extract parallelism from a process.  (As an aside, I *highly*
recommend reading this.)

Common Lisp, as specified by ANSI, is a sequential language.  There is
an implicit model of time that is enforced at various places in the
language.  For instance, forms execute from left to right.  Common
Lisp has no synchronization primitives, multitasking primitives, or
asynchronous operations.  Adding parallelism to Common Lisp is
strictly an extension to the language.  As should be clear from the
above, there are a huge number of possible mechanisms for doing so.

For a stack-group model, it is clear that a naive shallow binding
model (where the value cell of a symbol holds the current dynamic
value) coupled with free-threading would not be reasonable.  However,
there are many alternatives.  The usual one could be described as
a `copy upon bind' mechanism where each thread is given a private copy
at the point where a dynamic binding is created.  A `copy upon write'
model would work as well:  give each thread a completely separate
dynamic environment including the global values.  The stack-group
model provides no synchronization model, but a model based upon
futures has a very strong synchronization model.  It is easy to see
that discarding the current dynamic environment when spawning a future
would be a disaster.

In short, there are many models for parallelism and many ways to
extend Common Lisp in such a fashion.  There are several `wrong ways'
to deal with parallelism, but no clear-cut `right way'.  A
free-threaded uncontrolled `stack group' model is rather crude.  I
believe it to be an adequate substrate for a more sophisticated
parallelism mechanism, but the more sophisticated system would
necessarily require extensions to the language that deal with
synchronization issues.

~jrm
--------

References:

  Robert H. Halstead Jr.: 
  Multilisp: A Language for Concurrent Symbolic Computation. 
  ACM Trans. Program. Lang. Syst. 7(4): 501-538 (1985)


  Richard P. Gabriel, John L. McCarthy: 
  Queue-based Multi-processing Lisp. 
  LISP and Functional Programming 1984: 25-44

@article{ jr93evolution,
    author = "Guy L. {Steele, Jr.} and Richard P. Gabriel",
    title = "The evolution of {Lisp}",
    journal = "ACM SIG{\-}PLAN Notices",
    volume = "28",
    number = "3",
    pages = "231--270",
    year = "1993",
    url = "citeseer.nj.nec.com/steele93evolution.html" }

@inproceedings{ turbak96firstclass,
    author = "Franklyn A. Turbak",
    title = "First-Class Synchronization Barriers",
    booktitle = "International Conference on Functional Programming",
    pages = "157-168",
    year = "1996",
    url = "citeseer.nj.nec.com/turbak96firstclass.html" }

@techreport{ bawden93implementing,
    author = "Alan Bawden",
    title = "Implementing Distributed Systems Using Linear Naming",
    number = "AITR-1627",
    pages = "156",
    year = "1993",
    url = "citeseer.nj.nec.com/bawden93implementing.html" }
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041025370001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> [jrm wrote a bunch of stuff]
> 
> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > That seems to me to just be taking the position that the whole
> > concept of a global environment is a bad idea.  I do not necessarily
> > disagree with this, but the concept is woven rather deeply into the
> > CL standard.
> 
> I disagree with this assessment.

Which part of it do you disagree with?

>  I think that a global environment is
> fine, but when you have multiple processes, you may want multiple
> global environments.

This doesn't sound like disagreement to me.  Yes, you *might* want
multiple global environments.  But multiple dynamic environments are
*necessary* in the face of threads.  Multiple global environments are
not.  Therefore, the desirability of multiple global environments in the
face of threads is debatable, whereas the desirability of multiple dynamic
environments in the face of threads is not (you simply can't make them
work any other way).

I'm not actually taking a position on either side of this debate.  All I'm
saying is that it's debatable.  (And because it's debatable it probably
will be debated before it actually happens.)

> Each process would behave exactly as if there
> were a global environment modulo the visible effects of side-effects
> in other processes.  Binding of global variables would be invisible to
> any other process.

How do you handle defvar?  (BTW, that is a mostly rhetorical question.  If
you think you can answer it quickly then you have not understood the
ramifications of adding multiple global environments.)

[Review of thread models snipped]

> In short, there are many models for parallelism and many ways to
> extend Common Lisp in such a fashion.  There are several `wrong ways'
> to deal with parallelism, but no clear-cut `right way'.

Yes, but if you accept as axiomatic that whatever you do should require
minimal changes to the interpretation of the standard then that eliminates
many possibilities.  I am not saying that one should necessarily accept
this axiom, only that some people do.

> A free-threaded uncontrolled `stack group' model is rather crude.  I
> believe it to be an adequate substrate for a more sophisticated
> parallelism mechanism, but the more sophisticated system would
> necessarily require extensions to the language that deal with
> synchronization issues.

Yes.  I'm still searching in vain for signs of disagreement.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <r7x1iaj6.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
>
>> [jrm wrote a bunch of stuff]
>> 
>> ·········@jpl.nasa.gov (Erann Gat) writes:
>> 
>> > That seems to me to just be taking the position that the whole
>> > concept of a global environment is a bad idea.  I do not necessarily
>> > disagree with this, but the concept is woven rather deeply into the
>> > CL standard.
>> 
>> I disagree with this assessment.
>
> Which part of it do you disagree with?

I am not (deliberately) taking the position that the whole concept of
a global environment is a bad idea.

>>  I think that a global environment is
>> fine, but when you have multiple processes, you may want multiple
>> global environments.
>
> This doesn't sound like disagreement to me.  Yes, you *might* want
> multiple global environments.  But multiple dynamic environments are
> *necessary* in the face of threads.  Multiple global environments are
> not.  Therefore, the desirability of multiple global environments in the
> face of threads is debatable, whereas the desirability of multiple dynamic
> environments in the face of threads is not (you simply can't make them
> work any other way).
>
> I'm not actually taking a position on either side of this debate.  All I'm
> saying is that it's debatable.  (And because it's debatable it probably
> will be debated before it actually happens.)

Heh, that was what I was saying!
>
> Yes.  I'm still searching in vain for signs of disagreement.

Well, then.  Um, yes.  Er... what you said.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0br80$na1$1@newsreader2.netcologne.de>
Joe Marshall wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
>>This model is at odds with the standard, which specifies that a dynamic
>>binding may not outlive the execution of the form that created it. 
> 
> Given that the standard doesn't specify what happens under a
> multithreading extension, I don't see how it could be violated.

Whether or not this violates some standard doesn't matter much IMHO. I 
think Joe's scenario is a reasonable one, and the important question is 
how hard it is to implement it. I think one can do this in Common Lisp. 
Here is another attempt to tackle this, and again I think I have got it 
by now. The sting is to use object identity which I unconsciously tried 
to simulate with "parent" references before.

Here is my current take:

(defclass cell ()
   ((value :accessor value :initarg :value)))

(defmethod slot-unbound ((class t) (instance cell) slot)
   (assert (eql slot 'value))
   (error "Unbound cell ~A." instance))

(defmethod cell-symbol ((symbol symbol))
   (get symbol :cell))

(defmethod (setf cell-symbol) ((value symbol) (symbol symbol))
   (setf (get symbol :cell) value))

(defmacro defcell (cell-name &optional (value nil value-p))
   (let ((cell-symbol (make-symbol
                       (format nil "*~A*" cell-name))))
     `(progn
        (setf (cell-symbol ',cell-name) ',cell-symbol)
        (defvar ,cell-symbol
          (make-instance 'cell ,@(when value-p (list :value value))))
        (define-symbol-macro ,cell-name (value ,cell-symbol)))))

(defmacro cell-let (cells &body body)
   `(let ,(mapcar
           (lambda (celld)
             (etypecase celld
               (cons `(,(cell-symbol (car celld))
                       (make-instance 'cell :value ,(cadr celld))))
               (symbol (cell-symbol celld))))
           cells)
      ,@body))

(defun make-cell-closure (cells function)
   (let* ((symbols (mapcar #'cell-symbol cells))
          (values (mapcar #'symbol-value symbols)))
     (lambda ()
       (progv symbols values
         (funcall function)))))


DEFCELL should be used like DEFVAR.

CELL-LET should be used instead of LET.

MAKE-CELL-CLOSURE creates a dynamic closure of the given cells, and it 
should be possible to use it for passing cells to subthreads.

All the other stuff is supporting code.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002041830210001@192.168.1.71>
In article <············@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> Joe Marshall wrote:
> 
> > ·········@jpl.nasa.gov (Erann Gat) writes:
> > 
> >>This model is at odds with the standard, which specifies that a dynamic
> >>binding may not outlive the execution of the form that created it. 
> > 
> > Given that the standard doesn't specify what happens under a
> > multithreading extension, I don't see how it could be violated.
> 
> Whether or not this violates some standard doesn't matter much IMHO.

At one time there was a vocal faction in the Lisp community to which
adherence to the standard seemed to matter a great deal.  I do not know
whether or not this is stil the case.

> I think Joe's scenario is a reasonable one

I agree.

> and the important question is how hard it is to implement it.

That depends on what you mean by "it".  If all you want is the
functionality then it's easy.  If you care about embedding it in Common
Lisp (so that, for example, lambda bindings work the right way) then it's
hard in the sense that you almost certainly have to change the
implementation.  I've actually hacked MCL to do similar things (so that,
for example, you can do (lambda ((symbol-value x) x) ...) to create both a
dynamic binding and a lexical binding for X in the same lambda form) and
it's actually not that hard.  But it does require implementation hacking. 
You can't do it in standard Common Lisp.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0dcuu$13ei$1@f1node01.rhrz.uni-bonn.de>
Erann Gat wrote:

> In article <············@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
>>Joe Marshall wrote:
>>
>>>·········@jpl.nasa.gov (Erann Gat) writes:
>>>
>>>>This model is at odds with the standard, which specifies that a dynamic
>>>>binding may not outlive the execution of the form that created it. 
>>>
>>>Given that the standard doesn't specify what happens under a
>>>multithreading extension, I don't see how it could be violated.
>>
>>Whether or not this violates some standard doesn't matter much IMHO.
> 
> At one time there was a vocal faction in the Lisp community to which
> adherence to the standard seemed to matter a great deal.  I do not know
> whether or not this is stil the case.

It doesn't matter because I think the thing can be satisfactorily 
implemented in plain Common Lisp.

Apart from that, I think the standard is good and important to keep as 
it is, as long as noone can substantially improve it.

>>I think Joe's scenario is a reasonable one
> 
> I agree.
> 
>>and the important question is how hard it is to implement it.
> 
> That depends on what you mean by "it".  If all you want is the
> functionality then it's easy.  If you care about embedding it in Common
> Lisp (so that, for example, lambda bindings work the right way) then it's
> hard in the sense that you almost certainly have to change the
> implementation.  I've actually hacked MCL to do similar things (so that,
> for example, you can do (lambda ((symbol-value x) x) ...) to create both a
> dynamic binding and a lexical binding for X in the same lambda form) and
> it's actually not that hard.  But it does require implementation hacking. 
> You can't do it in standard Common Lisp.

This seems to me like a different issue. As far as I have been able to 
follow the discussion, it seems to me that the implementation I have 
provided (DEFCELL, etc.) offers the abstractions one needs to implement 
Joe's scenario. You could even shadow DEFVAR and the like with those 
definitions to make this work for "legacy" code, I guess.

Of course, I haven't tested this extensively, but it seems doable.

What would you need your changed lambda construct for, and why wouldn't 
it be implementable as eranns-lambda? ;)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041001490001@k-137-79-50-101.jpl.nasa.gov>
In article <·············@f1node01.rhrz.uni-bonn.de>, Pascal Costanza
<········@web.de> wrote:

> This seems to me like a different issue. As far as I have been able to 
> follow the discussion, it seems to me that the implementation I have 
> provided (DEFCELL, etc.) offers the abstractions one needs to implement 
> Joe's scenario. You could even shadow DEFVAR and the like with those 
> definitions to make this work for "legacy" code, I guess.
> 
> Of course, I haven't tested this extensively, but it seems doable.
> 
> What would you need your changed lambda construct for,

You would need it precisely for the purpose you mention: to make it work
for legacy code (which is the whole point -- Remember, Joe's motivating
scenario was, "I've got a server written in a particular way and I can't
change the code and I want to run two of them at the same time.")

>  and why wouldn't it be implementable as eranns-lambda? ;)

Because erann's-lambda wouldn't be enough.  You also need erann's-let,
erann's-labels, erann's-multiple-value-bind, etc. etc.  You're trying to
fundamentally change how dynamic binding works so you need to redefine all
the binding constructs (and all the variable definition constructs:
defvar, defparameter, and symbol-value, and symbol-value-in-process if
your implementation provides that).  It is possible (you can make Common
Lisp behave as if it were a C compiler if you work hard enough -- and vice
versa) but by the time you shadow all the binding constructs it seems to
me that you're no longer "in Common Lisp" any more, you're in a new
dialect of Lisp with different semantics that happens to be implemented in
Common Lisp.

Not that there's anything wrong with that.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0e1av$gl$1@newsreader2.netcologne.de>
Erann Gat wrote:

>>What would you need your changed lambda construct for,
> 
> You would need it precisely for the purpose you mention: to make it work
> for legacy code (which is the whole point -- Remember, Joe's motivating
> scenario was, "I've got a server written in a particular way and I can't
> change the code and I want to run two of them at the same time.")

ok

>> and why wouldn't it be implementable as eranns-lambda? ;)
> 
> Because erann's-lambda wouldn't be enough.  You also need erann's-let,
> erann's-labels, erann's-multiple-value-bind, etc. etc.  You're trying to
> fundamentally change how dynamic binding works so you need to redefine all
> the binding constructs (and all the variable definition constructs:
> defvar, defparameter, and symbol-value, and symbol-value-in-process if
> your implementation provides that).

ok

> It is possible (you can make Common
> Lisp behave as if it were a C compiler if you work hard enough -- and vice
> versa) but by the time you shadow all the binding constructs it seems to
> me that you're no longer "in Common Lisp" any more, you're in a new
> dialect of Lisp with different semantics that happens to be implemented in
> Common Lisp.
> 
> Not that there's anything wrong with that.

Exactly. That's the reason for my statement that I don't care whether a 
change is standard compliant or not. The real question is whether you 
can implement your own abstractions and make them interoperate with 
other Common Lisp code. If that's possible for a particular abstraction, 
then everything is fine IMHO.

There are possible extensions that would need fundamental changes to the 
standard, such as switching to Lisp-1 or integration of call/cc. It's 
hard to make these things interoperate with the rest of the CL world. 
However, since these features don't seem to add substantial advantages, 
there is no point in doing that.

It is really hard to come up with anything that would require a 
substantial revision of ANSI Common Lisp and would provide equally 
substantial benefits at the same time. As long as this is the case, it 
is absolutely sufficient to work within the boundaries set by ANSI CL.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041237180001@k-137-79-50-101.jpl.nasa.gov>
In article <···········@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> Exactly. That's the reason for my statement that I don't care whether a 
> change is standard compliant or not. The real question is whether you 
> can implement your own abstractions and make them interoperate with 
> other Common Lisp code. If that's possible for a particular abstraction, 
> then everything is fine IMHO.
>
> There are possible extensions that would need fundamental changes to the 
> standard, such as switching to Lisp-1 or integration of call/cc.

When you get right down do it you can do anything within the standard by
shadowing defun and writing a code walker.  So a reasonable interpretation
of "cannot be done within the standard" is "cannot be done within the
stanard except with a code walker."

On this definition, Lisp-1 can be done within the standard using symbol
macros (and in fact it has been done -- see my locales paper).  Call/cc
cannot.  Neither can ((foo) ...).  And, I believe (I could be wrong about
this), neither can Joe's proposed model of how dynamic bindings interact
with threads.

> It's 
> hard to make these things interoperate with the rest of the CL world. 
> However, since these features don't seem to add substantial advantages, 
> there is no point in doing that.

Reasonable people could disagree (and they do, which is why Scheme has a
user community.)

> It is really hard to come up with anything that would require a 
> substantial revision of ANSI Common Lisp and would provide equally 
> substantial benefits at the same time. As long as this is the case, it 
> is absolutely sufficient to work within the boundaries set by ANSI CL.

This seems to me to be at odds with your earlier statement:

> I don't care whether a change is standard compliant or not.

Not that this necessarily matters.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0eall$dfu$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <···········@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
> 
>>Exactly. That's the reason for my statement that I don't care whether a 
>>change is standard compliant or not. The real question is whether you 
>>can implement your own abstractions and make them interoperate with 
>>other Common Lisp code. If that's possible for a particular abstraction, 
>>then everything is fine IMHO.
>>
>>There are possible extensions that would need fundamental changes to the 
>>standard, such as switching to Lisp-1 or integration of call/cc.
> 
> When you get right down do it you can do anything within the standard by
> shadowing defun and writing a code walker.  So a reasonable interpretation
> of "cannot be done within the standard" is "cannot be done within the
> stanard except with a code walker."

I don't think that this is the only issue.

> On this definition, Lisp-1 can be done within the standard using symbol
> macros (and in fact it has been done -- see my locales paper).  Call/cc
> cannot.  Neither can ((foo) ...).  And, I believe (I could be wrong about
> this), neither can Joe's proposed model of how dynamic bindings interact
> with threads.

OK, let's see:

- Lisp-1 would have problems wrt to interoperability. When referring to 
Lisp-1 definitions from within Lisp-2 code, you could just use the same 
value for both function and value namespaces. (Functions only when they 
are lambda expressions.) When referring to Lisp-2 definitions from 
within Lisp-1 code, would you mean the function or the value namespace 
by default? What would be the effect when you set the symbol-value of a 
Lisp-2 symbol? What would happen if you passed Lisp-1 symbols to Lisp-2 
code and vice versa? It seems to me that these issues are not 
straightforward to solve.

- Likewise, call/cc has problems wrt unwind-protect, as Kent has 
explained in his paper. The fact that unwind-protect can be implemented 
on top of dynamic-wind doesn't seem to matter much in this regard 
AFAICS. Also, Duane has explained before that call/cc is hard to 
integrate with FFIs, IIRC.

- I think I have provided code that allows one to use Joe's model for 
dynamic bindings across threads. You cannot directly use Common Lisp's 
internal defvar and so on for that, but you can redefine / shadow it and 
have the "legacy" code recompiled, maybe with some minor tweaks. I don't 
see any real interoperability problems here.

I really don't think it matters how things are implemented. What matters 
is how seamless you can make it. But maybe I am missing something...

>>It's 
>>hard to make these things interoperate with the rest of the CL world. 
>>However, since these features don't seem to add substantial advantages, 
>>there is no point in doing that.
> 
> Reasonable people could disagree (and they do, which is why Scheme has a
> user community.)

Sure. Continuations are an important abstraction, at least from a 
computer scientist's point of view. That's why it is natural that there 
are languages that support them. BTW, there are also implementations of 
Turing machines out there. Worthwhile to understand those models, isn't 
it? ;)

>>It is really hard to come up with anything that would require a 
>>substantial revision of ANSI Common Lisp and would provide equally 
>>substantial benefits at the same time. As long as this is the case, it 
>>is absolutely sufficient to work within the boundaries set by ANSI CL.
> 
> This seems to me to be at odds with your earlier statement:
> 
>>I don't care whether a change is standard compliant or not.

No, not really. There are essentially four possibilies:

- Someone will invent a strictly better language for my purposes.
- I will find out about an already existing language that is strictly 
better for my purposes.
- I will understand that of the languages I know but currently despise, 
there is one that is indeed strictly better for my purposes, but I 
simply haven't gotten it yet.
- I will die beforehand. ;)

In the first three cases, I will happily switch to the better language. 
It wouldn't matter to me if Common Lisp also made the switch or not in 
those cases.

The point is, as far as I can see, it is really very hard to beat Common 
Lisp in terms of fundamental feature set, at least from my subjective 
point of view. There are many minor details that could be improved in 
one way or the other, but these aren't things that couldn't be added 
seamlessly with a bunch of macros. Changing the standard for those minor 
improvements would be gratuitous, especially because it will be hard to 
agree upon them. (For example, remember a recent discussion here whether 
global variables should always use the asterisk convention or not.) An 
agreement upon a certain way to combine features that is somewhat 
accidental to a certain degree is better than none. Given the 
circumstances under which Common Lisp was developed it is really amazing 
how well balanced it is. I don't see any language that really comes close.

So, no I don't care whether a change to the standard would be compliant 
or not. There just don't seem to be strong enough reasons to make 
non-compliant changes.

> Not that this necessarily matters.

Sure. ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041542570001@k-137-79-50-101.jpl.nasa.gov>
In article <············@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> - Lisp-1 would have problems wrt to interoperability. When referring to 
> Lisp-1 definitions from within Lisp-2 code, you could just use the same 
> value for both function and value namespaces. (Functions only when they 
> are lambda expressions.) When referring to Lisp-2 definitions from 
> within Lisp-1 code, would you mean the function or the value namespace 
> by default? What would be the effect when you set the symbol-value of a 
> Lisp-2 symbol? What would happen if you passed Lisp-1 symbols to Lisp-2 
> code and vice versa? It seems to me that these issues are not 
> straightforward to solve.

<shrug> You can look at the locales code for a point solution.  The
answers to your questions in that case are: there is no such thing as
"lisp-1 code" and "lisp-2 code", only lisp-1 namespaces and lisp-2
namespaces.  Variables are bound in one kind of namespace or the other. 
You can freely mix and match variables bound in either kind of namespace.

Setting the symbol-value or symbol-function of a symbol bound in a lisp-2
namespace the usual things happen.  Setting the symbol-value or
symbol-function of a symbol bound in a lisp-1 namespace will give you an
error at the moment because I've only implemented lexical lisp-1 bindings
(since the goal here was to emulate Scheme (or, more precisely, T)
semantics).

The question of "what happens when you pass lisp-1 symbols to lisp-2 code"
is meaningless because there is no such thing as a lisp-1/2 symbol or
lisp-1/2 code, only lisp-1/2 bindings.


> - Likewise, call/cc has problems wrt unwind-protect, as Kent has 
> explained in his paper. The fact that unwind-protect can be implemented 
> on top of dynamic-wind doesn't seem to matter much in this regard 
> AFAICS. Also, Duane has explained before that call/cc is hard to 
> integrate with FFIs, IIRC.

Yes, but none of this prevents you from choosing some semantics for
call/cc -- even if those semantics are that it is an error to use call/cc
in conjunction with unwind-protect -- and then implementing those
semantics using a code walker.


> - I think I have provided code that allows one to use Joe's model for 
> dynamic bindings across threads. You cannot directly use Common Lisp's 
> internal defvar and so on for that, but you can redefine / shadow it and 
> have the "legacy" code recompiled, maybe with some minor tweaks. I don't 
> see any real interoperability problems here.

But your solution relies on having a specialized cell-let form that must
be used when binding dynamic variables.  There's nothing wrong with that
(personally I think that's actually a good design), but it is very much at
odds with the design philosophy of Common Lisp, which is that whether a
binding is lexical or dynamic should be determined by the type of variable
that is being bound and not by the binding construct used.


> I really don't think it matters how things are implemented. What matters 
> is how seamless you can make it. But maybe I am missing something...

Well, one thing that you're missing is that your code doesn't work:  ;-)

? (defcell x 1)
X
? x
1
? (defun foo () x)
FOO
? (cell-let ( (x 2) ) (foo))
2
? (cell-let ( (x 3) ) (process-run-function "" (lambda () (sleep 1) (print
(foo)))))
#<PROCESS  [Enabled] #xEB827E>
? 
1 ; Should be 3


> The point is, as far as I can see, it is really very hard to beat Common 
> Lisp in terms of fundamental feature set, at least from my subjective 
> point of view.

Agreed.


> So, no I don't care whether a change to the standard would be compliant 
> or not. There just don't seem to be strong enough reasons to make 
> non-compliant changes.

I think you will find that implementing Joe's dynamic binding model
correctly will be quite a challenge.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0ehen$me6$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <············@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
>>- Lisp-1 would have problems wrt to interoperability. When referring to 
>>Lisp-1 definitions from within Lisp-2 code, you could just use the same 
>>value for both function and value namespaces. (Functions only when they 
>>are lambda expressions.) When referring to Lisp-2 definitions from 
>>within Lisp-1 code, would you mean the function or the value namespace 
>>by default? What would be the effect when you set the symbol-value of a 
>>Lisp-2 symbol? What would happen if you passed Lisp-1 symbols to Lisp-2 
>>code and vice versa? It seems to me that these issues are not 
>>straightforward to solve.
> 
> <shrug> You can look at the locales code for a point solution.  The
> answers to your questions in that case are: there is no such thing as
> "lisp-1 code" and "lisp-2 code", only lisp-1 namespaces and lisp-2
> namespaces.  Variables are bound in one kind of namespace or the other. 
> You can freely mix and match variables bound in either kind of namespace.

Hmm, seems like I find CL-style packages more natural than module 
systems. ;-)

So what do I need to do to use a definition from a lisp-2 namespace 
within a lisp-1 namespace? There has to be _some_ kind of export/import 
options between these namespaces.

>>- Likewise, call/cc has problems wrt unwind-protect, as Kent has 
>>explained in his paper. The fact that unwind-protect can be implemented 
>>on top of dynamic-wind doesn't seem to matter much in this regard 
>>AFAICS. Also, Duane has explained before that call/cc is hard to 
>>integrate with FFIs, IIRC.
> 
> Yes, but none of this prevents you from choosing some semantics for
> call/cc -- even if those semantics are that it is an error to use call/cc
> in conjunction with unwind-protect -- and then implementing those
> semantics using a code walker.

...but then you can't mix code developed in one style with code 
developed in the other style. This is what I would care about.

>>- I think I have provided code that allows one to use Joe's model for 
>>dynamic bindings across threads. You cannot directly use Common Lisp's 
>>internal defvar and so on for that, but you can redefine / shadow it and 
>>have the "legacy" code recompiled, maybe with some minor tweaks. I don't 
>>see any real interoperability problems here.
> 
> But your solution relies on having a specialized cell-let form that must
> be used when binding dynamic variables.  There's nothing wrong with that
> (personally I think that's actually a good design), but it is very much at
> odds with the design philosophy of Common Lisp, which is that whether a
> binding is lexical or dynamic should be determined by the type of variable
> that is being bound and not by the binding construct used.

Hmm, I don't regard this as fundamental. For example, ISLISP has special 
constructs to deal with dynamic bindings, and I don't think there are 
serious incompatibilities between Common Lisp and ISLISP. These are just 
syntactic details.

>>I really don't think it matters how things are implemented. What matters 
>>is how seamless you can make it. But maybe I am missing something...
> 
> Well, one thing that you're missing is that your code doesn't work:  ;-)
> 
> ? (defcell x 1)
> X
> ? x
> 1
> ? (defun foo () x)
> FOO
> ? (cell-let ( (x 2) ) (foo))
> 2
> ? (cell-let ( (x 3) ) (process-run-function "" (lambda () (sleep 1) (print
> (foo)))))
> #<PROCESS  [Enabled] #xEB827E>
> ? 
> 1 ; Should be 3

Try this:

? (cell-let ((x 3))
     (process-run-function
      "" (make-cell-closure '(x) (lambda () (sleep 1) (print (foo))))))
#<PROCESS  [Enabled] #x23FFB36>
?
3

As far as I understood Joe, this is what he meant by saying that dynamic 
closures would be a solution for his scenario. The references I have 
found describe an explicit make-dynamic-closure that behaves as 
make-cell-closure.

>>The point is, as far as I can see, it is really very hard to beat Common 
>>Lisp in terms of fundamental feature set, at least from my subjective 
>>point of view.
> 
> Agreed.
> 
>>So, no I don't care whether a change to the standard would be compliant 
>>or not. There just don't seem to be strong enough reasons to make 
>>non-compliant changes.
> 
> I think you will find that implementing Joe's dynamic binding model
> correctly will be quite a challenge.

See above. ;)

It's really only about object identity AFAICS.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041830210001@192.168.1.51>
In article <············@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> So what do I need to do to use a definition from a lisp-2 namespace 
> within a lisp-1 namespace? There has to be _some_ kind of export/import 
> options between these namespaces.

In the locales code (just as in your dynamic closures code) bindings are
first-class so you can do anything you like with them, including share
them across namespaces.  In fact (and this only just occurred to me) it's
not necessary to have separate lisp1 and lisp2 locales.  You can have a
lisp1 binding in a lisp2 locale by putting the same binding object in two
namespaces at the same time.  Ooh!  Hack attack!  Gotta go!  :-)

Of course, you can always use plain old Common Lisp bindings as well.  Any
time you refer to a symbol that has not been LSET it's just a CL symbol
like any other.


> >>- Likewise, call/cc has problems wrt unwind-protect, as Kent has 
> >>explained in his paper. The fact that unwind-protect can be implemented 
> >>on top of dynamic-wind doesn't seem to matter much in this regard 
> >>AFAICS. Also, Duane has explained before that call/cc is hard to 
> >>integrate with FFIs, IIRC.
> > 
> > Yes, but none of this prevents you from choosing some semantics for
> > call/cc -- even if those semantics are that it is an error to use call/cc
> > in conjunction with unwind-protect -- and then implementing those
> > semantics using a code walker.
> 
> ...but then you can't mix code developed in one style with code 
> developed in the other style. This is what I would care about.

Then you would need to choose different semantics for call/cc.


> >>- I think I have provided code that allows one to use Joe's model for 
> >>dynamic bindings across threads. You cannot directly use Common Lisp's 
> >>internal defvar and so on for that, but you can redefine / shadow it and 
> >>have the "legacy" code recompiled, maybe with some minor tweaks. I don't 
> >>see any real interoperability problems here.
> > 
> > But your solution relies on having a specialized cell-let form that must
> > be used when binding dynamic variables.  There's nothing wrong with that
> > (personally I think that's actually a good design), but it is very much at
> > odds with the design philosophy of Common Lisp, which is that whether a
> > binding is lexical or dynamic should be determined by the type of variable
> > that is being bound and not by the binding construct used.
> 
> Hmm, I don't regard this as fundamental. For example, ISLISP has special 
> constructs to deal with dynamic bindings, and I don't think there are 
> serious incompatibilities between Common Lisp and ISLISP. These are just 
> syntactic details.

I see it as fundamental because it has a major impact on what you have to
do to analyze code.  For example, in Common Lisp you have to do a global
analysis to know whether a variable is lexically or dynamically bound (and
in fact in the worst case you have to solve the halting problem).  If
there are separate forms for lexical and dynamic binding then determining
which kind of binding you have is trivial.

> Try this:
> 
> ? (cell-let ((x 3))
>      (process-run-function
>       "" (make-cell-closure '(x) (lambda () (sleep 1) (print (foo))))))
> #<PROCESS  [Enabled] #x23FFB36>
> ?
> 3

Ah.

Well, that seems a bit like cheating to me because you're asking the user
to do the hard part for you and identify all the variables that need to be
closed over.  (I must say, though, that make-cell-closure is much cooler
than it seemed to me at first glance.)

But if what you care about is compatibility with CL coding style then you
have a much bigger problem:

? (defcell x 1)
X
? (symbol-value 'x)
> Error: Unbound variable: X


> > I think you will find that implementing Joe's dynamic binding model
> > correctly will be quite a challenge.
> 
> See above. ;)

See above.  ;-)

> It's really only about object identity AFAICS.

That's what Pitman always used to say so it's probably true.  :-)

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0fh8f$33p$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <············@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
> 
>>So what do I need to do to use a definition from a lisp-2 namespace 
>>within a lisp-1 namespace? There has to be _some_ kind of export/import 
>>options between these namespaces.
> 
> In the locales code (just as in your dynamic closures code) bindings are
> first-class so you can do anything you like with them, including share
> them across namespaces.  In fact (and this only just occurred to me) it's
> not necessary to have separate lisp1 and lisp2 locales.  You can have a
> lisp1 binding in a lisp2 locale by putting the same binding object in two
> namespaces at the same time.  Ooh!  Hack attack!  Gotta go!  :-)
> 
> Of course, you can always use plain old Common Lisp bindings as well.  Any
> time you refer to a symbol that has not been LSET it's just a CL symbol
> like any other.

Hmm, I think I have to check out your paper again. My head hurts. ;)

>>>>- Likewise, call/cc has problems wrt unwind-protect, as Kent has 
>>>>explained in his paper. The fact that unwind-protect can be implemented 
>>>>on top of dynamic-wind doesn't seem to matter much in this regard 
>>>>AFAICS. Also, Duane has explained before that call/cc is hard to 
>>>>integrate with FFIs, IIRC.
>>>
>>>Yes, but none of this prevents you from choosing some semantics for
>>>call/cc -- even if those semantics are that it is an error to use call/cc
>>>in conjunction with unwind-protect -- and then implementing those
>>>semantics using a code walker.
>>
>>...but then you can't mix code developed in one style with code 
>>developed in the other style. This is what I would care about.
> 
> Then you would need to choose different semantics for call/cc.

Maybe.

>>>>- I think I have provided code that allows one to use Joe's model for 
>>>>dynamic bindings across threads. You cannot directly use Common Lisp's 
>>>>internal defvar and so on for that, but you can redefine / shadow it and 
>>>>have the "legacy" code recompiled, maybe with some minor tweaks. I don't 
>>>>see any real interoperability problems here.
>>>
>>>But your solution relies on having a specialized cell-let form that must
>>>be used when binding dynamic variables.  There's nothing wrong with that
>>>(personally I think that's actually a good design), but it is very much at
>>>odds with the design philosophy of Common Lisp, which is that whether a
>>>binding is lexical or dynamic should be determined by the type of variable
>>>that is being bound and not by the binding construct used.
>>
>>Hmm, I don't regard this as fundamental. For example, ISLISP has special 
>>constructs to deal with dynamic bindings, and I don't think there are 
>>serious incompatibilities between Common Lisp and ISLISP. These are just 
>>syntactic details.
> 
> I see it as fundamental because it has a major impact on what you have to
> do to analyze code.  For example, in Common Lisp you have to do a global
> analysis to know whether a variable is lexically or dynamically bound (and
> in fact in the worst case you have to solve the halting problem).  If
> there are separate forms for lexical and dynamic binding then determining
> which kind of binding you have is trivial.

Yes, and this is why ISLISP has done things a little better than Common 
Lisp in this regard. But I don't think this is reason enough to try to 
force everything into the same style in Common Lisp.

>>Try this:
>>
>>? (cell-let ((x 3))
>>     (process-run-function
>>      "" (make-cell-closure '(x) (lambda () (sleep 1) (print (foo))))))
>>#<PROCESS  [Enabled] #x23FFB36>
>>?
>>3
> 
> Ah.
> 
> Well, that seems a bit like cheating to me because you're asking the user
> to do the hard part for you and identify all the variables that need to be
> closed over.  (I must say, though, that make-cell-closure is much cooler
> than it seemed to me at first glance.)

I think the outcome of this discussion was that no binding scheme for 
dynamic variables across threads is the single right one. This indicates 
to me that programmers will probably want to choose between different 
semantics on a case-to-case basis. If make-cell-closure would close over 
all dynamic variables, we would need to offer a way to say something 
like "except for symbols s1, ..., sn". So this boils down to what's the 
default behavior. Since most of the people in this discussion said that 
something like dynamic closures are dangerous and can lead to subtle 
bugs, I think it really can't get any better than this.

> But if what you care about is compatibility with CL coding style then you
> have a much bigger problem:
> 
> ? (defcell x 1)
> X
> ? (symbol-value 'x)
> 
>>Error: Unbound variable: X

"Calling symbol-value on a cell has undefined consequences. Call 
(symbol-value (cell-symbol <cell>)) instead." ;)

If symbol-value were generic, we could adapt it.

>>It's really only about object identity AFAICS.
> 
> That's what Pitman always used to say so it's probably true.  :-)

:-))


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c1i8cv$4pd$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <············@newsreader2.netcologne.de>, Pascal Costanza
> <········@web.de> wrote:
> 
> 
>>So what do I need to do to use a definition from a lisp-2 namespace 
>>within a lisp-1 namespace? There has to be _some_ kind of export/import 
>>options between these namespaces.
> 
> 
> In the locales code (just as in your dynamic closures code) bindings are
> first-class so you can do anything you like with them, including share
> them across namespaces.  In fact (and this only just occurred to me) it's
> not necessary to have separate lisp1 and lisp2 locales.  You can have a
> lisp1 binding in a lisp2 locale by putting the same binding object in two
> namespaces at the same time.  Ooh!  Hack attack!  Gotta go!  :-)

I have reread your paper again, and I don't think your locales address 
the issue I have in mind. I was talking about interoperability between 
Lisp-1 and Lisp-2 "worlds". Given that a Lisp-2 locale has two bindings 
for the same name, a function binding and a value binding - how do you 
decide which one you take when you import the name into a Lisp-1 locale? 
You can't do this automatically, AFAICS, but only provide a default with 
an option to selectively override it. This is not unlike the situation 
we sometimes encounter with packages, when it is not clear which of two 
conflicting symbols should be part of a package.

For example, how does a Lisp-1 locale inherit from a Lisp-2 locale 
without losing half the bindings?

This is not a critique of your locales solution, because I think it is a 
general problem of interoperability between Lisp-1 and Lisp-2. Unless I 
am missing something, of course.

Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-2502040917070001@192.168.1.52>
In article <············@newsreader2.netcologne.de>, Pascal Costanza
<········@web.de> wrote:

> Erann Gat wrote:
> 
> > In article <············@newsreader2.netcologne.de>, Pascal Costanza
> > <········@web.de> wrote:
> > 
> > 
> >>So what do I need to do to use a definition from a lisp-2 namespace 
> >>within a lisp-1 namespace? There has to be _some_ kind of export/import 
> >>options between these namespaces.
> > 
> > 
> > In the locales code (just as in your dynamic closures code) bindings are
> > first-class so you can do anything you like with them, including share
> > them across namespaces.  In fact (and this only just occurred to me) it's
> > not necessary to have separate lisp1 and lisp2 locales.  You can have a
> > lisp1 binding in a lisp2 locale by putting the same binding object in two
> > namespaces at the same time.  Ooh!  Hack attack!  Gotta go!  :-)
> 
> I have reread your paper again, and I don't think your locales address 
> the issue I have in mind. I was talking about interoperability between 
> Lisp-1 and Lisp-2 "worlds". Given that a Lisp-2 locale has two bindings 
> for the same name, a function binding and a value binding - how do you 
> decide which one you take when you import the name into a Lisp-1 locale?
                                            ^^^^^^^^
You don't import names, you import bindings so you have to decide which
one you want.  (You can also import values, but that's not very
interesting.)

This is really crucial: when you switch from one locale to the other, the
*same* symbol becomes associated with *different* (top-level) bindings. 
This is very different from how packages work, where the same *name*
becomes associated with different *symbols*.

When you evaluate "X" in two different packages you are evaluating two
different symbols.  When you evaluate "X" in two different locales you are
evaluating the *same* symbol, but getting two different top-level (not
global) bindings for that symbol.

> You can't do this automatically, AFAICS, but only provide a default with 
> an option to selectively override it.

That's right.

> This is not unlike the situation 
> we sometimes encounter with packages, when it is not clear which of two 
> conflicting symbols should be part of a package.

Yes.

> For example, how does a Lisp-1 locale inherit from a Lisp-2 locale 
> without losing half the bindings?

When the current binding is in a superior locale and that superior locale
is a lisp-2 locale then it acts like a lisp-2 symbol (until you redefine
it in the lisp-1 locale).

I was hacking on the code and left it in a broken state so I can't run a
demo for you right now, but if you want I'll try to put things back
together.

E.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-2502041528240001@k-137-79-50-101.jpl.nasa.gov>
In article <··························@192.168.1.52>,
·········@jpl.nasa.gov (Erann Gat) wrote:

> I was hacking on the code and left it in a broken state so I can't run a
> demo for you right now, but if you want I'll try to put things back
> together.

I fixed the problem.  Here's a demo:

? (make-locale :l1)
#<Locale L1>
? (in-locale :l1)
"Locale L1"
? (ldefun foo () 'l1-foo-function)
FOO
? (ldefun baz () 'l1-baz-function)
BAZ
? (ldefvar foo 'l1-foo-value)
FOO
? (ldefvar baz 'l1-baz-value)
BAZ
? foo
L1-FOO-VALUE
? (foo)
L1-FOO-FUNCTION
? baz
L1-BAZ-VALUE
? (baz)
L1-BAZ-FUNCTION
? 

So far everything is just like CL.

? (make-locale :l2)  ; Inherits from L1
#<Locale L2>
? (convert-locale-to-lisp1-semantics *)
#<Locale L2>
? (in-locale :l2)
"Locale L2"
? (ldefun foo () 'l2-foo-function)  ; Could have used DEFINE also
FOO
? foo
#<Compiled-function |FOO (#<Locale L2>)| (Non-Global)  #xF2C66E>
? (foo)
L2-FOO-FUNCTION
? baz
L1-BAZ-VALUE
? (baz)
L1-BAZ-FUNCTION
? (setf baz 321)
321
? (baz)
L1-BAZ-FUNCTION
? (setf foo 123)
123
? (foo)
> Error: 123 can't be FUNCALLed or APPLYed.


Does that make sense?  FOO is bound in the current locale, which is a
Lisp-1 locale, so its value and function bindings are the same.  BAZ is
bound in the parent locale, which is still a lisp-2 locale, so it has
separate value and function bindings.

Having a lisp-1 locale inherit from a lisp-2 locale is probably a bad idea.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c1lhcb$nti$1@newsreader2.netcologne.de>
Erann Gat wrote:

> In article <··························@192.168.1.52>,
> ·········@jpl.nasa.gov (Erann Gat) wrote:
> 
> 
>>I was hacking on the code and left it in a broken state so I can't run a
>>demo for you right now, but if you want I'll try to put things back
>>together.
> 
> I fixed the problem.  Here's a demo:

Thanks.

> ? (make-locale :l1)
> #<Locale L1>
> ? (in-locale :l1)
> "Locale L1"
> ? (ldefun foo () 'l1-foo-function)
> FOO
> ? (ldefun baz () 'l1-baz-function)
> BAZ
> ? (ldefvar foo 'l1-foo-value)
> FOO
> ? (ldefvar baz 'l1-baz-value)
> BAZ
> ? foo
> L1-FOO-VALUE
> ? (foo)
> L1-FOO-FUNCTION
> ? baz
> L1-BAZ-VALUE
> ? (baz)
> L1-BAZ-FUNCTION
> ? 
> 
> So far everything is just like CL.
> 
> ? (make-locale :l2)  ; Inherits from L1
> #<Locale L2>
> ? (convert-locale-to-lisp1-semantics *)
> #<Locale L2>
> ? (in-locale :l2)
> "Locale L2"
[...]

> ? baz
> L1-BAZ-VALUE
> ? (baz)
> L1-BAZ-FUNCTION
> ? (setf baz 321)
> 321
> ? (baz)
> L1-BAZ-FUNCTION

I think this part would potentially lead to very confusing situations.

> Does that make sense?  FOO is bound in the current locale, which is a
> Lisp-1 locale, so its value and function bindings are the same.  BAZ is
> bound in the parent locale, which is still a lisp-2 locale, so it has
> separate value and function bindings.

I think that's a bad idea. The point in creating a Lisp-1 world is to be 
able to use the same bindings in both function and value positions in 
order to be able to use a "purer" applicative programming style. A 
locale in which both Lisp-1 and Lisp-2 symbols exist would require the 
Lisp-1 programmers to make the distinctions they don't want to make here.

A Lisp-2 world is more general: When you import a Lisp-2 binding you can 
just reuse it in both function and value positions, unless it is not a 
function in which case you just reuse it in value positions. The other 
way around is more complicated. Reasonable defaults would be a) to 
import only functions, b) to import only values, c) import both but use 
a renaming scheme. Option c is harder because you could still have name 
clashes in edge cases. All those options would probably need means to 
selectively express exceptions.

However, these are the reasons why I think it doesn't make a lot of 
difference whether you attach the Lisp-1/2-ness to a module or a 
CL-style package system. I don't think you'd want Lisp-1 
locales/modules/packages only to play around with a Lisp-1 system, but 
rather to reuse libraries written in Lisp-1 dialects and vice versa, 
reuse Common Lisp libraries in Lisp-1 dialects.

> Having a lisp-1 locale inherit from a lisp-2 locale is probably a bad idea.

That's what I meant.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Björn Lindberg
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hcsn07qa3qn.fsf@fnatte.nada.kth.se>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@comcast.net>, Joe Marshall
> <·············@comcast.net> wrote:
> 
> > Pascal Costanza <········@web.de> writes:
> > 
> > > Thanks for your response!
> > >
> > > However, now I am really confused. Your two previous comments sound to
> > > me as if a dynamic closure needs to preserve sharing but
> > > shouldn't. This doesn't make sense to me, so I am clearly missing
> > > something.
> > >
> > > Let's see. Here is how I understand your example:
> > >
> > >
> > >                    worker-1
> > >                   /
> > >           server-1
> > >               /        \
> > >         /          worker-2
> > > program
> > >         \          worker-3
> > >          \        /
> > >           server-2
> > >                   \
> > >                    worker-4
> > >
> > > You would like to be able to change a shared binding from within a
> > > worker thread that is bound in a server thread, but not in the global
> > > program thread.
> > 
> > Ok, under `normal' circumstances, a thread will share the top-level
> > binding of a special variable with all other threads.  Assignments
> > made by this thread are seen by other threads, and this thread will
> > see assignments made other threads.  If a thread wants to change the
> > value in a thread-local way, it simply binds the dynamic value and no
> > other thread sees it.
> > 
> > Now suppose that server-1 binds a dynamic variable.  This should make
> > the variable be local to server-1.  The worker threads `under'
> > server-1 should behave as if that were a global binding.  If worker-1
> > assigns to the variable, worker-2 will see the change (as will
> > server-1).  
> > 
> > However, worker-3 and worker-4 will *not* share the binding that
> > worker-1 and worker-2 see.  They will either share a global value (if
> > server-2 did nothing) or a binding local to the group (if server-2
> > dynamically bound the variable).
> > 
> > The goal here is that worker-1 and worker-2 do not need to know
> > whether server-1 is in fact the only server (and the variable is
> > `really' global) or whether server-1 is running in parallel with
> > another server (and the variable is only `global' to the group).
> 
> This model is at odds with the standard, which specifies that a dynamic
> binding may not outlive the execution of the form that created it. 
> Specifically, it specifies that a dynamic binding has dynamic extent,
> which is defined as:
> 
> an extent whose duration is bounded by points of establishment and
> disestablishment within the execution of a particular form.
>                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> This leaves you with a problem in the following case:
> 
> (defun server-fn ()
>   (let ( (*dynvar* ...) )
>     (spawn-worker)
>     ...))
> 
> According to the standard, the dynamic binding of *dynvar* becomes
> undefined after server-fn returns.

In this thread, yes, but there is nothing preventing that binding
being visible in other threads of execution.

> So to make this work you'd have to
> change the standard.

I don't think so.


Bj�rn
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002041821160001@192.168.1.71>
In article <···············@fnatte.nada.kth.se>, ·······@nada.kth.se
(=?iso-8859-1?q?Bj=F6rn_Lindberg?=) wrote:

> In this thread, yes, but there is nothing preventing that binding
> being visible in other threads of execution.

That is arguable.

3.1.2.1.1.2 Dynamic Variables

...
A dynamic variable can be referenced outside the dynamic extent of a form
that binds it.  Such a variable is sometimes called a ``global variable''
but is still in all respects just a dynamic variable whose binding happens
to exist in the global environment rather than in some dynamic
environment.

From the glossary:

dynamic extent n. an extent whose duration is bounded by points of
establishment and disestablishment within the execution of a particular
form.

extent n. the interval of time during which a reference to ... a binding
is defined.


IANALL, but it seems to me that the standard requires any reference to a
dynamic variable (in any thread) outside the interval of time that the
binding form is executing to be a refernce to the global binding.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <u11y6xe7.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

> 3.1.2.1.1.2 Dynamic Variables
>
> ...
> A dynamic variable can be referenced outside the dynamic extent of a form
> that binds it.  Such a variable is sometimes called a ``global variable''
> but is still in all respects just a dynamic variable whose binding happens
> to exist in the global environment rather than in some dynamic
> environment.
>
> From the glossary:
>
> dynamic extent n. an extent whose duration is bounded by points of
> establishment and disestablishment within the execution of a particular
> form.
>
> extent n. the interval of time during which a reference to ... a binding
> is defined.
>
>
> IANALL, but it seems to me that the standard requires any reference to a
> dynamic variable (in any thread) outside the interval of time that the
> binding form is executing to be a refernce to the global binding.

You do realize that the same argument applies in the converse
situation.  Look three paragraphs up:

  ``A dynamic variable can be referenced at any time in any program;
    there is no textual limitation on references to dynamic
    variables.  At any given time, all dynamic variables with a given
    name refer to exactly one binding, either in the dynamic environment
    or in the global environment.''

Now if you wish to argue that this section applies to multiple
threads, you'll have to explain that second sentence very carefully.

-- 
~jrm
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1002042301210001@192.168.1.51>
In article <············@comcast.net>, Joe Marshall
<·············@comcast.net> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > 3.1.2.1.1.2 Dynamic Variables
> >
> > ...
> > A dynamic variable can be referenced outside the dynamic extent of a form
> > that binds it.  Such a variable is sometimes called a ``global variable''
> > but is still in all respects just a dynamic variable whose binding happens
> > to exist in the global environment rather than in some dynamic
> > environment.
> >
> > From the glossary:
> >
> > dynamic extent n. an extent whose duration is bounded by points of
> > establishment and disestablishment within the execution of a particular
> > form.
> >
> > extent n. the interval of time during which a reference to ... a binding
> > is defined.
> >
> >
> > IANALL, but it seems to me that the standard requires any reference to a
> > dynamic variable (in any thread) outside the interval of time that the
> > binding form is executing to be a refernce to the global binding.
> 
> You do realize that the same argument applies in the converse
> situation.  Look three paragraphs up:
> 
>   ``A dynamic variable can be referenced at any time in any program;
>     there is no textual limitation on references to dynamic
>     variables.  At any given time, all dynamic variables with a given
>     name refer to exactly one binding, either in the dynamic environment
>     or in the global environment.''
> 
> Now if you wish to argue that this section applies to multiple
> threads, you'll have to explain that second sentence very carefully.

I'm not sure what you mean by "the converse situation", but there are some
things that you have to extrapolate in order for the concept of threads to
make sense at all.  For example, the standard says (or at least strongly
implies) that there is exactly one dynamic environment.  In the presence
of threads there is no reasonable alternative except to say that there is
one dynamic environment *per thread*.  (In fact, one could reasonably
argue that a thread *is* a dynamic environment.)  So one naturally
extrapolates the second sentence to read, "At any given point in the
execution of a thread, all dynamic variables with a given name refer to
exactly one binding, either in the dynamic environment of that thread, or
in the global environment."

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <lln9h8vd.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> I'm not sure what you mean by "the converse situation", but there are some
> things that you have to extrapolate in order for the concept of threads to
> make sense at all.  For example, the standard says (or at least strongly
> implies) that there is exactly one dynamic environment.  In the presence
> of threads there is no reasonable alternative except to say that there is
> one dynamic environment *per thread*.  (In fact, one could reasonably
> argue that a thread *is* a dynamic environment.)  So one naturally
> extrapolates the second sentence to read, "At any given point in the
> execution of a thread, all dynamic variables with a given name refer to
> exactly one binding, either in the dynamic environment of that thread, or
> in the global environment."

There is no reason that a threads dynamic environment cannot be shared
with anothers *provided* that transfer of control to the shared
portion is synchronized.

When a thread leaves a dynamic context it will no longer access the
dynamic binding in effect within that context.  What happens to the
binding in the presence of other threads is an implementation
decision, and *any behavior whatsoever* that does not affect the
semantics of the current thread would seem fair game for an extension.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-1102041027230001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > I'm not sure what you mean by "the converse situation", but there are some
> > things that you have to extrapolate in order for the concept of threads to
> > make sense at all.  For example, the standard says (or at least strongly
> > implies) that there is exactly one dynamic environment.  In the presence
> > of threads there is no reasonable alternative except to say that there is
> > one dynamic environment *per thread*.  (In fact, one could reasonably
> > argue that a thread *is* a dynamic environment.)  So one naturally
> > extrapolates the second sentence to read, "At any given point in the
> > execution of a thread, all dynamic variables with a given name refer to
> > exactly one binding, either in the dynamic environment of that thread, or
> > in the global environment."
> 
> There is no reason that a threads dynamic environment cannot be shared
> with anothers *provided* that transfer of control to the shared
> portion is synchronized.
> 
> When a thread leaves a dynamic context it will no longer access the
> dynamic binding in effect within that context.  What happens to the
> binding in the presence of other threads is an implementation
> decision, and *any behavior whatsoever* that does not affect the
> semantics of the current thread would seem fair game for an extension.

OK, I'll buy that.  But I'm probably not the person you need to convince.

E.
From: Kalle Olavi Niemitalo
Subject: When is a variable a dynamic variable?
Date: 
Message-ID: <87d68mqbkm.fsf_-_@Astalo.kon.iki.fi>
I don't understand the second condition in 3.1.2.1.1.2.

# A variable is a dynamic variable if one of the following conditions hold:
#
#   * It is locally declared or globally proclaimed special.
#
#   * It occurs textually within a form that creates a dynamic binding for a
#     variable of the same name, and the binding is not shadowed[2] by a
#     form that creates a lexical binding of the same variable name.

I have three interpretations for the second condition and I
don't think any of them are correct.

1. The "form that creates a dynamic binding" is just something
   like a LET form; the binding is dynamic only if declared or
   proclaimed so.

     (let ((x 1))
       (declare (special x))
       x)

   The LET form creates a dynamic binding for X, and the
   variable at the end is textually within the form.
   However, the first condition already covers this case.

2. The "form that creates a dynamic binding" could be something
   that creates a dynamic binding even without a separate
   declaration.  I can only think of PROGV here.

     (let ((x 1))
       (progv '(x) '(2)
         x))

   Now, the last reference to X is textually within the PROGV
   form that creates a dynamic binding for a variable of the
   name X, and the binding doesn't seem to be shadowed either.
   So according to my reading, the form should evaluate to 2;
   but that would make compilation of PROGV difficult.

3. Being "textually" within the form is a looser requirement than
   the one made in 3.3.4 Declaration Scope.

     (let ((x 2))
       (declare (special x))
       (let ((x 1))
         (let ((x (- x)))
           (declare (special x))
           x)))

   The variable X occurring in the form (- x) is textually within
   the last LET form, which creates a dynamic binding for a
   variable of the name X.  So this would be a dynamic variable,
   and the top-level form would evaluate to -2.  In CLISP 2.30,
   it actually does that; but in SBCL 0.8.6.34, the result is -1.
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0de0o$pto$1@f1node01.rhrz.uni-bonn.de>
Kalle Olavi Niemitalo wrote:

> I don't understand the second condition in 3.1.2.1.1.2.
> 
> # A variable is a dynamic variable if one of the following conditions hold:
> #
> #   * It is locally declared or globally proclaimed special.
> #
> #   * It occurs textually within a form that creates a dynamic binding for a
> #     variable of the same name, and the binding is not shadowed[2] by a
> #     form that creates a lexical binding of the same variable name.
> 
> I have three interpretations for the second condition and I
> don't think any of them are correct.

I think the first condition refers to the LOCALLY special form. See also 
  "3.1.2.1.1.4 Symbols Naming Both Lexical and Dynamic Variables"

> 3. Being "textually" within the form is a looser requirement than
>    the one made in 3.3.4 Declaration Scope.
> 
>      (let ((x 2))
>        (declare (special x))
>        (let ((x 1))
>          (let ((x (- x)))
>            (declare (special x))
>            x)))
> 
>    The variable X occurring in the form (- x) is textually within
>    the last LET form, which creates a dynamic binding for a
>    variable of the name X.  So this would be a dynamic variable,
>    and the top-level form would evaluate to -2.  In CLISP 2.30,
>    it actually does that; but in SBCL 0.8.6.34, the result is -1.

This should return -1, because the right hand side of the innermost let 
refers to the immediately surrounding let. The new scope is not "active" 
there yet.

Compare this with the following:

(let ((x 2))
   (declare (special x))
   (let ((x 1))
     (let ((x (locally (declare (special x)) (- x))))
       x)))

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kalle Olavi Niemitalo
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <87ptckrb8n.fsf@Astalo.kon.iki.fi>
Pascal Costanza <········@web.de> writes:

> I think the first condition refers to the LOCALLY special form.

AFAIK, the only difference between (locally ...) and (let () ...)
is that when the LOCALLY form appears at top level, the forms in
it are also considered to be at top level.  No, I think "locally
declared" in the first condition refers to any "local declaration"
(see the glossary), regardless of whether it is in a LOCALLY form.

> See also "3.1.2.1.1.4 Symbols Naming Both Lexical and Dynamic
> Variables"

I don't see anything relevant there.

> This should return -1, because the right hand side of the innermost
> let refers to the immediately surrounding let.

Then, do you think this is a bug in CLISP 2.30 (rather than in
SBCL 0.8.6.34)?  I also looked in the release notes of later
versions of both implementations and didn't find a statement
that this behavior would have been changed.

> The new scope is not "active" there yet.

It seems to me that the "textually" word in the second condition
can be interpreted to apply even when the scope is not active,
and that CLISP 2.30 is using this interpretation.

If this interpretation is not correct (and I hope it is not,
because it would make the SPECIAL declaration scope differently
from all other declarations), then what form triggers the second
condition but not the first?

If no such form exists, then I think the second condition should
be removed, as it only serves to confuse.
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0fged$1u9$1@newsreader2.netcologne.de>
Kalle Olavi Niemitalo wrote:

> Pascal Costanza <········@web.de> writes:
> 
> 
>>I think the first condition refers to the LOCALLY special form.
> 
> AFAIK, the only difference between (locally ...) and (let () ...)
> is that when the LOCALLY form appears at top level, the forms in
> it are also considered to be at top level.  No, I think "locally
> declared" in the first condition refers to any "local declaration"
> (see the glossary), regardless of whether it is in a LOCALLY form.

ok

>>See also "3.1.2.1.1.4 Symbols Naming Both Lexical and Dynamic
>>Variables"
> 
> I don't see anything relevant there.

ok

>>This should return -1, because the right hand side of the innermost
>>let refers to the immediately surrounding let.
> 
> Then, do you think this is a bug in CLISP 2.30 (rather than in
> SBCL 0.8.6.34)?

Yes.

>>The new scope is not "active" there yet.
> 
> It seems to me that the "textually" word in the second condition
> can be interpreted to apply even when the scope is not active,
> and that CLISP 2.30 is using this interpretation.
> 
> If this interpretation is not correct (and I hope it is not,
> because it would make the SPECIAL declaration scope differently
> from all other declarations), then what form triggers the second
> condition but not the first?
> 
> If no such form exists, then I think the second condition should
> be removed, as it only serves to confuse.

Se the description of LET and LET*. There, the spec says the following:

"let and let* create new variable bindings and execute a series of forms 
that use these bindings. [...] The form [...] first evaluates the 
expressions init-form-1, init-form-2, and so on, in that order, saving 
the resulting values. Then all of the variables varj are bound to the 
corresponding values; each binding is lexical unless there is a special 
declaration to the contrary."

To me, this clearly indicates that the bindings are created after the 
right hand sides are evaluated. A special declaration refers to the new 
binding, not to the previous one.

This complies with the general idea in Common Lisp that you can choose 
from different semantics if you need them. If the special declaration 
would also be valid for the right hand sides, how would you switch to 
the previous lexical binding for those scopes if that is what you really 
need?


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Kalle Olavi Niemitalo
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <87vfmcteh3.fsf@Astalo.kon.iki.fi>
Pascal Costanza <········@web.de> writes:

> Kalle Olavi Niemitalo wrote:
>> Then, do you think this is a bug in CLISP 2.30 (rather than in
>> SBCL 0.8.6.34)?
>
> Yes.

According to the literal interpretation of "textually", the form

  (let ((x 'special))
    (declare (special x))
    (let ((x 'lexical))
      (let* ((y (list x))
             (x (list y)))
        (declare (special x))
        x)))

should return ((SPECIAL)).  In SBCL 0.8.6.34, CMUCL 18e, and
GCL 2.4.0, it returns ((LEXICAL)).  In CLISP 2.30, it signals
an error:

  *** - POSITION: :START = 1 should not be greater than :END = 0

This is clearly a bug, so I suppose you are right and the result
of the simpler form was also just a bug.

> To me, this clearly indicates that the bindings are created after the
> right hand sides are evaluated. A special declaration refers to the
> new binding, not to the previous one.

The scope of the binding was not at issue.  A special declaration
both makes the binding dynamic and makes uses of the symbol refer
to the dynamic variable.  The issue was whether the latter effect
would have larger scope than the binding.

Now that this interpretation has been shot down, I again wonder
how the two conditions of 3.1.2.1.1.2 differ from each other.
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gdc9$17h4$1@f1node01.rhrz.uni-bonn.de>
Kalle Olavi Niemitalo wrote:

> Pascal Costanza <········@web.de> writes:

> According to the literal interpretation of "textually", the form
> 
>   (let ((x 'special))
>     (declare (special x))
>     (let ((x 'lexical))
>       (let* ((y (list x))
>              (x (list y)))
>         (declare (special x))
>         x)))
> 
> should return ((SPECIAL)).

According to the definition of LET and LET* it should clearly return 
((LEXICAL)). I don't know what you mean by "literal" here.

> The scope of the binding was not at issue.  A special declaration
> both makes the binding dynamic and makes uses of the symbol refer
> to the dynamic variable.  The issue was whether the latter effect
> would have larger scope than the binding.
> 
> Now that this interpretation has been shot down, I again wonder
> how the two conditions of 3.1.2.1.1.2 differ from each other.

I am losing track. However, think about what you expect as a result from 
the following expression:

(let ((x 5))
   (let ((x (1+ x)))
     x))

Should this return 6 or run into an infinite loop? ;)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: rmagere
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gdrs$ekm$1@news.ox.ac.uk>
>Pascal Costanza wrote:

>> Kalle Olavi Niemitalo wrote:
>> According to the literal interpretation of "textually", the form
>>
>>   (let ((x 'special))
>>     (declare (special x))
>>     (let ((x 'lexical))
>>       (let* ((y (list x))
>>              (x (list y)))
>>         (declare (special x))
>>         x)))
>>
>> should return ((SPECIAL)).  In SBCL 0.8.6.34, CMUCL 18e, and
>> GCL 2.4.0, it returns ((LEXICAL)).  In CLISP 2.30, it signals
>> an error:
>>   *** - POSITION: :START = 1 should not be greater than :END = 0

>
> According to the definition of LET and LET* it should clearly return
> ((LEXICAL)). I don't know what you mean by "literal" here.

ACL v5.0.1 returns ((SPECIAL))


> I am losing track. However, think about what you expect as a result
> from the following expression:
>
> (let ((x 5))
>    (let ((x (1+ x)))
>      x))
>
> Should this return 6 or run into an infinite loop? ;)
>
And this obviously returns 6.
From: Fred Gilham
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <u7fzdg2gp6.fsf@snapdragon.csl.sri.com>
"rmagere" <·······@*the-mail-that-burns*.com> writes:

> >Pascal Costanza wrote:
> 
> >> Kalle Olavi Niemitalo wrote:
> >> According to the literal interpretation of "textually", the form
> >>
> >>   (let ((x 'special))
> >>     (declare (special x))
> >>     (let ((x 'lexical))
> >>       (let* ((y (list x))
> >>              (x (list y)))
> >>         (declare (special x))
> >>         x)))
> >>
> >> should return ((SPECIAL)).  In SBCL 0.8.6.34, CMUCL 18e, and
> >> GCL 2.4.0, it returns ((LEXICAL)).  In CLISP 2.30, it signals
> >> an error:
> >>   *** - POSITION: :START = 1 should not be greater than :END = 0
> 
> >
> > According to the definition of LET and LET* it should clearly return
> > ((LEXICAL)). I don't know what you mean by "literal" here.
> 
> ACL v5.0.1 returns ((SPECIAL))

But ACL 6.2 returns ((LEXICAL)):

snapdragon:~/logo > ~/acl6.2/clim 
International Allegro CL Enterprise Edition
6.2 [Linux (x86)] (Aug 6, 2003 7:43)
Copyright (C) 1985-2002, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.

This development copy of Allegro CL is licensed to:
   [5377] SRI International

;; Optimization settings: safety 1, space 1, speed 1, debug 2.
;; For a complete description of all compiler switches given the current optimization
;; settings evaluate (EXPLAIN-COMPILER-SETTINGS).
CL-USER(1):  (let ((x 'special))
    (declare (special x))
    (let ((x 'lexical))
      (let* ((y (list x))
             (x (list y)))
        (declare (special x))
        x)))
((LEXICAL))


-- 
Fred Gilham                                   ······@csl.sri.com
I think it's pretty obvious that the worship of that false idol known
as the State has, in the 20th Century, had some very bad effects. The
historians I'm familiar with have settled on the number of dead as 177
million, although I've seen estimates of up to 200 million.
                                                          -Bob Wallace
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gg08$17he$1@f1node01.rhrz.uni-bonn.de>
rmagere wrote:

>>Pascal Costanza wrote:
> 
> 
>>>Kalle Olavi Niemitalo wrote:
>>>According to the literal interpretation of "textually", the form
>>>
>>>  (let ((x 'special))
>>>    (declare (special x))
>>>    (let ((x 'lexical))
>>>      (let* ((y (list x))
>>>             (x (list y)))
>>>        (declare (special x))
>>>        x)))
>>>
>>>should return ((SPECIAL)).  In SBCL 0.8.6.34, CMUCL 18e, and
>>>GCL 2.4.0, it returns ((LEXICAL)).  In CLISP 2.30, it signals
>>>an error:
>>>  *** - POSITION: :START = 1 should not be greater than :END = 0
> 
> 
>>According to the definition of LET and LET* it should clearly return
>>((LEXICAL)). I don't know what you mean by "literal" here.
> 
> 
> ACL v5.0.1 returns ((SPECIAL))

LispWorks returns ((LEXICAL)).

Should we hire a language lawyer? ;)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Rmagere
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gl36$hg3$1@news.ox.ac.uk>
>Pascal Costanza wrote:
>
>> rmagere wrote:
>> ACL v5.0.1 returns ((SPECIAL))
>
> LispWorks returns ((LEXICAL)).
>
> Should we hire a language lawyer? ;)
>
It would be interesting to know what does ACL 6.2 return (if I can be bother
I'll install the demo).
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gnpv$9dc$1@newsreader2.netcologne.de>
Rmagere wrote:

>>Pascal Costanza wrote:
>>
>>
>>>rmagere wrote:
>>>ACL v5.0.1 returns ((SPECIAL))
>>
>>LispWorks returns ((LEXICAL)).
>>
>>Should we hire a language lawyer? ;)
>>
> 
> It would be interesting to know what does ACL 6.2 return (if I can be bother
> I'll install the demo).

I don't have ACL at hand. BTW, the above test was done with LispWorks 
4.2 Personal Edition on Windows.

LispWorks 4.3 for Mac OS X and Macintosh Common Lisp also return 
((LEXICAL)).

((LEXICAL)) vs. ((SPECIAL)) 4:2 ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Jorge Tavares
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gv5v$a3t$1@rena.mat.uc.pt>
Hi,

Pascal Costanza wrote:

> I don't have ACL at hand. BTW, the above test was done with LispWorks 
> 4.2 Personal Edition on Windows.
> 
> LispWorks 4.3 for Mac OS X and Macintosh Common Lisp also return 
> ((LEXICAL)).
> 
> ((LEXICAL)) vs. ((SPECIAL)) 4:2 ;)
> 

Well, in ACL Enterprise 6.1 for Windows it returns ((LEXICAL)).


Regards,
Jorge

-- 
Jorge Tavares

"An engineer is someone who can do for ten shillings
  what any fool can do for a pound." - Neville Shute
From: Kalle Olavi Niemitalo
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <87ptckt3du.fsf@Astalo.kon.iki.fi>
"Rmagere" <·······@*the*mail*that*burns*.com> writes:

> It would be interesting to know what does ACL 6.2 return (if I can be bother
> I'll install the demo).

Allegro CL 6.2 at telnet://prompt.franz.com returns ((LEXICAL)).
From: Rmagere
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gva0$ld8$1@news.ox.ac.uk>
Kalle Olavi Niemitalo wrote:
> "Rmagere" <·······@*the*mail*that*burns*.com> writes:
>
>> It would be interesting to know what does ACL 6.2 return (if I can
>> be bother I'll install the demo).
>
> Allegro CL 6.2 at telnet://prompt.franz.com returns ((LEXICAL)).

Well I guess that now we know what is the accepted interpretation.
By the way the telnet prompt is quite cool.
From: Frode Vatvedt Fjeld
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <2hd68jsybr.fsf@vserver.cs.uit.no>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Allegro CL 6.2 at telnet://prompt.franz.com returns ((LEXICAL)).

Seems to me it returns lexical in interpreted mode, and special when
compiled.

-- 
Frode Vatvedt Fjeld
From: Pascal Costanza
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0gngn$90h$1@newsreader2.netcologne.de>
rmagere wrote:

>>I am losing track. However, think about what you expect as a result
>>from the following expression:
>>
>>(let ((x 5))
>>   (let ((x (1+ x)))
>>     x))
>>
>>Should this return 6 or run into an infinite loop? ;)
>>
> 
> And this obviously returns 6.

That's why I think that the special declaration in

(let ((x x))
   (declare (special x))
   ...)

should only cover the left x. The right-hand side stuff is the "old" 
stuff and left-hand side stuff is the "new" stuff. Letting the special 
declaration also cover the right-hand side but at the same moment refer 
it to its previous binding would be counter-intuitive IMHO, because this 
would mean that the right-hand side is influenced by both "old" and 
"new" stuff.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Tim Bradshaw
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <fbc0f5d1.0402130209.6b12ef5d@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@newsreader2.netcologne.de>...
> rmagere wrote:
> 
> >>I am losing track. However, think about what you expect as a result
> >>from the following expression:
> >>
> >>(let ((x 5))
> >>   (let ((x (1+ x)))
> >>     x))
> >>
> >>Should this return 6 or run into an infinite loop? ;)
> >>
> > 
> > And this obviously returns 6.
> 
> That's why I think that the special declaration in
> 
> (let ((x x))
>    (declare (special x))
>    ...)
> 
> should only cover the left x. The right-hand side stuff is the "old" 
> stuff and left-hand side stuff is the "new" stuff. Letting the special 
> declaration also cover the right-hand side but at the same moment refer 
> it to its previous binding would be counter-intuitive IMHO, because this 
> would mean that the right-hand side is influenced by both "old" and 
> "new" stuff.
> 

This is obviously correct.  I think we shouldn't be harking on about
what a particular implementation returns but should actually look at
what the spec says, and it's clear that the declaration in the above
form applies to the binding of X, established by that form, not to any
other binding of X which might exist, and in particular not to
whatever binding of X is used to compute the value of this binding
here.

I think that a correct rewrite of a LET form which establishes a
single binding (I'm sticking to the single binding case because I
don't have a CL which I can run here and I'm not up to writing the
multiple-binding macro) is:

(defmacro slet (((var &optional (init nil))) &body forms)
  (let ((temp (make-symbol "TEMP")))
    `(let ((,temp ,init))
       (let ((,var ,temp))
         ,@forms))))

Now, replacing the gensym with an interned symbol for clarity:

(slet ((x x))
  (declare (special x))
   x)
->
(let ((temp x))
  (let ((x temp))
    (declare (special x))
     x))

And this makes it really clear to what any special declaration must
apply.

--tim
From: Tim Bradshaw
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <ey3k72r28rv.fsf@cley.com>
* rmagere  wrote:

> ACL v5.0.1 returns ((SPECIAL))

I think this must be wrong.  Duane can comment, I'm sure, but I'm
really surprised that it gets this.  Looking at the code (and assuming
for the sake of argument that there is no globally special X, although
I don't think this actually matters):

(defun spectest ()
  (let ((x 'special))                   ;special binding of X[1]
    (declare (special x))               ;because of this declaration
     (let ((x 'lexical))                ;lexical binding of X[2]
       (let* ((y (list x))              ;Y[1] is lexical, 
                                        ;value is value of X[2]
              (x (list y)))             ;X[3] is bound specially, 
                                        ;value is Y[1]
         (declare (special x))          ;because of this special declaration
         x))))                          ;refers to X[3]


--tim
From: Duane Rettig
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <4hdxvu6xy.fsf@franz.com>
Tim Bradshaw <···@cley.com> writes:

> * rmagere  wrote:
> 
> > ACL v5.0.1 returns ((SPECIAL))
> 
> I think this must be wrong.  Duane can comment, I'm sure, but I'm
> really surprised that it gets this.  Looking at the code (and assuming
> for the sake of argument that there is no globally special X, although
> I don't think this actually matters):
> 
> (defun spectest ()
>   (let ((x 'special))                   ;special binding of X[1]
>     (declare (special x))               ;because of this declaration
>      (let ((x 'lexical))                ;lexical binding of X[2]
>        (let* ((y (list x))              ;Y[1] is lexical, 
>                                         ;value is value of X[2]
>               (x (list y)))             ;X[3] is bound specially, 
>                                         ;value is Y[1]
>          (declare (special x))          ;because of this special declaration
>          x))))                          ;refers to X[3]

The correct answer is ((LEXICAL)).  We fixed the interpreter circa
Allegro CL 6.x, and we've also fixed the compiler (along with a few
other scoping bugs) in our upcoming release.

I haven't looked at this example closely, but this whole issue
might be the result of a specials scoping change between CLtL and
CLtL2/ANS, where the scoping of specials were incompatibly changed
so as to bring them into line with other scoping rules (i.e. CLtL1
was inconsistent or underspecified).

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Kalle Olavi Niemitalo
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <877jypub3q.fsf@Astalo.kon.iki.fi>
Duane Rettig <·····@franz.com> writes:

> I haven't looked at this example closely, but this whole issue
> might be the result of a specials scoping change between CLtL and
> CLtL2/ANS, where the scoping of specials were incompatibly changed
> so as to bring them into line with other scoping rules (i.e. CLtL1
> was inconsistent or underspecified).

Was the second condition in section 3.1.2.1.1.2 changed in this process?
If it wasn't, should it have been?

I don't have CLtL1 myself so I can't check from there.
CLtL2 seems to be downloadable but I haven't found the original.
From: Rmagere
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <c0h4ba$n6i$1@news.ox.ac.uk>
Tim Bradshaw wrote:
> * rmagere  wrote:
>
>> ACL v5.0.1 returns ((SPECIAL))
>
> I think this must be wrong.  Duane can comment, I'm sure, but I'm
> really surprised that it gets this.  Looking at the code (and assuming
> for the sake of argument that there is no globally special X, although
> I don't think this actually matters):
>
> (defun spectest ()
>   (let ((x 'special))                   ;special binding of X[1]
>     (declare (special x))               ;because of this declaration
>      (let ((x 'lexical))                ;lexical binding of X[2]
>        (let* ((y (list x))              ;Y[1] is lexical,
>                                         ;value is value of X[2]
>               (x (list y)))             ;X[3] is bound specially,
>                                         ;value is Y[1]
>          (declare (special x))          ;because of this special
>          declaration x))))                          ;refers to X[3]
>
>

I just run your code and (spectest) returns ((SPECIAL))
If it helps I am using Allegro CL Professional Edition 5.0.1 Release:
29-Jun-99 16.41 (fully patched up).
From: Kalle Olavi Niemitalo
Subject: Re: When is a variable a dynamic variable?
Date: 
Message-ID: <87smhgt6ms.fsf@Astalo.kon.iki.fi>
Pascal Costanza <········@web.de> writes:

> I don't know what you mean by "literal" here.

The second condition in 3.1.2.1.1.2 involves checking whether the
symbol "occurs textually within a form that creates a dynamic
binding for a variable of the same name, and the binding is not
shadowed [...]".  My literal interpretation of "textually" was
that if the binding is not shadowed, then the occurrence of the
symbol could be really anywhere within the form -- including
places where the scope of the binding hasn't even started yet.

> Should this return 6 or run into an infinite loop? ;)

It should return 6.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c0advg$sck$1@f1node01.rhrz.uni-bonn.de>
Joe Marshall wrote:
> Pascal Costanza <········@web.de> writes:
> 
>>Thanks for your response!
>>
>>However, now I am really confused. Your two previous comments sound to
>>me as if a dynamic closure needs to preserve sharing but
>>shouldn't. This doesn't make sense to me, so I am clearly missing
>>something.
>>
>>Let's see. Here is how I understand your example:
>>
>>
>>                   worker-1
>>                  /
>>          server-1
>>       	/        \
>>        /          worker-2
>>program
>>        \          worker-3
>>         \        /
>>          server-2
>>                  \
>>                   worker-4
>>
>>You would like to be able to change a shared binding from within a
>>worker thread that is bound in a server thread, but not in the global
>>program thread.
> 
> Ok, under `normal' circumstances, a thread will share the top-level
> binding of a special variable with all other threads.  Assignments
> made by this thread are seen by other threads, and this thread will
> see assignments made other threads.  If a thread wants to change the
> value in a thread-local way, it simply binds the dynamic value and no
> other thread sees it.

OK, I see where my misunderstanding comes from. I have expected dynamic 
variables in subthreads to behave exactly like you describe and wasn't 
aware that they usually just refer to the global binding instead of 
those present in the threads that created them.

So (correctly implemented) dynamic closures would be just a way to keep 
dynamic bindings across threads. (Which in turn means that my attempts 
to implement them are not correct.)

Thanks again for your feedback.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ekt74rc2.fsf@comcast.net>
Pascal Costanza <········@web.de> writes:

> Sorry again for posting so many times about this issue, but I have
> actually found some code at
> http://groups.google.com/groups?selm=1990Dec28.093020.17301%40Think.COM

Google for EVCP and include something else lisp-like or you'll get things like 
``Executive Vice Chancellor and Provost''

-- 
~jrm
From: Bulent Murtezaoglu
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87znbx5vho.fsf@cubx.internal>
>>>>> "JRM" == Joe Marshall <·············@comcast.net> writes:

    JRM> ·········@jpl.nasa.gov (Erann Gat) writes:
    >> Thread-local is the only behavior that makes sense for dynamic
    >> binding.

    JRM> Not necessarily.  In the default case, yes --- if thread A
    JRM> binds *print-base* to 8 then thread B should not see the
    JRM> change.  If B subsequently binds it to 16, A should not see
    JRM> the change.

Right.

    JRM> But suppose I wrote this:

    JRM> (defun foo (thunk) (let ((*print-base* 16)) (synchronize
    JRM> (process-run-function thunk))))

    JRM> It may make sense for this process and the spawned process to
    JRM> share the dynamic binding of *print-base*.

The intuition (mine at any rate) is for the stack-like behaviour of
dynamic bindings not to be violated even in the presence of 
threading.  I don't see this as conflicting with thread-local bindings
(and assignment thereto) as long as the spawned thread inherits (a
copy of?) the binding stack.  The interesting case would be setf'ing
from the subthread which I'd expect to only affect the binding in the
subthread by default.  So if *print-base* if setf'ed to 20 in the
subprocess, seeing it changed in the creating thread would be
counterintuitive for me.  Maybe having used unix fork before using
lightweight threads is warping my senses?  I'd expect lexicals to be 
shared so I suspect this is a lispy intuition.

cheers,

BM
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcvfzdpbgrs.fsf@famine.OCF.Berkeley.EDU>
Bulent Murtezaoglu <··@acm.org> writes:

> >>>>> "JRM" == Joe Marshall <·············@comcast.net> writes:
> 
>     JRM> ·········@jpl.nasa.gov (Erann Gat) writes:
>     >> Thread-local is the only behavior that makes sense for dynamic
>     >> binding.
> 
>     JRM> Not necessarily.  In the default case, yes --- if thread A
>     JRM> binds *print-base* to 8 then thread B should not see the
>     JRM> change.  If B subsequently binds it to 16, A should not see
>     JRM> the change.
> 
> Right.
> 
>     JRM> But suppose I wrote this:
> 
>     JRM> (defun foo (thunk) (let ((*print-base* 16)) (synchronize
>     JRM> (process-run-function thunk))))
> 
>     JRM> It may make sense for this process and the spawned process to
>     JRM> share the dynamic binding of *print-base*.
> 
> The intuition (mine at any rate) is for the stack-like behaviour of
> dynamic bindings not to be violated even in the presence of 
> threading.  I don't see this as conflicting with thread-local bindings
> (and assignment thereto) as long as the spawned thread inherits (a
> copy of?) the binding stack.

I guess this depends on what you view a thread-spawning operation as
acutally doing, but I *don't* view the new thread as being in the
dynamic contour of the old thread.  That's the magic thing
thread-creation functions do, they start something new back behind any
dynamic contours.  You'll notice how threads don't return back to
their spawning points.

As a practical matter, having a thread inherit the dynamic binding
state of its parent would leave the possiblity of really weird, hard
to find bugs.  Say you use globals to communicate between threads.
You have a function somewhere that binds one of these globals.  If a
thread-spawning function is anywhere in the dynamic path from the
binding function, the spawned threads will have no way to see the
global variable, but *only* when they're spawned from the appropriate
contour; sometimes it'll be bound, sometimes not.  Looking at the code
for the new thread, and looking at the spawning code won't help you
figure out what's going wrong.  This sounds way too much like dynamic
closures.

I think a much better approach is to have the MAKE-PROCESS function
take a set of initial dynamic bindings.  If you really want a private
channel for communication between two threads, proclaim a gensym to be
special, and pass it to the new thread.

> The interesting case would be setf'ing
> from the subthread which I'd expect to only affect the binding in the
> subthread by default.  So if *print-base* if setf'ed to 20 in the
> subprocess, seeing it changed in the creating thread would be
> counterintuitive for me.

Then I suspect you don't actually want new threads to inherit their
parents' dynamic binding state :-)

> Maybe having used unix fork before using
> lightweight threads is warping my senses?  I'd expect lexicals to be 
> shared so I suspect this is a lispy intuition.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <r7x976qj.fsf@comcast.net>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> I guess this depends on what you view a thread-spawning operation as
> acutally doing, but I *don't* view the new thread as being in the
> dynamic contour of the old thread.  That's the magic thing
> thread-creation functions do, they start something new back behind any
> dynamic contours.  You'll notice how threads don't return back to
> their spawning points.

You'll notice how I put in a call to `synchronize' around the thread
creation to indicate that I *do* want the thread to return back to the
spawning process.

It really depends on how one intends to use threads.  One model is
`separate processes that have access to the same objects', but another
model that is often used is `worker threads that are manged by a
master process'.  Another is `speculative work that may pay off
later'.  In the first model, you probably would not want to share
bindings, but in the second and third models, you may.  I have found
that when implementing the second model that it was a pain in the butt
to ensure that all the workers were in the correct dynamic contour.
(There was no mechanism to query the current dynamic contour, so I had
to hack a way to crawl the dynamic binding stack to find the binding
cells!)

> As a practical matter, having a thread inherit the dynamic binding
> state of its parent would leave the possiblity of really weird, hard
> to find bugs.  

When it is unexpected, sure.  Having a thread *not* inherit the
dynamic binding state of its parent can *also* leave really weird
bugs, too.  There are some things dynamically bound at the top level
REPL that you may not expect.

> This sounds way too much like dynamic closures.

Which existed on the Lisp machine.  They were esoteric, but they had
their uses.

> I think a much better approach is to have the MAKE-PROCESS function
> take a set of initial dynamic bindings.  

Yes, but enumerating the initial bindings can be problematic.

-- 
~jrm
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <vfml777d.fsf@comcast.net>
Bulent Murtezaoglu <··@acm.org> writes:

>>>>>> "JRM" == Joe Marshall <·············@comcast.net> writes:
>
>     JRM> ·········@jpl.nasa.gov (Erann Gat) writes:
>     >> Thread-local is the only behavior that makes sense for dynamic
>     >> binding.
>
>     JRM> Not necessarily.  In the default case, yes --- if thread A
>     JRM> binds *print-base* to 8 then thread B should not see the
>     JRM> change.  If B subsequently binds it to 16, A should not see
>     JRM> the change.
>
> Right.
>
>     JRM> But suppose I wrote this:
>
>     JRM> (defun foo (thunk) (let ((*print-base* 16)) (synchronize
>     JRM> (process-run-function thunk))))
>
>     JRM> It may make sense for this process and the spawned process to
>     JRM> share the dynamic binding of *print-base*.
>
> The intuition (mine at any rate) is for the stack-like behaviour of
> dynamic bindings not to be violated even in the presence of 
> threading.  I don't see this as conflicting with thread-local bindings
> (and assignment thereto) as long as the spawned thread inherits (a
> copy of?) the binding stack.  The interesting case would be setf'ing
> from the subthread which I'd expect to only affect the binding in the
> subthread by default.  So if *print-base* if setf'ed to 20 in the
> subprocess, seeing it changed in the creating thread would be
> counterintuitive for me.  

It wouldn't if the parent thread *hadn't* bound *print-base*. 

-- 
~jrm
From: Bulent Murtezaoglu
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87k72y68ti.fsf@cubx.internal>
>>>>> "JRM" == Joe Marshall <·············@comcast.net> writes:
[...]
    BM> The intuition (mine at any rate) is for the stack-like
    BM> behaviour of dynamic bindings not to be violated even in the
    BM> presence of threading.  I don't see this as conflicting with
    BM> thread-local bindings (and assignment thereto) as long as the
    BM> spawned thread inherits (a copy of?) the binding stack.  The
    BM> interesting case would be setf'ing from the subthread which I'd
    BM> expect to only affect the binding in the subthread by default.
    BM> So if *print-base* if setf'ed to 20 in the subprocess, seeing
    BM> it changed in the creating thread would be counterintuitive for
    BM> me.

    JM> It wouldn't if the parent thread *hadn't* bound *print-base*.

Right again.  How did you know?  So do you know what system[s] behaved
this way?  (Maybe not even lisp, but some esoteric grad school seminar
language?)  As Thomas Burdick observed this is not an altogether
coherent way to think even if one assumes parent/child relationships
among threads (think?  I was writing right from the gut w/o thinking
up examples).

cheers,

BM
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <RiuUb.229141$xy6.1164044@attbi_s02>
Erann Gat wrote:

> In article <·······················@attbi_s52>, Dave Roberts
> <·····@re-move.droberts.com> wrote:
> 
>> Erann Gat wrote:
>> 
>> > In article <······················@attbi_s03>, Dave Roberts
>> > <·····@re-move.droberts.com> wrote:
>> >> Every other threading system does this all the time (C, Java,
>> >> etc.). No issues.
>> > 
>> > You are mistaken.
>> 
>> Mistaken how?
> 
> You are mistaken in your claim that there are "no issues."

I'd just say that "issue" is in the eye of the beholder. One man's "issue"
is another man's "no biggie." Again, it all depends on what you are
optimizing for. State all your objectives and then we can evaluate the
various solutions against those. Without those objectives, every solution
is possible, though some have different strengths and weaknesses.

> 
>> Every other threading system I have used does exactly this for
>> state shared between multiple threads. I have used them quite
>> successfully, so if I'm too mistaken, I don't get it. ;-) We must be
>> having a semantic or terminology difference.
> 
> Possibly.  But just because you have not encountered (or noticed) the
> issues does not mean they do not exist.

Well, I think I have done enough programming over my 25 years to understand
the issues. Again, state your objectives and then we can evaluate
solutions. Without those, everything just becomes an abstract argument with
no grounding.

> 
>> Now, you can also have thread-local variables, too.
>> If that's the behavior you want, that's fine.
> 
> It's not a question of what I want.  Thread-local is the only behavior
> that makes sense for dynamic binding.

Yes, you are right there. See, I was approaching this from a strictly global
sense, not dynamic. For you to keep the same sematics as Lisp has now for
dynamic variables, you are totally right that thread-local is the only
behavior that makes sense. If you just want global state, however, there
are other ways to get there and others do it all the time.

> 
> Of course you can.  You can also take out half the spark plugs to deal
> with adverse torque in a powerful engine.

Again, I wasn't making a value judgement. Put another way, all I said was,
"You can take out half the spark plugs to deal with this... and people do
that all the time." You basically replied, "That's dumb." Whether or not I
agree with you on that, the fact is, it is a solution and people do it all
the time.

> 
>> Both Java and C also support thread-local state, too, if you can
>> break your problem up that way. Note that many times that is distinctly
>> what you do *not* want, however, and you actually require access to state
>> shared across multiple threads.
> 
> That's true, but it has nothing to do with the topic at hand, which is
> dynamic bindings.
> 
> I'll refer you back to some advice you got early on in this discussion:
> stop trying to understand Lisp in terms of C.  Just try to understand it
> on its own terms.

I think I understand it all now, and the issue of sychronizing global state
for sure. Note that I'm not pushing a C model here, I'm just reacting to a
statement you made that basically said extending Lisp to deal with multiple
threads necessitated a certain model. I just said that there are
potentially other ways to solve it. You may not view them as good ways, but
they would work. Now, as you say, if you want to talk about dynamic/special
variables and preserve the same semantics as you have today, you need
thread-local. If what you really want is just global behavior, without
dynamic/special behavior, then there are other ways to get that. Again,
whether those meet your objectives or not, that's a different question. You
might say that preserving the semantics is a given. That's fine. My
reaction would be to say that if you're going to extend the model to
introduce something as deep as threads, it's at least worth a look to see
if you want to keep those same semantics.

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0502040950030001@k-137-79-50-101.jpl.nasa.gov>
In article <························@attbi_s02>, Dave Roberts
<·····@re-move.droberts.com> wrote:
> My reaction would be to say that if you're going to extend the model to
> introduce something as deep as threads, it's at least worth a look to see
> if you want to keep those same semantics.

And my reaction would be: what makes you think that the decision to retain
the semantics of dynamic binding in the presence of threads was made
capriciously?  (And do you realize how presumptuous it is for you to
suggest that it was?)

The decision to keep the same semantics is pretty much a no-brainer. 
Dynamic binding has been around for longer than you've been programming,
and it is a tremendously useful tool.  Just because C and its ilk don't
offer it and as a result those communities have developed all sorts of
clever hacks to work around this deficiency does not change the fact that
they are clever hacks to work around a deficiency that Common Lisp simply
doesn't have.

This is why it is important not to try to map Common Lisp onto your
understanding of C because if you do you will project the constraints of C
onto Common Lisp and you will never achieve enlightenment.

You will also piss a lot of people off.

E.
From: Will Hartung
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvuan0$10l7qs$1@ID-197644.news.uni-berlin.de>
"Erann Gat" <·········@jpl.nasa.gov> wrote in message
·······························@k-137-79-50-101.jpl.nasa.gov...

> This is why it is important not to try to map Common Lisp onto your
> understanding of C because if you do you will project the constraints of C
> onto Common Lisp and you will never achieve enlightenment.

Coming in late. Just trying to make clear that I understand how these things
work.

This is LispWorks, and it befuddles me. I thought I had it grokked, but this
messes me all up.

Thus:
CL-USER 47 > (defvar *special* 1)
*SPECIAL*

CL-USER 48 > *special*
1

CL-USER 49 > (let ((*special* 10))
               (print *special*))

10
10

CL-USER 50 > *special*
1

CL-USER 51 > (defun f4 (stream)
               (print *special* stream)
               (setf *special* 3)
               (print *special* stream))
F4

CL-USER 52 > (let ((*special* 10))
               (f4 *standard-output*))

10
3
3

CL-USER 53 > *special*
1

CL-USER 54 > (f4 *standard-output*)

1
3
3

CL-USER 55 > *special*
3

CL-USER 56 > (setf *special* 1)
1

CL-USER 57 > (let ((*special* 27))
               (mp:process-run-function 'proc-name nil (function f4)
*standard-output*))
#<MP:PROCESS Name PROC-NAME Priority 850000 State "Running">

1
3
CL-USER 58 > *special*
3

aaiiiee!!

So, is this "correct" behavior? Is it consistent? Is it portable? Do other
lisps work this way? Am I not supposed to be surpised that the rebinding of
*special* to 27 didn't get caught by the process-run-function routine?

Regards,

Will Hartung
(·····@msoft.com)
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0502041445090001@k-137-79-50-101.jpl.nasa.gov>
In article <···············@ID-197644.news.uni-berlin.de>, "Will Hartung"
<·····@msoft.com> wrote:

> "Erann Gat" <·········@jpl.nasa.gov> wrote in message
> ·······························@k-137-79-50-101.jpl.nasa.gov...
> 
> > This is why it is important not to try to map Common Lisp onto your
> > understanding of C because if you do you will project the constraints of C
> > onto Common Lisp and you will never achieve enlightenment.
> 
> Coming in late. Just trying to make clear that I understand how these things
> work.
> 
> This is LispWorks, and it befuddles me. I thought I had it grokked, but this
> messes me all up.
> 
> Thus:
> CL-USER 47 > (defvar *special* 1)
> *SPECIAL*
> 
> CL-USER 48 > *special*
> 1
> 
> CL-USER 49 > (let ((*special* 10))
>                (print *special*))
> 
> 10
> 10
> 
> CL-USER 50 > *special*
> 1
> 
> CL-USER 51 > (defun f4 (stream)
>                (print *special* stream)
>                (setf *special* 3)
>                (print *special* stream))
> F4
> 
> CL-USER 52 > (let ((*special* 10))
>                (f4 *standard-output*))
> 
> 10
> 3
> 3
> 
> CL-USER 53 > *special*
> 1
> 
> CL-USER 54 > (f4 *standard-output*)
> 
> 1
> 3
> 3
> 
> CL-USER 55 > *special*
> 3
> 
> CL-USER 56 > (setf *special* 1)
> 1
> 
> CL-USER 57 > (let ((*special* 27))
>                (mp:process-run-function 'proc-name nil (function f4)
> *standard-output*))
> #<MP:PROCESS Name PROC-NAME Priority 850000 State "Running">
> 
> 1
> 3
> CL-USER 58 > *special*
> 3
> 
> aaiiiee!!
> 
> So, is this "correct" behavior? Is it consistent? Is it portable? Do other
> lisps work this way? Am I not supposed to be surpised that the rebinding of
> *special* to 27 didn't get caught by the process-run-function routine?

"Correct" is impossible to say since the standard provides no guidance on
what happens when you spawn a thread.  This behavior does seem to be the
de facto standard.  I presume that what makes you cry "aaiiieee" is that
you expected the spawned process to inherit (a copy of) the dynamic
bindings of the spawning process.  That is also IMO reasonable behavior
and consistent with the standard (as far as I can tell - IANALL).

E.
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcvbrocbxmq.fsf@famine.OCF.Berkeley.EDU>
"Will Hartung" <·····@msoft.com> writes:

> So, is this "correct" behavior? Is it consistent? Is it portable? Do other
> lisps work this way? Am I not supposed to be surpised that the rebinding of
> *special* to 27 didn't get caught by the process-run-function routine?

It's the expected behavior, at least for me.  So as not to repeat
myself in one day, I just wrote my thoughts on this this morning, in
this post, if you're curious: ···············@famine.OCF.Berkeley.EDU

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Edi Weitz
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <m3fzdp1bmf.fsf@bird.agharta.de>
On Thu, 5 Feb 2004 13:11:52 -0800, "Will Hartung" <·····@msoft.com> wrote:

> CL-USER 57 > (let ((*special* 27))
>                (mp:process-run-function 'proc-name nil (function f4)
> *standard-output*))
> #<MP:PROCESS Name PROC-NAME Priority 850000 State "Running">
>
> 1
> 3
> CL-USER 58 > *special*
> 3
>
> aaiiiee!!
>
> So, is this "correct" behavior? Is it consistent? Is it portable? Do
> other lisps work this way? Am I not supposed to be surpised that the
> rebinding of *special* to 27 didn't get caught by the
> process-run-function routine?

Try

  (let ((mp:*process-initial-bindings* (cons '(*special* . 27) mp:*process-initial-bindings*)))
    (mp:process-run-function 'proc-name nil (function f4) *standard-output*))

See <http://cl-cookbook.sourceforge.net/process.html#state>

Cheers,
Edi.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <t_PTb.216520$na.354043@attbi_s04>
Pascal Bourguignon wrote:

> Keeping one  place per thread would  defeat this obvious  (at least to
> me)  idiom.  That  is, I'd  expect global  stuff to  be common  to all
> threads, and special variables like common-lisp:*print-circle* to need
> special, explicit  handling (mutex) when  I start to use  non standard
> stuff like threads.

Coming from a C or Java background, that makes sense to me, too, but I'm
quickly learning that special variable != global. Rather, it equals
"dynamic," and that means viewing it from the point of view of a thread.

-- Dave
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvoilp$1380$1@f1node01.rhrz.uni-bonn.de>
Dave Roberts wrote:

> Pascal Bourguignon wrote:
> 
>>Keeping one  place per thread would  defeat this obvious  (at least to
>>me)  idiom.  That  is, I'd  expect global  stuff to  be common  to all
>>threads, and special variables like common-lisp:*print-circle* to need
>>special, explicit  handling (mutex) when  I start to use  non standard
>>stuff like threads.
> 
> Coming from a C or Java background, that makes sense to me, too, but I'm
> quickly learning that special variable != global. Rather, it equals
> "dynamic," and that means viewing it from the point of view of a thread.

BTW, the Java API offers a concept called "thread local variables". See 
the class ThreadLocal. (I don't remember the package it's in.)

It may give you some further insights to try to understand what you need 
to do to make ThreadLocal behave like full dynamically scoped variables 
a la Common Lisp.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Frode Vatvedt Fjeld
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2h4qu92rnb.fsf@vserver.cs.uit.no>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

>> [..] A variable is an association between (from) a name (in the
>> variable name-space) and a value. This association can be of many
>> kinds, neither of which match your struct very well, to my
>> knowledge.

Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> I think this is wrong, a variable is not an association between a
> _name_ and a value.  In my undestanding, a variable is a _place_
> (where values can be referenced from).

This is not really something that is up for debate, IMHO:

  variable n. a binding in the ``variable'' namespace. See Section
  3.1.2.1.1 (Symbols as Forms).


  binding n. an association between a name and that which the name
  denotes. ``A lexical binding is a lexical association between a name
  and its value.'' [...]


> A lexical variable has one place.  For a lexical variable, we use a
> symbol to name it (or its place).  The name of a lexical variable
> exists only in the source up to the compile time.  At run-time, this
> name is not remembered.

  place n. 1. a form which is suitable for use as a generalized
  reference. 2. the conceptual location referred to by such a place[1].


So I don't think your description of variables is very much in
contradiction with mine.

I'm not hitting you on the head with The Standard solely for the fun
of it... I think it's important to be careful with terminology,
particularly in an area where this is actually standardized.

-- 
Frode Vatvedt Fjeld
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <877jz5kl1y.fsf@thalassa.informatimago.com>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> Frode Vatvedt Fjeld <······@cs.uit.no> writes:
> 
> >> [..] A variable is an association between (from) a name (in the
> >> variable name-space) and a value. This association can be of many
> >> kinds, neither of which match your struct very well, to my
> >> knowledge.
> 
> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > I think this is wrong, a variable is not an association between a
> > _name_ and a value.  In my undestanding, a variable is a _place_
> > (where values can be referenced from).
> 
> This is not really something that is up for debate, IMHO:
> 
>   variable n. a binding in the ``variable'' namespace. See Section
>   3.1.2.1.1 (Symbols as Forms).
> 
> 
>   binding n. an association between a name and that which the name
>   denotes. ``A lexical binding is a lexical association between a name
>   and its value.'' [...]
> 
>
> > A lexical variable has one place.  For a lexical variable, we use a
> > symbol to name it (or its place).  The name of a lexical variable
> > exists only in the source up to the compile time.  At run-time, this
> > name is not remembered.
> 
>   place n. 1. a form which is suitable for use as a generalized
>   reference. 2. the conceptual location referred to by such a place[1].

    binding   = (name , value) 

Where do you store this "binding"?


In the case of a special variable, obviously the binding IS the symbol
(name, value, ...).



In the case of a lexical variable, at compilation time you have names,
but no value. [Or are these non conformant implementations:

clisp:
[29]> (defun f (a) (let ((s 'when)) (macrolet ((stuff (c i) `(,s ,c ,i))) (setq s a) (stuff nil (print :toto)))))
F
[30]> (compile 'f)
ERROR in F :
Not the name of a function: 
*** - Lisp stack overflow. RESET

sbcl:
* (defun f (a) (let ((s 'when)) (macrolet ((stuff (c i) `(,s ,c ,i))) (setq s a) (stuff nil (print :toto)))))
debugger invoked on condition of type SIMPLE-CONDITION:
  The variable S is unbound.


cmucl:
* (defun f (a) (let ((s 'when)) (macrolet ((stuff (c i) `(,s ,c ,i))) (setq s a) (stuff nil (print :toto)))))
F
* (compile 'f)
In: LAMBDA (A)
  (STUFF NIL (PRINT :TOTO))
Error: (during macroexpansion)
Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable S is unbound.
]

And at run-time, the name does not exist anymore, so we have: 
    binding=(value)
and it happens that's exactly the definition (2.) of place:
    place=(value)

So I'd say that lexical binding = place (at run-time).


And note that in the case  of special variables, the symbol contains a
place(2.) (where the value is stored).  A symbol IS a place(1.).

There are two kinds of variables.  Special variables are symbols (that
implement a binding=(name,value)).  Lexical variables are merely names
(implemented by  symbols) at compilation time, and  merely places (2.)
at run-time (you can still  call that a spacio-temporal binding if you
like, but I don't believe in souls :-).


> So I don't think your description of variables is very much in
> contradiction with mine.

Indeed you were seeing the trunk while I was seeing the tail.
 

> I'm not hitting you on the head with The Standard solely for the fun
> of it... I think it's important to be careful with terminology,
> particularly in an area where this is actually standardized.

True.


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Frode Vatvedt Fjeld
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2hptcw1q4w.fsf@vserver.cs.uit.no>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

>> This is not really something that is up for debate, IMHO:
>> 
>>   variable n. a binding in the ``variable'' namespace. See Section
>>   3.1.2.1.1 (Symbols as Forms).
>> 
>>   binding n. an association between a name and that which the name
>>   denotes. ``A lexical binding is a lexical association between a name
>>   and its value.'' [...]

Pascal Bourguignon <····@thalassa.informatimago.com> writes:

>     binding   = (name , value) 
>
> Where do you store this "binding"?
>
> In the case of a special variable, obviously the binding IS the
> symbol (name, value, ...).

No, "binding" and hence "variable" are, by definition, the association
between name and value. This is an abstract concept, and not a
first-class lisp object, or anything much concrete at all. That the
value at run-time often will have to live somewhere concrete is true,
but this somewhere is not given a standard name (and probably for good
reason), although "location" is sometimes used in general, and "cell"
for some particular cases. Don't hi-jack other terminology for
this. It is true that a variable's name is one kind of "place", but
this is not the same as saying e.g:

> [..] So I'd say that lexical binding = place (at run-time).

It seems to me you are trying to map "variable" to something concrete
at the machine-code level, which is fine, but then you use this
mapping to say what a "variable" _is_, which is a bad idea.

A lexical binding's value is typically stored in a location, which
might be a slot in a function's activation frame, a cdr in an cons
cell whose car is the variable's name, or whatever. The notion of
"place" is really part of a completely different part of the language
and terminology, and I think it's just confusing to try to use one
(part of the CL terminology) to describe the other.

>> [..] I think it's important to be careful with terminology,
>> particularly in an area where this is actually standardized.
>
> True.

It's good that you agree with this, but also a bit strange just after
having seen you abuse the terminology once more, even after I pointed
out the de jure definitions, which are quite clear and concise.

-- 
Frode Vatvedt Fjeld
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87hdy8jsi5.fsf@thalassa.informatimago.com>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:
> >> [..] I think it's important to be careful with terminology,
> >> particularly in an area where this is actually standardized.
> >
> > True.
> 
> It's good that you agree with this, but also a bit strange just after
> having seen you abuse the terminology once more, even after I pointed
> out the de jure definitions, which are quite clear and concise.

Sorry.  I'll  be more careful.  It's  also more abstract  than what we
have been used (and abused ;-) to in procedural languages...


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <IUPTb.167732$Rc4.1289220@attbi_s54>
Pascal Bourguignon wrote:

> Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> So I'd say that lexical binding = place (at run-time).
> 
> 
> And note that in the case  of special variables, the symbol contains a
> place(2.) (where the value is stored).  A symbol IS a place(1.).
> 
> There are two kinds of variables.  Special variables are symbols (that
> implement a binding=(name,value)).  Lexical variables are merely names
> (implemented by  symbols) at compilation time, and  merely places (2.)
> at run-time (you can still  call that a spacio-temporal binding if you
> like, but I don't believe in souls :-).

Not that I know what I'm talking about, but it seems sort of like you guys
are arguing the difference between the theoretical model and the typical
implementation, maybe the difference between a simple interpreter and a 
compiler.

-- Dave
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <YyPTb.169781$sv6.911223@attbi_s52>
Pascal Bourguignon wrote:

 
> A lexical  variable has one place.   For a lexical variable,  we use a
> symbol to  name it  (or its  place).  The name  of a  lexical variable
> exists only in  the source up to the compile  time.  At run-time, this
> name is not remembered.

Got it. This helps. I was getting the naming of a variable using a symbol
confused with the use of a symbol to hold a value at top-level. All this
discussion is making it clear now.

-- Dave
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <KTHTb.81978$U%5.446087@attbi_s03>
Frode Vatvedt Fjeld wrote:

> This is quite incorrect. A variable is an association between (from) a
> name (in the variable name-space) and a value. This association can be
> of many kinds, neither of which match your struct very well, to my
> knowledge.
> 
> If you must think of this in terms of other languages (and this is
> discouraged for good reasons), the Common Lisp
> 
>   (defun foo ()
>     (let ((variable 'value))
>       ...)
> 
> where the name variable is associated with value using a lexical
> binding, maps approximately to the following pseudo-C:
> 
>   foo () {
>     lisp_object variable = 'value;
>     ...
>   }
> 
> In both cases, what a variable "is" is a poor question from a
> beginner. It's best to accept the abstraction on its own terms and
> just understand what it provides and how you use it. Later on you
> might learn e.g. how gcc compiles that function into assembly:
> sometimes variable will denote a register, sometimes a piece of the
> stack-frame, a boolean bit somewhere, or what have you. It's pretty
> much the same with the Common Lisp version.
> 

Okay, I think I get it.
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-032-880-KL2065E@naggum.no>
* Dave Roberts
| What may help me is to sort of describe a simplistic implementation of
| this in C terms, so I can make the translation.

  Do you want to become good at translating between the mind-sets of
  different languages or do you want to write programs in Common Lisp?

-- 
Erik Naggum | Oslo, Norway                                      2004-032

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <mjfTb.157861$5V2.827283@attbi_s53>
Erik Naggum wrote:

> * Dave Roberts
> | What may help me is to sort of describe a simplistic implementation of
> | this in C terms, so I can make the translation.
> 
>   Do you want to become good at translating between the mind-sets of
>   different languages or do you want to write programs in Common Lisp?
> 

I think you're reading in here, per your other posting about avoiding
comparisons, to something I'm not trying to do. I'm specifically not asking
for how this compares to C in terms of language. I'm really asking how this
is implemented, simply with C as the syntax of choice for that presentation
since it's easy to understand. If you want to describe it in assembly
language, I'm fine with that, too.

Put another way, I'm really trying to ask, "What are 'bindings,'
'variables,' 'symbols,' etc., in terms of machine words, pointers, and byte
groupings representing objects?" If I can understand that, even if it's
just a naive implementation, that helps me understand the other terminology
better. Sorry, I'm carrying baggage from being a hardware engineer here.
Abstraction and abstract ideas are nice, but I find that my own personal
learning style is that I can't make them stick unless I anchor them to the
bits and bytes that really underly them. Once I have that, I find that I
can work very naturally and easily in the abstract system.

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0102042213100001@192.168.1.51>
In article <·······················@attbi_s53>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Put another way, I'm really trying to ask, "What are 'bindings,'
> 'variables,' 'symbols,' etc.,

http://www.flownet.com/gat/specials.pdf

E.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <tUHTb.212099$xy6.1099690@attbi_s02>
Erann Gat wrote:

> In article <·······················@attbi_s53>, Dave Roberts
> <·····@re-move.droberts.com> wrote:
> 
>> Put another way, I'm really trying to ask, "What are 'bindings,'
>> 'variables,' 'symbols,' etc.,
> 
> http://www.flownet.com/gat/specials.pdf
> 
> E.

Yes, thank you. This helped.

-- Dave
From: David Golden
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <EtgTb.1087$rb.54035@news.indigo.ie>
Downloading or otherwise finding a copy of "Common Lisp: A Gentle
Introduction to Symbolic Computation" by David S. Touretzky might help you
learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html

It may seem "too gentle" for the first few chapters, but it might be good to
read it without trying to compare lisp to other stuff. 
Lisp is lisp, it's not the other stuff.

It won't break things down into "hardware primitives" exactly, but
does break things down into lisp primitives in a manner that comes 
vaguely close.  Oh, and Chapter 14, about basic lisp macros, uses a finite
state machine "little language" (lisp is a language for writing languages)
as a worked example.

Note that lisp *once* mapped fairly reasonably to certain hardware
primitives on certain hardware (it's where the funny names "car" and "cdr"
come from, for example), but nowadays, it's much better to think of it more
abstractly, particularly since back in those days, lisp really was "LISt
Processing" and not much else - now there's a whole load of other data
types that may or may not be built from lists in a particular
implementation.

It's kinda just *not* that lisp is "built up" from hardware primitives, but
rather lisp "is", and the hardware representation is an implementation
detail that the compiler handles for you. Lisp could be on a trinary
content-addressable-memory computer, and it would still be lisp. 
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <KThTb.162310$nt4.735668@attbi_s51>
David Golden wrote:

> Downloading or otherwise finding a copy of "Common Lisp: A Gentle
> Introduction to Symbolic Computation" by David S. Touretzky might help you
> learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
> 
> It may seem "too gentle" for the first few chapters, but it might be good
> to read it without trying to compare lisp to other stuff.
> Lisp is lisp, it's not the other stuff.

Okay, great. I'll check it out.

> It won't break things down into "hardware primitives" exactly, but
> does break things down into lisp primitives in a manner that comes
> vaguely close.  Oh, and Chapter 14, about basic lisp macros, uses a finite
> state machine "little language" (lisp is a language for writing languages)
> as a worked example.

That would work. Again, it isn't that I actually require the hardware level
description. I just need a naive function model for the algorithms and data
structures and being a hardware guy, I tend to think low level. Even a
Lisp-level description would help me tremendously.

> Note that lisp *once* mapped fairly reasonably to certain hardware
> primitives on certain hardware (it's where the funny names "car" and "cdr"
> come from, for example), but nowadays, it's much better to think of it
> more abstractly, particularly since back in those days, lisp really was
> "LISt Processing" and not much else - now there's a whole load of other
> data types that may or may not be built from lists in a particular
> implementation.

Yes, agreed. Again, it isn't that I'm looking for an actual implementation
model so much as a naive one. I need a model with which to reason about the
operation of the system. As long as that model mirrors the system behavior,
I don't really need to know all the gory details.

> It's kinda just *not* that lisp is "built up" from hardware primitives,
> but rather lisp "is", and the hardware representation is an implementation
> detail that the compiler handles for you. Lisp could be on a trinary
> content-addressable-memory computer, and it would still be lisp.

Right. Ditto with many other languages, but sometimes it helps to understand
the naive implementation. For instance, if you're working in something like
C, understanding that local variables are allocated on the stack frame can
help you understand some types of bugs and issues like stack overflow.
There is really nothing in the C spec that says they must be implemented
that way, but if you know that most implementations do something like that,
it helps your understanding. Java doesn't actually mandate garbage
collection, assuming you have infinite memory, nor does CL. But knowing
that most implementations implement it can help.

-- Dave
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402021032.514e3f81@posting.google.com>
Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> David Golden wrote:
> 
> > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
> > Introduction to Symbolic Computation" by David S. Touretzky might help you
> > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html


How you can recommend anything that porn and bomb instruction guy Dave
Touretzky wrote is beyond me. Perhaps you don't know enough about that
man and never heard him in his own cheap words.

Check below log out:

Copied from the www.religiousfreedomwatch.org
 
   
 
IRC Logs

Religious Freedom Watch is currently reviewing more than 500 IRC logs
which contain information on what David Touretzky, Robert Clark,
Christopher Owen, Kady O'Malley, Scott Pilutik and several other
anti-religious extremists have been doing behind the scenes on several
fronts, some of which will be turned over to law enforcement as they
appear to have exceeded the legal limits.

Our review of these logs is featured below.


* IRC Definition 


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

Tuesday, January 27, 2004 

Following is David Touretzky's comment about the September 11, 2001,
terrorist attack."Well taking out congress might not be so bad."

Posted by rfw @ 08:47 AM PST [Link] 


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

Monday, January 26, 2004 

When Keith Henson was arrested in May 2001 by Canadian authorities,
his friends had a discussion about his arrest and the truth came out
about Henson having lied to Canadian Immigration when he entered
Canada, after fleeing the U.S. Henson never applied for refugee status
prior to entering Canadian soil, however he later mislead the press
and others to believe that he did. Moreover when Henson was released
from jail (on bail) his friends "forgot" about Henson's lies and wrote
a press release for him misleading the media to believe an entirely
different story with the assistance of Kady O'Maley (supposedly a
freelance reporter) and David Touretzky.

Kady O'Malley: "He [Keith Henson] may not face charges in Canada in
addition to those in the US but I don't think there's any way he's
going to be permitted to stay."

Deana Holmes: "He's [Keith Henson] a fugitive."

John Andersen: "Keith never mentioned that conviction in California,
if he told the Customs guard that then it maybe another reason."

Kady O'Malley: "He broke the law. He was arrested. He stayed in the
country illegally did nobody but me notice that? He was not legally in
Canada for the last week and a half."

Deana Holmes: "He declared how long he was going to stay in Canada." 

Kady O'Malley: "When you get to the border you fill out a form. After
the date of departure, you are in violation of the law. Keith was in
violation of the law and kept blithering on about filing for refugee
status. We don't actually want fugitives here we'd rather they filed
for refugee status and didn't just sit around taunting [the church]."

Elizabeth Cox: "I wish Keith would consider the consequences of his
actions prior to engaging in them."

Kady O'Malley: "Actually, weirdly, borders are looser as long as you
say you're going to be there, beverly but if you decide to become a
refugee and skip your court date in the US it's wise to file the
papers rather than sit around waiting to be arrested for breaking the
law."

Deana Holmes: "Right he is." 

Elizabeth Cox: "He fled to a foreign country." 

Kady O'Malley: "He [Keith Henson] lied to Canada customs. Canada
customs doesn't like being lied to."

Rob Clark: "Did he? What did he actually say to them?" 

Christopher Wood: "Keith hasn't exactly been acting all refugee-like,
and if he lied to immigration (even by omission) or didn't do all the
exact steps of the Refugee Dance, then he's gonna find himself back in
the US."

Kady O'Malley: "In reality, immigration doesn't usually care all that
much provided you aren't a refugee fleeing from a court date."

Rob Clark: "Keith's flight to Canada threw the court calendar into
disarray. nothing i know of has happened."

Beverly Rice: "Didn't he understand about the overstay thing?" 

Rob Clark: "Since the verdict, and the sentencing hearing that
wasn't."

Kady O'Malley: "He was having too much fun taunting the church." 

Beverly Rice: "Did Keith know about the staying over what you said
thing?"

Kady O'Malley: "Keith doesn't tend to listen to advice he doesn't like
yes, I told him myself."

Elizabeth Cox: "Once again, Keith refuses to accept advice and is his
own worst enemy."

Beverly Rice: "Did he just go and stay or did he apply for some kind
of status."

Kady O'Malley: "He hadn't applied yet." 

Beverly Rice: "I was under the impression that he had applied." 

Jeff Jacobsen: "I hope people don't call him a hero for this stuff." 

Rob Clark: "No, he definitely absolutely didn't apply." 

Kady O'Malley: "Jeff, don't even start me I really wish people would
quit egging him on."

Elizabeth Cox: "Jeff, Keith is no hero. In fact, he is the worst enemy
we have right now."

Deana Holmes: "Look, I'm going to be blunt here Keith is an egotist
he's got an ego the size of Manhattan Island. He did this for the
wrong reasons. He did this for the *publicity not because he thought
it was the best thing to do and frankly, his inability to come to his
senses is driving me nuts folks, I have yelled, screamed, cussed out
and argued with Keith. Ida [Camburn] tells me that he listens to me
but I have scant proof of that. Keith is his own worst enemy."

Elizabeth Cox: "Many of us are just tired of the deep bullshit and the
ravings of a self proclaimed martyr who is hurting his family, and the
other critics."

Deana Holmes: "Some people here can testify to how much I took Keith
to task."

Beverly Rice: "I thought Keith was in Canada with approval of
authorities."

Kady O'Malley: "No, unless by authority, you mean Keith. The
authorities had no idea he was here."

Elizabeth Brayman: "Keith is a MORON." 

Deana Holmes: "Keith was a moron from day one. Everything he's done
since the day he posted [copyrighted materials] in that letter to
Judge Whyte has been stupid."

Beverly Rice: "I was under the impression that Keith was in Canada as
a refugee and it was cool."

Elizabeth Cox: "No, it is not cool to flee justice." 

Elizabeth Brayman: "I swear, though, nobody here will say that to him
in channel. Maybe in private msg [message] but not in public."

Kady O'Malley: "Keith's fatal crime, as it were, throughout this
matter has been his appalling judgement and failure to deal with the
consequences of his actions. It's useless it's like talking to a
wall."

Elizabeth Cox: "He is too stupid to reform. 

Deana Holmes: "I suspect that Keith will not be a guest of the
Government du Canada very long.

Elizabeth Cox: "He is a married man, and that breeds responsibility." 

Elizabeth Brayman: "I don't know anything about his family. I just
know that he's a moron and I want to kick the shit out of him."

Kady O'Malley: "I mean, it's okay to go on and on about what a hero he
is, but god forbid anyone have a different opinion."

Rob Clark: "Who's going on and on about what a hero he is?" 

Kady O'Malley: "Half of ars? or did you miss the 50 "keith is a hero"
threads?"

Elizabeth Brayman: "KEITH IS A HERO! Just like that lady who sued
McDonalds because she spilled coffee on her crotch."

Beverly Rice: "Well, I don't like how this is going to be able to
affect other critics when they do things, as every thing that happens
always sets a precedent."

Elizabeth Cox: "There is so much more at stake here then just Keith." 

Kady O'Malley: "I would issue a statement disassociating it from
Keith's actions."

Gregg Hagglund: "Send money." 

Kady O'Malley: "Don't send him fucking money." 

Deana Holmes: "No, I'm not going to send him money." 

Kady O'Malley: "Jesus christ people do not send him money." 

Gregg Hagglund: "Keith should be out within 48 hours." 

Tim: "Why are you against sending keith money?" 

Kady O'Malley: "Because he's being a moron and does not need
encouragement. He puts himself into these situations then expects
people to fork over cash. Ars is not Keith Henson's fund raising
vehicle."

Elizabeth Brayman: "Keith shouldn't have run in the first place! He's
a freakin idiot!"

Kady O'Malley: "He could have appealed the conviction and done that
without fleeing."

Elizabeth Cox: "Settled the situaition correctly and appropriately." 

Gregg Hagglund: "Think of Keith Henson in the Jail � then they tell
the population Keith is a child molester...... His chances of survival
would be what?"

Kady O'Malley: "Oh here we go the Keith death predictions." 

Jeff Jacobsen: "I think somebody ought to start worrying pretty soon
at the rate this is sliding into worse and worse situations."

Elizabeth Cox: "I am not sending money to Keith." 

Gregg Hagglund: "Who says Kieth resisted filing Refugee status?" 

Kady O'Malley: "He didn't resist it. He just didn't file it." 

Scott Pilutik: "Well, it sure should get press anyway.. one salon
article was a weak PR campaign.. this pretty much forces mainstream
press to write about it.. just don't let Keith talk about 'how great
this arrest was' next interview."

Kady O'Malley: "He didn't tell the truth to customs when he arrived
not the thing about being a fugitive but about being a visitor. He
didn't leave when he said he would."

Christopher Wood: "Kady: Well, he was visiting at first... decided
later. Right?"

Kady O'Malley: "It doesn't work like that. He said that he was only
planning on going for a few days."

Gregg Hagglund: "Keith is in the max security immigration Jail along
with real terrorists some who have been here for years."

Kady O'Malley: "Apparently, this is a huge victory for Keith." 

Jeff Jacobsen: "If these are victories I'm glad I'm not in on the
fight. Keith arrested, big victory! Keith convicted, big victory!
Keith flees to Canada, big victory!"




Posted by rfw @ 04:30 PM PST [Link] 


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

David Touretzky created a website, hosted by Carnegie Mellon
University, containing instructions on how to build bombs. In
reference to his bomb website Touretzky had the following discussion
with Barbara Graham.

Barbara Graham: "What was the purpose in mirroring the site?"

David Touretzky: "I discuss that in detail on the web site. Basically,
the purpose was to allow people to read the material and decide for
themselves if the government acted reasonably. The mirror also points
out the sillyness of this law, since I can have the very same
bomb-making info on MY web site and not face any legal penalties. So
because of this, I got to have a nice chat with CMU's new legal
counsel. � Terrorism is in fashion these days."


Posted by rfw @ 12:44 PM PST [Link] 


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

David Touretzky discussing the abortion issue and how babies should be
disposed of six months after birth.

Ed Hamerstrom writes: "Terrell is awful, she wants to make
contraception illegal."

Dave Touretzky writes: "Ed oh, it doesn't matter what the candidates
say about birth control or abortion, cuz nothing is ever going to
happen in that department. There are too many Republican women with
secret abortions in their past."

Rod Keller: "I think it's the democrat who is against contraception." 

Ed Hamerstrom: "No, the other way." 

Dave Touretzky: "Maybe they'll ban partial birth abortion though. Not
that I think they should."

Elizabeth Cox: "It is why those nice conservative women such as myself
voted for Bill Clinton."

Dave Touretzky: "Hell, I'm for post-partum abortion! Retro-active
abortion! Up until, say, the age of six months."


Posted by rfw @ 12:40 PM PST [Link] 


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

Keith Henson is an explosives expert and a convicted hate criminal. On
July 19, 2000, he was arrested by the Riverside County, California,
Sheriff's Office for making terrorist threats on the Internet. On
April 26, 2001, a jury found Henson guilty of having committed a hate
crime under section 422.6 of the California Penal Code. Henson was
scheduled to appear for sentencing on May 16, 2001, but failed to
appear and the Judge was forced to issue a warrant for his arrest.
Henson fled to Canada where he was arrested by Immigration authorities
for having failed to disclose his conviction in the United States.
Henson was released on bail in Canada pending a final disposition of
his case. Meanwhile, on July 20, 2001, the Riverside County Judge
sentenced Keith Henson in absentia to one-year in county jail. As an
alternative, the Judge ruled that Henson could accept a six-month jail
term, three years probation, and pay a $2,000 fine. The Judge also
stated that when Henson returns to the United States he will, in
addition, face up to half a year in jail and a $1,000 fine, plus
penalty assessments, for having failed to appear at the sentencing
hearing on May 16, 2001. At this writing, Henson remains a fugitive
from justice.

The following chat log show how Kady O'Malley, Rob Clark, David
Touretzky and others supported Keith Henson's lies about his bogus
political refugee claim in Canada and they discuss what should be
written in the press release. Touretzky offers to re-write the press
release while he is supposedly at work (Carnegie Mellon University)
and as he writes the press release he makes it available to his
friends by using Carnegie Mellon University's server.

Keith Henson is not a political refugee. Henson came up with his bogus
claim after he was arrested in Canada. If he was a "political refugee"
why didn't he state so to Immigration when he entered Canada?

More documents are currently being processed showing that before
Henson fled to Canada there were some discussions on the same chat
channel where Henson's friends solicited him to leave the United
States to avoid sentencing.

David Touretzky: "ptsc [Rob Clark]: mind if I make a pass over this
text?"

Rob Clark: "sure, if you're going to issue an "alternate press
release" feel free to mutate, alter or whatever. I assume Kady won't
mind. At the moment, it would be copyright Kady O'malley."

David Touretzky: "Just gimme a few minutes." 

Rob Clark "Declan immediately issued a report that they have granted
him asylum, which ain't true."

Elizabeth Fisher "Send me the finished press release in email, I might
try something here."

David Touretzky: "I don't buy this "fled out of fear... persecuted in
prison" crap."

Arnie Lerma: "That it was a publicity stunt?" 

David Touretzky: "I'm rewriting now... gimme a few more minutes." 

Kady O'Malley: "This was all a big publicity stunt' isn't a great line
for a press release. We don't have to specify whether his fears are
justified."

Elizabeth Fisher: "It should be "Henson is represented by" instead of
"was represented by" and drop the second sentence."

David Touretzky: "I've cleaned up the language�
http://www.cs.cmu.edu/~dst/henson-release.txt."

Elizabeth Fisher: "Oh this is good, dst!" 

Keith Henson: "ptsc [Rob Clark], wait a sec on the press release talk
to Gregg first the lawyer has talked to him."

Keith Henson: "dst [David Touretzky], please unlink that for a few
Gregg is working on an official version he is sending it to you right
now."

Kady O'Malley: "Tell him [Gregg] to be easy on the hyperbole." 

David Touretzky: "Henson, it's not linked. Only available to this
channel. Yeah, Gregg tends to go over the top with his language."

Keith Henson: "dst [David Touretzky], Gregg is sending right now.

David Touretzky: We should be sure to mention that he's a POLITICAL
refugee."

Elizabeth Fisher: "� the temple of atlan has nothing to do with
Keith's case and in fact makes the release less credible for
mainstream media, that is."

David Touretzky: "Where are you reading this?" 

Elizabeth Fisher: "On ars!" 

David Touretzky: "Oh shit! Gregg posted some lame-brain thing to ARS?"

Elizabeth Fisher: "Gregg posted it yes." 

Rob Clark: "I don't have the temple of atlan in the release nor is
there a request for donations."

David Touretzky: "ptsc [Rob Clark] she's reading Gregg's piece of crap
that he posted to ARS."

Keith Henson: "Gregg's may be lame, but it was lawyer approved." 

David Touretzky: "It's not lame, it's LOONY." 

Rob Clark: "It's really too late since it's already released." 

Kady O'Malley: "Can't we start an independent support group that
doesn't involve the official endorsement of Keith and Gregg?"

Scott Pilutik: "It's the same press release I think, with a Gregg sig
at the bottom."

David Touretzky: "Newest version:
http://www.cs.cmu.edu/~dst/henson-release.txt."

Rob Clark: "I did not present that as a Keith and Gregg production,
but cited it to "supporters of Keith Henson". Essentially without your
permission, except I quoted you [Henson]."

Kady O'Malley: "That's good." 

Rob Clark: "Gregg, email to the Keith list and if I have it I'll do
it. I'm gonna do one final update of the page to add the dueling press
releases and then hit the hay."

David Touretzky: "Okay, I merged in the new Keith quotes from Gregg's
post into my edit of kady ptsc's press release. New version is
uploaded."

Elizabeth Fisher: "You left in the Breaches of Trust! That is not good
take out the "because of its Breaches of Trust"."

David Touretzky: "Why?" 

Elizabeth Fisher: "It makes the sentence very awkward." 

David Touretzky: "Well yeah, but that's how Keith talks." 

Kady O'Malley: "No it isn't it's how Gregg talks. It would be better
as not a quote just leave it as a paragraph although it is totally
irrelevant to the main news story."

David Touretzky: "Okay, fixed." 





Posted by rfw @ 10:41 AM PST [Link] 


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

David Touretzky never stops to discriminate African Americans.

David Touretzky: "There should be a video game where you can beat
Rodney King."

Posted by rfw @ 08:28 AM PST [Link] 


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

Sunday, January 25, 2004 

David Touretzky criticizing Geraldo Rivera. Could it be because he
hates Hispanics? Here is what Touretzky has to say about Hispanics,
"Man, Hispanics are fucked up, which is why they're still working
class. Dipshits."

Ida Camburn: "Some conservatives are angry as Fox has hired Geraldo." 

David Touretzky: "Hiring Geraldo sure didn't do much for their image.
He's a creep."

Barbara Graham: "I can't watch Geraldo. Last night he was blathering
on about how all the other journalists in Afghanistan were weenies but
big brave Rivera brought you the real news!"

David Touretzky: "Geraldo is so full of shit... and everyone knows
it."

Rob Clark: "Rivera was a huge liar. Rivera makes me sick. I think Fox
just hired him to make liberals look like they are all stupid liars.
It doesn't help that he has a hairy burrito on his upper lip."

Rob Clark: "He's a tail-chasing narcissist." 

Barbara Graham: "I thought it was a Chupacabra!" 

Rob Clark: "They should drag him to al Capone's vault and lock him up
in there."


David Touretzky: "His head wouldn't fit in al Capone's vault." 

Rob Clark: "Would if you popped it with a pin." 





Posted by rfw @ 02:45 PM PST [Link] 


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

Tuesday, January 13, 2004 

Following is a statement made by David Touretzky which shows
disrespect of Chinese individuals executed by their own oppressive
government.

"It would be cheaper to just buy your replacement organs from executed
Chinese."

Posted by rfw @ 06:39 PM PST [Link] 


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

Thursday, January 1, 2004 

David Touretzky displaying more racism. Even his own friend calls him
racist.

David Touretzky: "Washington DC is more disgusting than Harlem."

[Name Deleted]: "How and why is Harlem disgusting."

David Touretzky: "Disgusting as in rates of illegitimacy, drug abuse,
domestic abuse, shootings, prostitution, welfare culture. I think
Harlem has gotten better the last few years, but DC has not. White men
don't walk in Harlem at night."

[Name Deleted]: "Yes they do it is not and never was 'disgusting'.
What's disgusting is you, dst, for even calling it 'disgusting'. Some
of the greatest art and science in this country came from Harlem."

David Touretzky: "I know that Harlem was once a major cultural
center."

[Name Deleted]: "I resent you saying Harlem is 'disgusting' dst and
you should be ashamed. Not was once still is, always was. I just think
it's wrong."

David Touretzky: "The great Harlem theaters and clubs have closed
although the Apollo is still around."

[Name Deleted]: "Why do you say Harlem is 'disgusting'."

David Touretzky: "For the same reason DC is disgusting."

[Name Deleted]: "And that is???"

David Touretzky: "If you wanna buy crack cocaine, go to Harlem or DC,
not Wall Street."

[Name Deleted]: "dst, cut to the quick here you [are] what's
disgusting?"

David Touretzky: "Doesn't DC has the highest murder rate in the
country? Or is it only second highest now?"

[Name Deleted]: "These are like the little racist pop-ups you see on
Neo nazi channels."

David Touretzky: "[name deleted] objects to my stating opinions, and
even more to my citing statistics."

[Name Deleted]: "dst, do the good one about how the niggers are
killing everyone. You have all those in pop-ups when you're on those
other channels, don't you? You know, the neo-nazi ones the white
supremacists ones you go on, dst, the niggers are just a problem."

David Touretzky: "Although, [name deleted], your remark about
'niggers' reminds me of an incident I'd been meaning to tell you
about. This happened quite a few years ago now."

[Name Deleted]: "Harlem is not disgusting."

David Touretzky: "Back before we were all posting on Usenet, we had a
local bulletin board system here at CMU. And one of those boards was
dedicated to no-holds-barred discussion."

[Name Deleted]: "That's racist dribble and frankly, I won't continue."

David Touretzky: "I asked on this board why we had no term that was
the black equivalent of 'white trash'. Because, you know, the N-word
was totally unsuitable. We needed some other term. A term that would
show that the speaker drew a deliberate distinction between people of
a certain skin color who behaved decently (as in 'decent white folk')
and those who behave badly (as in 'white trash')."

Rob Clark: "I have an equivalent as offensive as n-word term for black
trash. 'clarence thomas'."

David Touretzky: "So why don't we have equivalent terms for blacks?"

[Name Deleted]: "We do, dst."

David Touretzky: "And what would those terms be?"

[Name Deleted]: "You just don't know them. Human beings. It's really
deep in there, dst, maybe one day you'll get over it."

David Touretzky: "Living in trailers is a white thing.
Drive-by-shootings are a black thing etc. Anyway, here's the
interesting part of my story. A colleague of mine, from Texas, took
grave offense at my inquiry. He said that the reason people say 'WHITE
trash' is to distinguish it from ordinary trash, which is ASSUMED to
be black. So even "white trash" is an anti-black term. Personally, I
think we need a term for 'black trash' so that people can express
disapproval of a subculture without appearing to denounce an entire
ethnic group. I also think 'white trash' is a useful and appropriate
term."


Posted by rfw @ 01:17 PM PST [Link] 


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

Saturday, December 6, 2003 

David Touretzky discusses the bomb-making information website that
Sherman Austin built (which Touretzky has mirrored at Carnegie Mellon
University). While Touretzky criticizes Austin, and wishes he would go
to jail, he is mirroring the same website which does encourage people
to build a specific bomb and drop it into police cars.

David Touretzky: "this RaisehteFist case is getting interesting." 

Chris Owen: "it's a bit borderline." 

David Touretzky: "yeah, I have to wonder whether this kid did or did
not cross the line. I do think it's borderline. But I hear he's gonna
have some high-powered lawyers defending his sorry ass. The kid is a
shithead."

Chris Owen: "he'll probably yell "free speech" but in the present
climate i don't know if ppl [people] will listen."

David Touretzky: "The thing is, his bomb-making information appeared
to be directed toward people protesting the WTO meeting in DC."

Chris Owen: "the "free speech" argument is the first they always go
for."

David Touretzky: "and that may put him in violation of 18 USC 842(p)."

Chris Owen: "which says what? 

David Touretzky: "I'd be perfectly happy to see this shithead in
jail."

Chris Owen: "i get the feeling that legitimacy isn't too high on the
agenda at the moment particularly when you get idiots from DoD
[Department of Defense] talking about opting out of the Geneva
convention."

David Touretzky: "18 USC 842(p) says it's illegal to provide
bomb-making information for the purpose of, or in furtherance of,
federal acts of violence.


Posted by rfw @ 07:11 PM PST [Link] 


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

David Touretzky admitting to viewing kiddie porn. To be noted that
Touretzky went to the website and describes that he saw naked kids. He
then explains that those who are showing genitalia are "closer" to 18.
Why is Touretzky interested in such websites in the first place?

David Touretzky:"the images at the web site front door contain some
naked kiddies, but they're not engaged in sex acts and the ones
showing genitalia are closer to 18."





Posted by rfw @ 02:08 PM PST [Link] 


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

David Touretzky greetings to hatemongers on IRC.

David Touretzky:"good evening, religion haters." 

"I feel the need to commit crimes against a religion." 


Posted by rfw @ 01:49 PM PST [Link] 


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

David Touretzky on IRC from work.

David Touretzky: "afternoon, religion-destroyers. Anything going on
today?"

Posted by rfw @ 01:39 PM PST [Link] 


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


This is how David Touretzky spends his time while he is supposedly
doing "research" at Carnegie Mellon University.

David Touretzky: "http://www.anorexic-rec.com/ � the nice thing about
this site is that these anorexic women are happy with their looks.
Which is more than can be said for a lot of people. Calista Flockhart
But the women on that page are willing to take their clothes off,
which gives them one up on ol' Calista."

Deana Holmes: "does it make you hot?"

Tim:"you're sick"

David Touretzky: "the women on that page are too skinny even for me
but Calista still makes me hot. Anyway, that anorexic porn site is a
*pay* site. It's $14.95/month for the really hardcore stuff. ... [I]
like the concept of amputee porn. Makes the women feel good about
themselves. ... I do have this picture of a quadruple amputee with
nice boobs. She's looking straight at the camera, a smile on her face,
calm, self-possessed. She's doing fine."


Posted by rfw @ 12:51 PM PST [Link] 


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

Friday, December 5, 2003 


Statement made by Robert Clark on usenet against Scientology:

Clark: "fire bomb it, demolish it with a rented crane and ball, fire
bomb it again and then salt the ground so that nothing will ever grow
there again. and then if you're up for it, fire bomb it again."

Posted by rfw @ 07:54 PM PST [Link] 


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

David Touretzky "I guess it would be a bad idea for me to talk in open
channel about the anthrax we mailed to FLAG last week."

*FLAG is a Church of Scientology in Florida. 

Two weeks prior an anthrax hoax (an envelope containing white powder)
was received at the above-named Church.

Posted by rfw @ 07:24 PM PST [Link] 


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

Thursday, November 8, 2003 


David Touretzky advertising the sale of a 757 flight manual:

David Touretzky:"... 757 Flight Manual for sale -- Arabic translation.
Slightly used. Minimum bid $7500. ... you think that would get me a
phone call from the FBI?"

[Name Deleted]:"Dave: probably"


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



Posted by rfw @ 01:08 PM PST [Link] 


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

Thursday, October 05, 2003 


Rob Clark anti-America hate songs:

Rob Clark:"God Hates America
(Sung to God Bless America)
God hates America!
Land of the gays
He abhors her
Deplores her
Day and night, by his might, all his days
From the mountains
To the prairies
To the oceans
White with foam
God hates America!
The fag-gots' home!"

Robert Clark:"God does not love America; He hates it. God does not
mourn with America; He laughs at it. We are in distress because of our
sins, and should therefore fly the flag upside down. It's too late to
pray for America (Jeremiah 7:16). This event is a small foretaste of
the eternal wrath of God."

Rob Clark:"Here's another twisted hatesong
America the Burning
(Sung to America the Beautiful)
O wicked land of sodomites
Your World Trade Center's gone
With crashing planes and burning flames
To hell your souls have flown
America

America
God's wrath was shown to thee!
He smote this land
With his own hand
And showed his sovereignty"


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



Posted by rfw @ 01:06 PM PST [Link] 


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

Thursday, September 16, 2003 


David Touretzky and his friend discussing the shooting of certain
people:

[Name being given to law enforcement]:"buy a gun."

David Touretzky:"yeah, a ... gun might be useful."

[Name being given to law enforcement]:"... hell, get a 38 buy a gun
and a knife, after you shoot the guy you can put the knife in his hand
and say he threatened you with it."

David Touretzky:"well you can use the gun to shoot up the car, not the
[deleted] blow out his windshield and put a hole in his radiator ..."


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



Posted by rfw @ 01:04 PM PST [Link] 


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

Thursday, September 9, 2003 

David Touretzky logged on IRC from Carnegie Mellon University
····@Hidden_SP-31739.BOLTZ.CS.CMU.EDU_ making racist comments about
African Americans:

Note: DST stands for David Stuart Touretzky.

David Touretzky: "... we have a high infant mortality rate for a
developed country, but it's not because middle class people's babies
are dying. It's because of crack whores giving birth to high risk
premies."

[Name Deleted]: "dst, why do you use language like that?"

David Touretzky: "I'm just telling the truth."

[Name Deleted]: "the truth you are telling is that, despite all your
great intelligence and capacity and humor, you are, so it seems, under
it all and hateful racist."

David Touretzky: "maybe [you] know something about crack whores that I
don't. ... but if you want to talk about race.... infant mortality in
the US is much higher for blacks than for whites. I have no idea what
the racial breakdown of crack whores is."

[Name Deleted]: "there are no "crack babies" first of all that term is
a misnomer and medically incorrect."

David Touretzky: "I'm sure that blacks are over-represented in that
profession, but in terms of absolute numbers, I don't know."

[Name Deleted]: "so, it's about class then."

[Name Deleted]: "dst, you really take yourself down when you use
language like that. classism IS a form of racism."

David Touretzky: "it's your right to not like my language."

[Name Deleted]: "dst, it's not that I don't like it. It's what it says
about you that I find, well, very disappointing. I guess I'd expect
more from you."

David Touretzky: "I'm not creepy. I'm just impatient with people who
run down this country."

[Name Deleted]: "... but using language like that is inflammatory it
invites rebuke demands it."

David Touretzky: "you wanna defend crack whores?"

[Name Deleted]: "yup."

David Touretzky: "Go ahead. I'm listening."

[Name Deleted]: "they are saints. first, they are sex workers women
who are living, trying to make a way in a brutal world they are people
responding to conditions that are totally out of their control
sometimes and come from long stading problems, often going back to
home life lack there of many are victims of abuse they are all human
beings and they find themselves in this place and someone introduces
them to the idea of being a prostitute. So this name calling of "crack
whores" is first and foremost a cry of pain, sort of like road rage
and this langue of "crack whores, crack babies (which don't exist),
welfare queens" it's not just classist, but it's also racist one is
contained in the other."

David Touretzky: "Why do you say crck babies don't exist?"

[Name Deleted]: "it's my understanding that more recent research
disproves the original ideas of what was a "crack baby."

David Touretzky: "disproves it how? The stats on premature birth are
pretty clear."

[Name Deleted]: "the addictive properties of the drug are not passed
along from Mother to Child as they were thought when the original term
was put forward. it's not premature so "crack baby" is not a valid
term."

David Touretzky: "a baby who is born not-premature or underweight, and
not addicted to any drug, would not result in high medical costs."

David Touretzky: "but there are babies who run up $500,000 in hospital
costs because of their medical problems, which they wouldn't have if
their mother wasn't a crack whore."

[Name Deleted]: "it's a racist term. get it f***ing straight crack
babies and crack whores is racist crap bullshit and I will rebuke that
kind of racist hate speech as long as I live."

David Touretzky: "you should listen to kady [O'Malley]. I'm not
racist, I'm classist. And they're NOT equivalent."

[Name Deleted]: "YES bullshit, dst that is such crap since Class is
based on race don't run that specious line, dst. come to terms with
your own hate and racist heart."

David Touretzky: "that URL you posted was an article from 1992. And
it's just an AP piece, not a serious scientific article."

[Name Deleted]: "so what? read the lasttest info for youself. that's
HOW long that term went out of style -- dst, you're still in bell
bottoms, highwaters, that's yesterdays racist stuff."

David Touretzky: "well for one thing, the article looks only at babies
who survive long enough to make it out of the hospital."

[Name Deleted]: "the dead ones dont' matter, do they."

David Touretzky: "if they die after spending a month in NICU, they
cost hundreds of thousands."

[Name Deleted]: "under it all is the economic, on that agree, but
keeping it that way involves, indisputably, racist practices like it
or not, not just racist, but always racist and that dst's speech is
both classist, which is seems strnagly proud of, and racists."

David Touretzky: "Larry Elder says blacks are more racist than whites.
... Well yelling "racist" doesn't advance your argument."

[Name Deleted]: "ok, so then were shall I start to just show you how
creapy and hatful you are. Hateful as in "crack whores who are running
everything."  "

David Touretzky: "I mean, who cares if a crack whore's kid is retarded
because of alocohol abuse instead of cocaine abuse? The kid is still
fucked. ... there are more whites than blacks on welfare in this
country."

[Name Deleted]: "oh so what, dst. drop it ok."

David Touretzky: "I don't think you're calling me a hateful racist
because of some minor detail."

[Name Deleted]: "dst, that you do not know shows only the depths of
your ignorance and need to think really deeply about this."




Posted by rfw @ 12:59 PM PST [Link] 


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

Thursday, September 1, 2003 


David Touretzky and Deana Holmes on Christianity:

David Touretzky: "Daddy, Why Did Jesus Kill Grandma?"

Deana Holmes: "Summary: God's violent anger is directed toward those
who dare to question His perfect love for them. Grandma Jenkins is no
exception. One little slip of the tongue on her deathbed secured an
eternity of separation from God. Marooned alone in the lake of fire,
her only company is a visiting red-finned water demon who sodomizes
her from the deep as fire waves crash into her screaming head and
burst her wrinkled body into flames."



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


Another example on how David Touretzky spends his grant money:

"I've given three interviews today. I've spent 4 hours on the phone
today giving interviews."



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


David Touretzky's comment about the Salvation Army:

"... the Salvation Army ... buncha fuckheads."



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



Posted by rfw @ 12:51 PM PST [Link] 


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

Thursday, August 25, 2003 


It is of interest to taxpayers that Touretzky spends many hours on a
hate channel attacking religions and races while at work. We have not
completed the counting of these hours but so far it is over 300 (in
less than a year). During this time Touretzky was plotting attacks
against a religion instead of working at Carnegie Mellon University
(CMU). The total number of hours will soon be made available on this
website.


David Touretzky criticizes the FBI:

"FBI is looking like shitheads today."


David Touretzky teaches how to lie to law enforcement to antagonize
them against members of the Church:

"Don't make the cops into enemies; paint them as victims..."


But then he criticizes the police:

"Police investigations are just ways of delaying things until the heat
dies down."



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


David Touretzky makes racist comments against Hispanics:

"Man, Hispanics are fucked up."

"... which is why they're still working class. Dipshits."



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



Posted by rfw @ 12:48 PM PST [Link] 


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

Thursday, August 20, 2003 


Why was Kady O'Malley so concerned when certain papers were turned
over to the Royal Canadian Mounted Police (RCMP) (soon to be
featured):


Jacobsen: "... he told people stuff that was not supposed to leave the
channel."

Fisher: "... and had the RCMP [Royal Canadian Mounted Police] taken
his crap seriously, it had very bad ramifications for Kady
[O'Malley]."

Hammerstrom: "What did [deleted] post?" 

Cox: "A private chat with Kady [O'Malley], and he sent it to a ranking
Canadian official."

Fisher: "He sent a private chat with Kady [O'Malley] to the RCMP." 

Hammerstrom: "What was the substance, was it something important or
harmful to Kady?"

Cox: "It was a potential criminal matter."


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



Posted by rfw @ 12:36 PM PST [Link] 


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

Thursday, August 19, 2003 


David Touretzky on his use of public funds:


"My money comes mostly from the US govt, not corporations. So if we
raise taxes and hike the NSF and NIH and DARPA budgets, that would be
to my benefit."

"I'm already overpaid."



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


David Touretzky boasting about his exploitation of Carnegie Mellon
University:

"dst* feels very fortunate to have a university for his ISP."

"Every time someone tries to censor me, Carnegie Mellon gives them the
finger."

"We've got a big fucking notice on the site pointing out that RTC owns
this trademark. I could move the image to my CMU web server, but I'm
not going to let this ISP off the hook so easily.

*dst: David Stewart Touretzky



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


David Touretzky planning a false and derogatory campaign against the
Scientology religion:

"How about a black PR* campaign? Something about a Scientology
pedophile ring?"

*Black PR: false and derogatory information passed out to vilify a
person or group.



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


David Touretzky's statement about the 
movie industry:

"well, I have to go contribute to the destruction of the movie
industry."



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



Posted by rfw @ 11:07 AM PST [Link] 


--------------------------------------------------------------------------------
 
[Archives] 

Search entries: 
 

 
 
  
 Home  |  Latest News  |  Anti-Religious Extremists  |  Hate Groups  |
 Influence of Hate  |  Experts  |  False Experts?  |  Hate Crimes &
The Law  |  Whistleblowers  |  Articles  |  Combating Hate

For the truth about religion:
Buddhism, Christianity, Catholicism, Hinduism, Islam, Judaism,
Scientology, What is Scientology?, Scientology Theology General

 
 
 
  
> > 
> > It may seem "too gentle" for the first few chapters, but it might be good
> > to read it without trying to compare lisp to other stuff.
> > Lisp is lisp, it's not the other stuff.
> 
> Okay, great. I'll check it out.
> 
> > It won't break things down into "hardware primitives" exactly, but
> > does break things down into lisp primitives in a manner that comes
> > vaguely close.  Oh, and Chapter 14, about basic lisp macros, uses a finite
> > state machine "little language" (lisp is a language for writing languages)
> > as a worked example.
> 
> That would work. Again, it isn't that I actually require the hardware level
> description. I just need a naive function model for the algorithms and data
> structures and being a hardware guy, I tend to think low level. Even a
> Lisp-level description would help me tremendously.
> 
> > Note that lisp *once* mapped fairly reasonably to certain hardware
> > primitives on certain hardware (it's where the funny names "car" and "cdr"
> > come from, for example), but nowadays, it's much better to think of it
> > more abstractly, particularly since back in those days, lisp really was
> > "LISt Processing" and not much else - now there's a whole load of other
> > data types that may or may not be built from lists in a particular
> > implementation.
> 
> Yes, agreed. Again, it isn't that I'm looking for an actual implementation
> model so much as a naive one. I need a model with which to reason about the
> operation of the system. As long as that model mirrors the system behavior,
> I don't really need to know all the gory details.
> 
> > It's kinda just *not* that lisp is "built up" from hardware primitives,
> > but rather lisp "is", and the hardware representation is an implementation
> > detail that the compiler handles for you. Lisp could be on a trinary
> > content-addressable-memory computer, and it would still be lisp.
> 
> Right. Ditto with many other languages, but sometimes it helps to understand
> the naive implementation. For instance, if you're working in something like
> C, understanding that local variables are allocated on the stack frame can
> help you understand some types of bugs and issues like stack overflow.
> There is really nothing in the C spec that says they must be implemented
> that way, but if you know that most implementations do something like that,
> it helps your understanding. Java doesn't actually mandate garbage
> collection, assuming you have infinite memory, nor does CL. But knowing
> that most implementations implement it can help.
> 
> -- Dave
From: Tim Lavoie
Subject: re: David Tourtezky rant (was Re: Understanding #' and function variables)
Date: 
Message-ID: <87u129kzxc.fsf_-_@theasylum.dyndns.org>
>>>>> ""Barbara Swarc"" == The only true Barbara Schwarz <·············@myway.com> writes:

    "Barbara Schwarz"> How you can recommend anything that porn and bomb
    "Barbara Schwarz"> instruction guy Dave Touretzky wrote is beyond
    "Barbara Schwarz"> me. Perhaps you don't know enough about that man
    "Barbara Schwarz"> and never heard him in his own cheap words.

Lots of people value freedom of speech. If he's posted something you
don't like, he's at least seemed to do so honestly, under his own
name. That site you posted a link to has nothing of the sort; no
author, no contact info, no "who are we? (I?)" link.

Screaming on about bits of what other people say, out of context, says
more about your ideas than those of anyone else.

-- 
Man is the best computer we can put aboard a spacecraft ... and the
only one that can be mass produced with unskilled labor.
                -- Wernher von Braun
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: David Tourtezky rant (was Re: Understanding #' and function variables)
Date: 
Message-ID: <760804b4.0402031056.6b6ae329@posting.google.com>
Tim Lavoie <········@spamcop.net> wrote in message news:<·················@theasylum.dyndns.org>...
> >>>>> ""Barbara Swarc"" == The only true Barbara Schwarz <·············@myway.com> writes:
> 
>     "Barbara Schwarz">
>      How you can recommend anything that porn and bomb
>      instruction guy Dave Touretzky wrote is beyond
>      me. Perhaps you don't know enough about that man
>      and never heard him in his own cheap words.
> 
> Lots of people value freedom of speech.

You make mine to a mockery.

>If he's posted something you
> don't like,

I don't like? He sexually harassed me with a porn letter!

> he's at least seemed to do so honestly, under his own
> name. 

My sites critical of him were removed by him and his friends, as they
lied to the ISPs that my site would be libel! Fine free speech that
is. Dave Touretzky likes only one free speech and that is his.


>That site you posted a link to has nothing of the sort; no
> author, no contact info, no "who are we? (I?)" link.

Not true. You are posting falsehoods. Go to the
www.religiousfreedomwatch.org. It is all on there.

> 
> Screaming on about bits of what other people say, out of context, says
> more about your ideas than those of anyone else.

You cited me out of context, you hypocrite. I believe that all the
people that defend porn and bomb instructions guys are like him, the
rest is appalled.


Barbara Schwarz (the only real one)


P.S. Postings with e-mail address ···············@emailaccount.com and
identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
and "Truth Speaker 2" are not done by me. Those are forgeries of
criminal, Aids infected, gay lunatic Garry Lynn Scarff who is a
fanatical Dave Touretzky defender. Scarff persecutes me from thread to
thread often using my name as identity for those crimes (!) and
verbally assaults me, threatens me, harasses me, sexually harasses me,
tries to intimidate me, libels, insults and lies about me. He also
lied that he spoke to a roomate of mine in the Utah mental health
hospital. I never was in that hospital, but he probably escaped from
one. Scarff is active member of the gay WeHo "church", that according
to Scarff applaudes Scarffs lawless behavior against me. An ex-WeHo
member wrote me that this "church" sanctions and promotes dishonorable
behavior and that he and his friends were raped and drugged by one of
their active members, and that one of their active members murdered
others under the guise of "drug overdose". The ex-WeHo wrote that the
gay men make sexual innuendo during sermon and "church" leadership
doesn't see what's wrong with that.

Frederic Rice, another fierce David Touretzky defender, posted also
with the stolen identity de Rothschild. He is as little a de
Rothschild as a dirty slimy and greasy punch bag is an impressive man.
He threatened governmental officials over the Internet, wants to
celebrate when both President Bush's are dead and has tips on his
website on how to kill bikers.

His brother David Rice, posts with "Dr." or "Reverend" Desertphile and
also with the stolen identity de Rothschild. He suggested to kill
members of the FBI. (Go to www.religiousfreedom.watch.org, the
extremist pages on David Touretzky, page 9, his connections and click
on the PDF file.) Dave Rice also posted a long time with the identity
"Prozac filled gay terrorist psycho", which tells a lot about him.

Barbara Graham Warr, self-proclaimed "caplain" of the A.R.S. newsgroup
and snakepit, another David Touretzky promoter, is a DUI offender and
pleaded guilty to possession and manufacturing of prohibited weapon
under California penal code. She congratulated the WeHo "congregation"
accepting Scarff's criminal behaviors against me. However, she posted
before that there is no God. She also posts with stolen identity de
Rothschild. - For more, click on the below links.



----------------------------------------------
Linda Anderson
http://www.religiousfreedomwatch.org/extremists/andersenl1.html
Gerald Armstrong
http://www.religiousfreedomwatch.org/extremists/armstrong1.html
Jim Beebe
http://www.religiousfreedomwatch.org/extremists/beebej1.html
Graham Berry
http://www.religiousfreedomwatch.org/extremists/berry.html
David Bird
http://www.religiousfreedomwatch.org/extremists/birdd1.html
Tory Christman
http://religiousfreedomwatch.org/extremists/christmant4.html
Ursula Caberta
http://www.religiousfreedomwatch.org/extremists/caberta.html
Ida Camburn
http://www.religiousfreedomwatch.org/extremists/camburn1.html
Joe Cisar
http://www.religiousfreedomwatch.org/extremists/cisarj1.html
Robert Clark
http://www.religiousfreedomwatch.org/extremists/clark1.html
Elizabeth Ann Cox
http://www.religiousfreedomwatch.org/extremists/coxea1.html
Mark Dallara 
http://www.religiousfreedomwatch.org/extremists/dallara1.html
Alexander Dvorkin
http://www.religiousfreedomwatch.org/extremists/dvorkin1.html
Valerie Emanuel
http://www.religiousfreedomwatch.org/extremists/emanuelv1.html
Steven Fishman
http://www.religiousfreedomwatch.org/extremists/fishman1.html
Vickki Ford Cook
http://www.religiousfreedomwatch.org/extremists/fordv1.html
Phil Georgi
http://www.religiousfreedomwatch.org/extremists/jacobsen6.html
Scott Goehring
http://www.religiousfreedomwatch.org/extremists/goehrings1.html
Roger Gonnet
http://www.religiousfreedomwatch.org/extremists/gonnet1.html
Barbara Graham
http://www.religiousfreedomwatch.org/extremists/graham1.html
Gregg Hagglund
http://www.religiousfreedomwatch.org/extremists/hagglund1.html
Steve Hassan
http://www.religiousfreedomwatch.org/false_exp/hassan1.html
Tilman Hausherr
http://www.religiousfreedomwatch.org/extremists/hauser1.html
Andreas Heldal-Lund
http://www.religiousfreedomwatch.org/extremists/lund1.html
Keith Henson
http://www.religiousfreedomwatch.org/extremists/henson1.html
Deana Holmes
http://www.religiousfreedomwatch.org/extremists/holmes1.html
Jeff Jacobsen
http://www.religiousfreedomwatch.org/extremists/jacobsen1.html
Patrick Jost
http://www.religiousfreedomwatch.org/extremists/jost1.html
Charlotte Kates
http://www.religiousfreedomwatch.org/extremists/katesc1.html
Rod Keller
http://www.religiousfreedomwatch.org/extremists/keller1.html
Steven Kent
http://www.religiousfreedomwatch.org/false_exp/kent1.html
Arnie Lerma
http://www.religiousfreedomwatch.org/extremists/lerma1.html
Joe Lynn
http://www.religiousfreedomwatch.org/extremists/lynn1.html
Ted Mayett
http://www.religiousfreedomwatch.org/extremists/mayett1.html
Frank Oliver
http://www.religiousfreedomwatch.org/extremists/oliver.html
Kady O'Malley
http://www.religiousfreedomwatch.org/extremists/omalley1.html
Zenon Panoussis
http://www.religiousfreedomwatch.org/extremists/panoussis1.html
Ted Patrick
http://www.religiousfreedomwatch.org/false_exp/patrick1.html
Michael Pattinson
http://www.religiousfreedomwatch.org/extremists/pattinsonm1.html
Robert Peterson
http://www.religiousfreedomwatch.org/extremists/peterson1.html
Bruce/Kathleen Pettycrew
http://www.religiousfreedomwatch.org/extremists/pettycrew.html
Jesse Prince
http://www.religiousfreedomwatch.org/extremists/prince1.html
Roland Rashleigh-Berry
http://www.religiousfreedomwatch.org/extremists/rashleighb1.html
David Rice
http://www.religiousfreedomwatch.org/extremists/riced.html
Fred Rice
http://www.religiousfreedomwatch.org/extremists/ricef.html
Rick Ross
http://www.religiousfreedomwatch.org/false_exp/rossr1.html
Karin Spaink
http://www.religiousfreedomwatch.org/extremists/spaink1.html
David Touretzky
http://www.religiousfreedomwatch.org/extremists/touretzky1.html
Alan Walter
http://www.religiousfreedomwatch.org/extremists/walter1.html
Grady Ward
http://www.religiousfreedomwatch.org/extremists/ward.html
Johan Wevers
http://www.religiousfreedomwatch.org/extremists/weversj1.html
Hana/Jerry Whitfield
http://www.religiousfreedomwatch.org/false_exp/whitfield1.html
Larry Wollersheim
http://www.religiousfreedomwatch.org/extremists/wollersheim1.html
Sten-Arne Zerpe
http://www.religiousfreedomwatch.org/extremists/zerpesa1.html
--
http://www.religiousfreedomwatch.org
--
From: Tim Lavoie
Subject: [NOISE] Re: David Tourtezky rant
Date: 
Message-ID: <87znbzkjjq.fsf_-_@theasylum.dyndns.org>
>>>>> "Barb" == The only true Barbara Schwarz <·············@myway.com> writes:

    Barb> Tim Lavoie <········@spamcop.net> wrote in message

    >> Lots of people value freedom of speech.

    Barb> You make mine to a mockery.

Nope. You're free to say what you like, as am I. If you come off as
yet another Usenet Loon, it is your own doing.


    >> If he's posted something you don't like,

    Barb> I don't like? He sexually harassed me with a porn letter!

Not here, he didn't. If so, please cite a Google link.  Your site goes
on about IRC logs, which aren't exactly the paragon of verifiable
identity at the best of times. 


    >> he's at least seemed to do so honestly, under his own name.

    Barb> My sites critical of him were removed by him and his
    Barb> friends, as they lied to the ISPs that my site would be
    Barb> libel! Fine free speech that is. Dave Touretzky likes only
    Barb> one free speech and that is his.

Why, this site you point us to is critical of him, and it is still
there. In fact, it is critical of lots of people. What are your old
sites? We should be able to find archives.


    >> That site you posted a link to has nothing of the sort; no
    >> author, no contact info, no "who are we? (I?)" link.

    Barb> Not true. You are posting falsehoods. Go to the
    Barb> www.religiousfreedomwatch.org. It is all on there.

Nope, it isn't. Your name isn't on there anywhere, and the only email
address is for ·········@... No personal names, other than for
targets. Oh, wait, there are (allegedly third-party) authors' names in
the whistleblower's section. Little on who the site is created by. If
I missed it, please post a link.


    >>  Screaming on about bits of what other people say, out of
    >> context, says more about your ideas than those of anyone else.

    Barb> You cited me out of context, you hypocrite. I believe that
    Barb> all the people that defend porn and bomb instructions guys
    Barb> are like him, the rest is appalled.

Ah, right, anyone who disagrees is a liar and a hypocrite. How silly
of me to forget. I'll have to wait until later to wallow in my
collection of exploding porn.


    Barb> Barbara Schwarz (the only real one)

Bloody good thing, that is. By the way, I just
checked. www.ravingnetloon.org is wide open, along with many
variations. For that matter, religiouswhackowatch.org is just begging
for a site too.  Hm....

 [ I know, don't feed the trolls, and all that. ]
From: David Golden
Subject: Re: [NOISE] Re: David Tourtezky rant
Date: 
Message-ID: <SnVTb.1331$rb.54806@news.indigo.ie>
Tim Lavoie wrote:

> exploding porn.

HOT! Three Way Nitro Action with our Tasty Toluene Temptresses! 
CLOSE-UP! XXX Blasting Caps and Explicit Tamping Scenes!
C4?  See More! 
Our Shockwave Sluts are Waiting for Your Call!
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: [NOISE] Re: David Tourtezky rant
Date: 
Message-ID: <760804b4.0402061016.603d9601@posting.google.com>
Tim Lavoie <········@spamcop.net> wrote in message news:<·················@theasylum.dyndns.org>...
> >>>>> "Barb" == The only true Barbara Schwarz <·············@myway.com> writes:
> 
>     Barb> Tim Lavoie <········@spamcop.net> wrote in message
> 
>     >> Lots of people value freedom of speech.
> 
>     Barb> You make mine to a mockery.
> 
> Nope. You're free to say what you like, as am I. If you come off as
> yet another Usenet Loon, it is your own doing.
> 
> 
>     >> If he's posted something you don't like,
> 
>     Barb> I don't like? He sexually harassed me with a porn letter!
> 
> Not here, he didn't. If so, please cite a Google link.  Your site goes
> on about IRC logs, which aren't exactly the paragon of verifiable
> identity at the best of times. 
> 
> 
>     >> he's at least seemed to do so honestly, under his own name.
> 
>     Barb> My sites critical of him were removed by him and his
>     Barb> friends, as they lied to the ISPs that my site would be
>     Barb> libel! Fine free speech that is. Dave Touretzky likes only
>     Barb> one free speech and that is his.
> 
> Why, this site you point us to is critical of him, and it is still
> there. In fact, it is critical of lots of people. What are your old
> sites? We should be able to find archives.
> 
> 
>     >> That site you posted a link to has nothing of the sort; no
>     >> author, no contact info, no "who are we? (I?)" link.
> 
>     Barb> Not true. You are posting falsehoods. Go to the
>     Barb> www.religiousfreedomwatch.org. It is all on there.
> 
> Nope, it isn't. Your name isn't on there anywhere, 

Of course it is not, as it is not my website!


>and the only email
> address is for ·········@... No personal names, other than for
> targets. Oh, wait, there are (allegedly third-party) authors' names in
> the whistleblower's section. Little on who the site is created by. If
> I missed it, please post a link.

Many websites against SCN are a lot more anonymous.
> 
> 
>     >>  Screaming on about bits of what other people say, out of
>     >> context, says more about your ideas than those of anyone else.
> 
>     Barb> You cited me out of context, you hypocrite. I believe that
>     Barb> all the people that defend porn and bomb instructions guys
>     Barb> are like him, the rest is appalled.
> 
> Ah, right, anyone who disagrees is a liar and a hypocrite. How silly
> of me to forget. I'll have to wait until later to wallow in my
> collection of exploding porn.

Dave Touretzky has new porn pictures of fat ladies on his site. I bet
he took the photos off. But he took the perverted male photo off,
after it was posted that this short thing could he his.

That man is not qualified to educated kids.

That was my website, he and his friends went after with lies, that it
would be libel.

WARNING
To parents of students at Carnegie Mellon University
If you are the parent of a student who attends Carnegie Mellon
University, this notice is posted to help you.

David Touretzky is a research scientist at Carnegie Mellon University.
He teaches some of your children. He claims to be an "educator." For
this reason you should be made aware of the kind of person he is.

David Touretzky owns a website (hosted by the university) that
publishes instructions on how to build bombs. One of these bomb
instructions encourages people to throw these bombs into police cars.
This website is a mirror of an illegal site that was removed by the
FBI after its original creator was arrested. David Touretzky says he
created the mirror as a matter of "free speech." He claims no
responsibility for what his students or other children surfing the net
might do with these instructions. Neither does Carnegie Mellon
University. They allow Touretzky to use the University's computer
server to post this website, on your tax dollar or your tuition fees.
They also appear to have no care for its dangerous content and the
students who might feel encouraged to use them out of false admiration
for their "teacher."

This is not an innocent lack of judgment by Touretzky for, as they
say, where there is smoke there is fire, and Touretzky is involved in
other dangerous and perverted activities. In private and during his
work time he associates with extremists on the internet who attack and
harass religions and ethnic groups. Some of these extremists post
death threats against the people they harass. Touretzky regularly
associates with these people and he supports and encourages their
activities.

Touretzky has perversions that the parents of the students he teaches
should be informed about. He is a customer of sex shops and purchases
sexual implements. The invoice posted on this website as evidence of
this activity shows that Touretzky uses his University office phone
number for this sex shop to contact him. You can compare the phone
number listed in the invoice - 412 268-7561- with the phone number
listed in the university directory which goes to David Touretzky,
www.ri.cmu.edu/people/touretzky_david.htm. You can also find this
connection by searching in Google for "412 268-7561" and "Touretzky".

I had challenged some members of an extremist group on the internet of
which Touretzky is a part but had not really paid much attention to
him. Then I received the evidence presented here, likely by Touretzky
himself as some strange form of harassment. Touretzky supports people
who sexually harass women as can be seen on his website. He also has
pornographic photographs on his website - right there for children to
see - in which he disgraces property belonging to a religion. At that
point I began to research what kind of man Touretzky is and openly
challenged him about his dangerous activities on the internet.

Why would Touretzky encourage extremists and provide instructions on
how to build explosives if he does not have some secret perverted wish
to see others blown to pieces? Why would a teacher of impressionable
students be involved in this? Most important, why does the University
knowingly allow this man to use their server to post information that
is against the law and encourages terrorism? Perhaps for the same
reason they allow Touretzky to use his office phone to order sex toys.
They obviously do not care about their students or the kind of people
who are teaching them or about what their students are being taught.

As an example here are some of the extremists Touretzky calls his
friends:

Robert Clark was arrested in 1990 for hacking into Los Alamos National
Laboratory and has posted bomb threats on the internet.

Zenon Panoussis is hosting websites containing bomb-making
instructions and was a member of the Anti-Olympic Committee which
supported bombings to sabotage the 2004 Olympics. He was arrested in
1999 for verbally assaulting a police officer.

David Rice suggested in a posting to kill members of the FBI. 

Frederic Rice has threatened governmental officials over the Internet.
He also hosts a site where he gives tips on how to kill bikers.

Andreas Heldal-Lund hosts a website with a message board that contains
death threats.

Arnie Lerma is a supporter of the Neo Nazis movement founded by Willis
Carto and is on the Board of Policy of Liberty Lobby, an anti-semitic
organization founded by Carto. He is also associated with the Utopian
Anarchist Party, that promotes the overthrowing of the U.S.
government, the killing of police officers and their website teaches
how to build bombs. Lerma is close to William White, spokesperson of
UAP who was arrested and convicted of battery and carrying a concealed
weapons.

These are the people that Touretzky associates with, people who
encourage terrorism. Touretzky's website also encourages terrorism no
matter his claims of innocence and "free speech". He knows that there
are people out there that want to know how to make explosives and who
will use them against innocent victims. Even if he claims no
responsibility, he is totally responsible for whatever he puts in
people's heads and the terrible results. Same for the Carnegie Mellon
University that sponsors this man and who lets him use facilities that
are sponsored by tax payers money.

Carnegie Mellon University is playing a dangerous game allowing David
Touretzky to continue to work at their university. How can a man with
such a warped mind be allowed to shape the minds of young students?

What if one of these kids uses the bomb instructions that Touretzky
put on the web to harm others?

Do you parents want to wait to find out how tragic the result will be
and if your child will be involved?

I encourage you to start asking questions now. Call the University and
speak to the Dean of Carnegie Mellon or the President (Dr. Jared L
Cohon) or contact the Board of Trustees. Let them know how you feel
about this so-called "educator" being allowed to teach your children.

Do not wait for another tragedy. 

Act now! 

Barbara Schwarz
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <llnluvhe.fsf@ccs.neu.edu>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
>> David Golden wrote:
>> 
>> > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
>> > Introduction to Symbolic Computation" by David S. Touretzky might help you
>> > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
>
>
> How you can recommend anything that porn and bomb instruction guy Dave
> Touretzky wrote is beyond me.  Perhaps you don't know enough about that
> man and never heard him in his own cheap words.

[rant snipped]
This rant has little to do with lisp.

Dr. Touretzky is a respected computer scientist at a top university,
it seems reasonable that many people value his writing.

`www.religiousfreedomwatch.org' on the other hand, is a front for the
Church of Scientology cult.  This cult is known for spamming usenet
groups with pseudorandom postings.  See 
  http://www.techtv.com/cybercrime/features/jump/0,23009,2254599,00.html

See http://www.xenu.net/ for more information.
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <873c9tkksh.fsf@thalassa.informatimago.com>
Joe Marshall <···@ccs.neu.edu> writes:
> [rant snipped]
> This rant has little to do with lisp.
> 
> Dr. Touretzky is a respected computer scientist at a top university,
> it seems reasonable that many people value his writing.
> 
> `www.religiousfreedomwatch.org' on the other hand, is a front for the
> Church of Scientology cult.  This cult is known for spamming usenet
> groups with pseudorandom postings.  See 
>   http://www.techtv.com/cybercrime/features/jump/0,23009,2254599,00.html

Are DNA samples  transmited thru IRC and stored in these "IRC logs"?


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402031036.4d36a7dd@posting.google.com>
Pascal Bourguignon <····@thalassa.informatimago.com> wrote in message news:<··············@thalassa.informatimago.com>...
> Joe Marshall <···@ccs.neu.edu> writes:
> > [rant snipped]
> > This rant has little to do with lisp.
> > 
> > Dr. Touretzky is a respected computer scientist at a top university,
> > it seems reasonable that many people value his writing.
> > 
> > `www.religiousfreedomwatch.org' on the other hand, is a front for the
> > Church of Scientology cult.  This cult is known for spamming usenet
> > groups with pseudorandom postings.  See 
> >   http://www.techtv.com/cybercrime/features/jump/0,23009,2254599,00.html
> 
> Are DNA samples  transmited thru IRC and stored in these "IRC logs"?

Lol, Pascal. What are you trying to say? 

However, Dave Touretzky mailed me a harassing porn letter. I bet I
have his fingerprints and DNA right in the letter.

People don't know the real guy. He harassed me with a porn letter, he
has porn on his website, he has links to the defamatory and sexually
explointing article on Katy Johnson, he provided links to order all
kinds of books to make weapons of mass destructions, the has bomb and
porn instructions on his site, he makes racial remarks about others,
he goes to sites with child porn and posts to his friends about the
genitials of the kids, and he attacks the study tech of L. Ron
Hubbard, which indeed works, he persecutes Narconon, drug rehab
centers, gee, what a good man that is. I am so impressed!

He is also anti-free speech. He and his friends lied to four of my
IPS's that my critical website of Dave Touretzky would be libel to get
the site removed. They are such a bunch of hypocrites, just as you
are, claiming my postings is spam, but yours not.

You should read more about him and his friends below. Yes, also Heldal
Lund, who wants to bake Scientologists. (You recommended his hateful
website!)

Barbara Schwarz (the only real one)


P.S. Postings with e-mail address ···············@emailaccount.com and
identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
and "Truth Speaker 2" are not done by me. Those are forgeries of
criminal, Aids infected, gay lunatic Garry Lynn Scarff who is a
fanatical Dave Touretzky defender. Scarff persecutes me from thread to
thread often using my name as identity for those crimes (!) and
verbally assaults me, threatens me, harasses me, sexually harasses me,
tries to intimidate me, libels, insults and lies about me. He also
lied that he spoke to a roomate of mine in the Utah mental health
hospital. I never was in that hospital, but he probably escaped from
one. Scarff is active member of the gay WeHo "church", that according
to Scarff applaudes Scarffs lawless behavior against me. An ex-WeHo
member wrote me that this "church" sanctions and promotes dishonorable
behavior and that he and his friends were raped and drugged by one of
their active members, and that one of their active members murdered
others under the guise of "drug overdose". The ex-WeHo wrote that the
gay men make sexual innuendo during sermon and "church" leadership
doesn't see what's wrong with that.

Frederic Rice, another fierce David Touretzky defender, posted also
with the stolen identity de Rothschild. He is as little a de
Rothschild as a dirty slimy and greasy punch bag is an impressive man.
He threatened governmental officials over the Internet, wants to
celebrate when both President Bush's are dead and has tips on his
website on how to kill bikers.

His brother David Rice, posts with "Dr." or "Reverend" Desertphile and
also with the stolen identity de Rothschild. He suggested to kill
members of the FBI. (Go to www.religiousfreedom.watch.org, the
extremist pages on David Touretzky, page 9, his connections and click
on the PDF file.) Dave Rice also posted a long time with the identity
"Prozac filled gay terrorist psycho", which tells a lot about him.

Barbara Graham Warr, self-proclaimed "caplain" of the A.R.S. newsgroup
and snakepit, another David Touretzky promoter, is a DUI offender and
pleaded guilty to possession and manufacturing of prohibited weapon
under California penal code. She congratulated the WeHo "congregation"
accepting Scarff's criminal behaviors against me. However, she posted
before that there is no God. She also posts with stolen identity de
Rothschild. - For more, click on the below links.



----------------------------------------------
Linda Anderson
http://www.religiousfreedomwatch.org/extremists/andersenl1.html
Gerald Armstrong
http://www.religiousfreedomwatch.org/extremists/armstrong1.html
Jim Beebe
http://www.religiousfreedomwatch.org/extremists/beebej1.html
Graham Berry
http://www.religiousfreedomwatch.org/extremists/berry.html
David Bird
http://www.religiousfreedomwatch.org/extremists/birdd1.html
Tory Christman
http://religiousfreedomwatch.org/extremists/christmant4.html
Ursula Caberta
http://www.religiousfreedomwatch.org/extremists/caberta.html
Ida Camburn
http://www.religiousfreedomwatch.org/extremists/camburn1.html
Joe Cisar
http://www.religiousfreedomwatch.org/extremists/cisarj1.html
Robert Clark
http://www.religiousfreedomwatch.org/extremists/clark1.html
Elizabeth Ann Cox
http://www.religiousfreedomwatch.org/extremists/coxea1.html
Mark Dallara 
http://www.religiousfreedomwatch.org/extremists/dallara1.html
Alexander Dvorkin
http://www.religiousfreedomwatch.org/extremists/dvorkin1.html
Valerie Emanuel
http://www.religiousfreedomwatch.org/extremists/emanuelv1.html
Steven Fishman
http://www.religiousfreedomwatch.org/extremists/fishman1.html
Vickki Ford Cook
http://www.religiousfreedomwatch.org/extremists/fordv1.html
Phil Georgi
http://www.religiousfreedomwatch.org/extremists/jacobsen6.html
Scott Goehring
http://www.religiousfreedomwatch.org/extremists/goehrings1.html
Roger Gonnet
http://www.religiousfreedomwatch.org/extremists/gonnet1.html
Barbara Graham
http://www.religiousfreedomwatch.org/extremists/graham1.html
Gregg Hagglund
http://www.religiousfreedomwatch.org/extremists/hagglund1.html
Steve Hassan
http://www.religiousfreedomwatch.org/false_exp/hassan1.html
Tilman Hausherr
http://www.religiousfreedomwatch.org/extremists/hauser1.html
Andreas Heldal-Lund
http://www.religiousfreedomwatch.org/extremists/lund1.html
Keith Henson
http://www.religiousfreedomwatch.org/extremists/henson1.html
Deana Holmes
http://www.religiousfreedomwatch.org/extremists/holmes1.html
Jeff Jacobsen
http://www.religiousfreedomwatch.org/extremists/jacobsen1.html
Patrick Jost
http://www.religiousfreedomwatch.org/extremists/jost1.html
Charlotte Kates
http://www.religiousfreedomwatch.org/extremists/katesc1.html
Rod Keller
http://www.religiousfreedomwatch.org/extremists/keller1.html
Steven Kent
http://www.religiousfreedomwatch.org/false_exp/kent1.html
Arnie Lerma
http://www.religiousfreedomwatch.org/extremists/lerma1.html
Joe Lynn
http://www.religiousfreedomwatch.org/extremists/lynn1.html
Ted Mayett
http://www.religiousfreedomwatch.org/extremists/mayett1.html
Frank Oliver
http://www.religiousfreedomwatch.org/extremists/oliver.html
Kady O'Malley
http://www.religiousfreedomwatch.org/extremists/omalley1.html
Zenon Panoussis
http://www.religiousfreedomwatch.org/extremists/panoussis1.html
Ted Patrick
http://www.religiousfreedomwatch.org/false_exp/patrick1.html
Michael Pattinson
http://www.religiousfreedomwatch.org/extremists/pattinsonm1.html
Robert Peterson
http://www.religiousfreedomwatch.org/extremists/peterson1.html
Bruce/Kathleen Pettycrew
http://www.religiousfreedomwatch.org/extremists/pettycrew.html
Jesse Prince
http://www.religiousfreedomwatch.org/extremists/prince1.html
Roland Rashleigh-Berry
http://www.religiousfreedomwatch.org/extremists/rashleighb1.html
David Rice
http://www.religiousfreedomwatch.org/extremists/riced.html
Fred Rice
http://www.religiousfreedomwatch.org/extremists/ricef.html
Rick Ross
http://www.religiousfreedomwatch.org/false_exp/rossr1.html
Karin Spaink
http://www.religiousfreedomwatch.org/extremists/spaink1.html
David Touretzky
http://www.religiousfreedomwatch.org/extremists/touretzky1.html
Alan Walter
http://www.religiousfreedomwatch.org/extremists/walter1.html
Grady Ward
http://www.religiousfreedomwatch.org/extremists/ward.html
Johan Wevers
http://www.religiousfreedomwatch.org/extremists/weversj1.html
Hana/Jerry Whitfield
http://www.religiousfreedomwatch.org/false_exp/whitfield1.html
Larry Wollersheim
http://www.religiousfreedomwatch.org/extremists/wollersheim1.html
Sten-Arne Zerpe
http://www.religiousfreedomwatch.org/extremists/zerpesa1.html
--
http://www.religiousfreedomwatch.org
--
From: ewsnead
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <OhZTb.169329$Rc4.1304199@attbi_s54>
> Lol, Pascal. What are you trying to say?
>
> However, Dave Touretzky mailed me a harassing porn letter. I bet I
> have his fingerprints and DNA right in the letter.
>
> People don't know the real guy. He harassed me with a porn letter, he
> has porn on his website, he has links to the defamatory and sexually
> explointing article on Katy Johnson, he provided links to order all
> kinds of books to make weapons of mass destructions, the has bomb and
> porn instructions on his site, he makes racial remarks about others,
> he goes to sites with child porn and posts to his friends about the
> genitials of the kids, and he attacks the study tech of L. Ron
> Hubbard, which indeed works, he persecutes Narconon, drug rehab
> centers, gee, what a good man that is. I am so impressed!
>
> He is also anti-free speech. He and his friends lied to four of my
> IPS's that my critical website of Dave Touretzky would be libel to get
> the site removed. They are such a bunch of hypocrites, just as you
> are, claiming my postings is spam, but yours not.
>
> You should read more about him and his friends below. Yes, also Heldal
> Lund, who wants to bake Scientologists. (You recommended his hateful
> website!)
>
> Barbara Schwarz (the only real one)
>


For our curious Russian readers, who occasionally drop by ARS to schmooze,
here is a Slavic translation of the above lunatic rants by that
schizophrenic marvel known to the western world as Barbara Schwartz...



Lol, ???????. ?? ????????? ????????

??????, Dave Touretzky ????????? ???? ?????? ?????? porn. ? ?????? ???? I
?????? ??? ???????????? ? ????? ???? ? ??????.

???? ?? ????? ???????? ?????. ?? ????? ???? ? ??????? porn, ??
????? porn ?? ??? website, ?? ????? ?????????? ? defamatory ? ?????????
explointing ?????? ?? Katy Johnson, ?? ????????? ?????????? ??? ???? ?????
????????? ???
???? ???? ??? ???? ????? ??????? ?????? ???????? destructions, ????? ????? ?
?????????? porn ?? ??? ?????, ?? ?????? ??????? ?????????? ? ??????,
?? ???? ? ?????? ? porn ??????? ? ??????? ? ??? ??????? ?
genitials ???????, ? ??? ??????? ??????? ???????? ?. Ron
Hubbard, ??????? ????????????? ????????, ?? ???????? Narconon, rehab
????????
??????, gee, ??? ??????? ??????? ???????. ? ??????? ????? ???? ??? ?
?????????!

?? ????? ????? ????-svobodno ?????. ?? ? ??? ?????? ?????? ?? 4 ?? ?????
IPS's ??? ???? ?????????? website Dave Touretzky ??? ????????, ????? ?????
????????
????? ????????. ??? ????? ????? ??? hypocrites, ??? ??? ??? ??
, ????????? ??? postings spam, ?? ????? ??.

?? ?????? ????????? ?????? ? ?? ? ??? ??????? ????. ??, ????? Heldal
Lund, ??????? ????? ?????? Scientologists. (?? ??????????????? ??? ????????
website!)

??????? Schwarz (???????????? ???????? ????)

ews
-- 
* Effectively invalidating the case gains of Scientologists and ridiculing
the Scientology belief system since 1970 *



"
From: ewsnead
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <7oZTb.169373$Rc4.1304557@attbi_s54>
That's a shame. Apparently the characters of the Slavic alphabet won't show
up except in the form of repeating *?*'s when pasting to this NG from a Word
document.

So much for the Russian connection.

ews

-- 
* Effectively invalidating the case gains of Scientologists and ridiculing
the Scientology belief system since 1970 *
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402031033.4dce19af@posting.google.com>
Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
> 
> > Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> >> David Golden wrote:
> >> 
> >> > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
> >> > Introduction to Symbolic Computation" by David S. Touretzky might help you
> >> > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
> >
> >
> > How you can recommend anything that porn and bomb instruction guy Dave
> > Touretzky wrote is beyond me.  Perhaps you don't know enough about that
> > man and never heard him in his own cheap words.
> 
> [rant snipped]
> This rant has little to do with lisp.

Seems you can't handle the truth about the porn and bomb instructions
guy, Joe Marhall.
> 
> Dr. Touretzky is a respected computer scientist at a top university,
> it seems reasonable that many people value his writing.

Because people don't know the real guy. He harassed me with a porn
letter, he has porn on his website, he has links to the defamatory and
sexually explointing article on Katy Johnson, he provided links to
order all kinds of books to make weapons of mass destructions, the has
bomb and porn instructions on his site, he makes racial remarks about
others, he goes to sites with child porn and posts to his friends
about the genitials of the kids, and he attacks the study tech of L.
Ron Hubbard, which indeed works, he persecutes Narconon, drug rehab
centers, gee, what a good man that is. I am so impressed!

He is also anti-free speech. He and his friends lied to four of my
IPS's that my critical website of Dave Touretzky would be libel to get
the site removed. They are such a bunch of hypocrites, just as you
are, claiming my postings is spam, but yours not.

You should read more about him and his friends below. Yes, also Heldal
Lund, who wants to bake Scientologists. (You recommended his hateful
website!)

Barbara Schwarz (the only real one)


P.S. Postings with e-mail address ···············@emailaccount.com and
identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
and "Truth Speaker 2" are not done by me. Those are forgeries of
criminal, Aids infected, gay lunatic Garry Lynn Scarff who is a
fanatical Dave Touretzky defender. Scarff persecutes me from thread to
thread often using my name as identity for those crimes (!) and
verbally assaults me, threatens me, harasses me, sexually harasses me,
tries to intimidate me, libels, insults and lies about me. He also
lied that he spoke to a roomate of mine in the Utah mental health
hospital. I never was in that hospital, but he probably escaped from
one. Scarff is active member of the gay WeHo "church", that according
to Scarff applaudes Scarffs lawless behavior against me. An ex-WeHo
member wrote me that this "church" sanctions and promotes dishonorable
behavior and that he and his friends were raped and drugged by one of
their active members, and that one of their active members murdered
others under the guise of "drug overdose". The ex-WeHo wrote that the
gay men make sexual innuendo during sermon and "church" leadership
doesn't see what's wrong with that.

Frederic Rice, another fierce David Touretzky defender, posted also
with the stolen identity de Rothschild. He is as little a de
Rothschild as a dirty slimy and greasy punch bag is an impressive man.
He threatened governmental officials over the Internet, wants to
celebrate when both President Bush's are dead and has tips on his
website on how to kill bikers.

His brother David Rice, posts with "Dr." or "Reverend" Desertphile and
also with the stolen identity de Rothschild. He suggested to kill
members of the FBI. (Go to www.religiousfreedom.watch.org, the
extremist pages on David Touretzky, page 9, his connections and click
on the PDF file.) Dave Rice also posted a long time with the identity
"Prozac filled gay terrorist psycho", which tells a lot about him.

Barbara Graham Warr, self-proclaimed "caplain" of the A.R.S. newsgroup
and snakepit, another David Touretzky promoter, is a DUI offender and
pleaded guilty to possession and manufacturing of prohibited weapon
under California penal code. She congratulated the WeHo "congregation"
accepting Scarff's criminal behaviors against me. However, she posted
before that there is no God. She also posts with stolen identity de
Rothschild. - For more, click on the below links.



----------------------------------------------
Linda Anderson
http://www.religiousfreedomwatch.org/extremists/andersenl1.html
Gerald Armstrong
http://www.religiousfreedomwatch.org/extremists/armstrong1.html
Jim Beebe
http://www.religiousfreedomwatch.org/extremists/beebej1.html
Graham Berry
http://www.religiousfreedomwatch.org/extremists/berry.html
David Bird
http://www.religiousfreedomwatch.org/extremists/birdd1.html
Tory Christman
http://religiousfreedomwatch.org/extremists/christmant4.html
Ursula Caberta
http://www.religiousfreedomwatch.org/extremists/caberta.html
Ida Camburn
http://www.religiousfreedomwatch.org/extremists/camburn1.html
Joe Cisar
http://www.religiousfreedomwatch.org/extremists/cisarj1.html
Robert Clark
http://www.religiousfreedomwatch.org/extremists/clark1.html
Elizabeth Ann Cox
http://www.religiousfreedomwatch.org/extremists/coxea1.html
Mark Dallara 
http://www.religiousfreedomwatch.org/extremists/dallara1.html
Alexander Dvorkin
http://www.religiousfreedomwatch.org/extremists/dvorkin1.html
Valerie Emanuel
http://www.religiousfreedomwatch.org/extremists/emanuelv1.html
Steven Fishman
http://www.religiousfreedomwatch.org/extremists/fishman1.html
Vickki Ford Cook
http://www.religiousfreedomwatch.org/extremists/fordv1.html
Phil Georgi
http://www.religiousfreedomwatch.org/extremists/jacobsen6.html
Scott Goehring
http://www.religiousfreedomwatch.org/extremists/goehrings1.html
Roger Gonnet
http://www.religiousfreedomwatch.org/extremists/gonnet1.html
Barbara Graham
http://www.religiousfreedomwatch.org/extremists/graham1.html
Gregg Hagglund
http://www.religiousfreedomwatch.org/extremists/hagglund1.html
Steve Hassan
http://www.religiousfreedomwatch.org/false_exp/hassan1.html
Tilman Hausherr
http://www.religiousfreedomwatch.org/extremists/hauser1.html
Andreas Heldal-Lund
http://www.religiousfreedomwatch.org/extremists/lund1.html
Keith Henson
http://www.religiousfreedomwatch.org/extremists/henson1.html
Deana Holmes
http://www.religiousfreedomwatch.org/extremists/holmes1.html
Jeff Jacobsen
http://www.religiousfreedomwatch.org/extremists/jacobsen1.html
Patrick Jost
http://www.religiousfreedomwatch.org/extremists/jost1.html
Charlotte Kates
http://www.religiousfreedomwatch.org/extremists/katesc1.html
Rod Keller
http://www.religiousfreedomwatch.org/extremists/keller1.html
Steven Kent
http://www.religiousfreedomwatch.org/false_exp/kent1.html
Arnie Lerma
http://www.religiousfreedomwatch.org/extremists/lerma1.html
Joe Lynn
http://www.religiousfreedomwatch.org/extremists/lynn1.html
Ted Mayett
http://www.religiousfreedomwatch.org/extremists/mayett1.html
Frank Oliver
http://www.religiousfreedomwatch.org/extremists/oliver.html
Kady O'Malley
http://www.religiousfreedomwatch.org/extremists/omalley1.html
Zenon Panoussis
http://www.religiousfreedomwatch.org/extremists/panoussis1.html
Ted Patrick
http://www.religiousfreedomwatch.org/false_exp/patrick1.html
Michael Pattinson
http://www.religiousfreedomwatch.org/extremists/pattinsonm1.html
Robert Peterson
http://www.religiousfreedomwatch.org/extremists/peterson1.html
Bruce/Kathleen Pettycrew
http://www.religiousfreedomwatch.org/extremists/pettycrew.html
Jesse Prince
http://www.religiousfreedomwatch.org/extremists/prince1.html
Roland Rashleigh-Berry
http://www.religiousfreedomwatch.org/extremists/rashleighb1.html
David Rice
http://www.religiousfreedomwatch.org/extremists/riced.html
Fred Rice
http://www.religiousfreedomwatch.org/extremists/ricef.html
Rick Ross
http://www.religiousfreedomwatch.org/false_exp/rossr1.html
Karin Spaink
http://www.religiousfreedomwatch.org/extremists/spaink1.html
David Touretzky
http://www.religiousfreedomwatch.org/extremists/touretzky1.html
Alan Walter
http://www.religiousfreedomwatch.org/extremists/walter1.html
Grady Ward
http://www.religiousfreedomwatch.org/extremists/ward.html
Johan Wevers
http://www.religiousfreedomwatch.org/extremists/weversj1.html
Hana/Jerry Whitfield
http://www.religiousfreedomwatch.org/false_exp/whitfield1.html
Larry Wollersheim
http://www.religiousfreedomwatch.org/extremists/wollersheim1.html
Sten-Arne Zerpe
http://www.religiousfreedomwatch.org/extremists/zerpesa1.html
--
http://www.religiousfreedomwatch.org
--
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcvd68wdkxx.fsf@famine.OCF.Berkeley.EDU>
Hey, if you c.l.l.moderated supporters want an *actually* convincing
argument...

·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
>
> > [rant snipped]
> > This rant has little to do with lisp.
> 
> Seems you can't handle the truth about the porn and bomb instructions
> guy, Joe Marhall.

I still don't see any Lisp.

(Checking ...) Nor can I find any porn.  I do find that I have a
deeper respect for Dr. Touretzky, though.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402040839.2823a9bf@posting.google.com>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) wrote in message news:<···············@famine.OCF.Berkeley.EDU>...
> Hey, if you c.l.l.moderated supporters want an *actually* convincing
> argument...
> 
> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
> 
> > Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
> >
> > > [rant snipped]
> > > This rant has little to do with lisp.
> > 
> > Seems you can't handle the truth about the porn and bomb instructions
> > guy, Joe Marhall.
> 
> I still don't see any Lisp.
> 
> (Checking ...) Nor can I find any porn.  I do find that I have a
> deeper respect for Dr. Touretzky, though.


He degrades the Scientology e-meter and shows genitalia and a fat
naked woman in chains. Check SCN "humor" on his site. Last time I
checked it was still there. He also admitted to go to child porn sites
and posted about the genitalia of the kids. (It is the IRC log.) He is
such a pig. He harassed me with a porn letter, and he makes his sex
shop purchases by handing the shop his CMU phone number!

I have no respect for that man, neither for his racial remarks nor for
his religious persecution. He is no professional, and what is your
excuse of him having bomb instructions on his site. He is no free
speech either, as he and his lawless friends lied to four of my IPS
that my website critial of them would be libel.

Barbara Schwarz (the only real one)
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <d68wgexu.fsf@ccs.neu.edu>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> Seems you can't handle the truth about the porn and bomb instructions
> guy, Joe Marhall.

If you wish to continue this discussion, let's take it off line.
There is no content relevant to comp.lang.lisp
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402040831.7d905b7f@posting.google.com>
Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
> 
> > Seems you can't handle the truth about the porn and bomb instructions
> > guy, Joe Marhall.
> 
> If you wish to continue this discussion, let's take it off line.
> There is no content relevant to comp.lang.lisp

Why should other c.l.l. readers not be informed what kind of man Dave
Touretzky is? I don't go in private converstation with people who try
to control freedom of speech, Joe.

Barbara Schwarz (the only real one)


P.S. Postings with e-mail address ···············@emailaccount.com and
identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
and "Truth Speaker 2" are not done by me. Those are forgeries of
criminal, Aids infected, gay lunatic Garry Lynn Scarff who is a
fanatical Dave Touretzky defender. Scarff persecutes me from thread to
thread often using my name as identity for those crimes (!) and
verbally assaults me, threatens me, harasses me, sexually harasses me,
tries to intimidate me, libels, insults and lies about me. He also
lied that he spoke to a roomate of mine in the Utah mental health
hospital. I never was in that hospital, but he probably escaped from
one. Scarff is active member of the gay WeHo "church", that according
to Scarff applaudes Scarffs lawless behavior against me. An ex-WeHo
member wrote me that this "church" sanctions and promotes dishonorable
behavior and that he and his friends were raped and drugged by one of
their active members, and that one of their active members murdered
others under the guise of "drug overdose". The ex-WeHo wrote that the
gay men make sexual innuendo during sermon and "church" leadership
doesn't see what's wrong with that.

Frederic Rice, another fierce David Touretzky defender, posted also
with the stolen identity de Rothschild. He is as little a de
Rothschild as a dirty slimy and greasy punch bag is an impressive man.
He threatened governmental officials over the Internet, wants to
celebrate when both President Bush's are dead and has tips on his
website on how to kill bikers.

His brother David Rice, posts with "Dr." or "Reverend" Desertphile and
also with the stolen identity de Rothschild. He suggested to kill
members of the FBI. (Go to www.religiousfreedom.watch.org, the
extremist pages on David Touretzky, page 9, his connections and click
on the PDF file.) Dave Rice also posted a long time with the identity
"Prozac filled gay terrorist psycho", which tells a lot about him.

Barbara Graham Warr, self-proclaimed "caplain" of the A.R.S. newsgroup
and snakepit, another David Touretzky promoter, is a DUI offender and
pleaded guilty to possession and manufacturing of prohibited weapon
under California penal code. She congratulated the WeHo "congregation"
accepting Scarff's criminal behaviors against me. However, she posted
before that there is no God. She also posts with stolen identity de
Rothschild. - For more, click on the below links.



----------------------------------------------
Linda Anderson
http://www.religiousfreedomwatch.org/extremists/andersenl1.html
Gerald Armstrong
http://www.religiousfreedomwatch.org/extremists/armstrong1.html
Jim Beebe
http://www.religiousfreedomwatch.org/extremists/beebej1.html
Graham Berry
http://www.religiousfreedomwatch.org/extremists/berry.html
David Bird
http://www.religiousfreedomwatch.org/extremists/birdd1.html
Tory Christman
http://religiousfreedomwatch.org/extremists/christmant4.html
Ursula Caberta
http://www.religiousfreedomwatch.org/extremists/caberta.html
Ida Camburn
http://www.religiousfreedomwatch.org/extremists/camburn1.html
Joe Cisar
http://www.religiousfreedomwatch.org/extremists/cisarj1.html
Robert Clark
http://www.religiousfreedomwatch.org/extremists/clark1.html
Elizabeth Ann Cox
http://www.religiousfreedomwatch.org/extremists/coxea1.html
Mark Dallara 
http://www.religiousfreedomwatch.org/extremists/dallara1.html
Alexander Dvorkin
http://www.religiousfreedomwatch.org/extremists/dvorkin1.html
Valerie Emanuel
http://www.religiousfreedomwatch.org/extremists/emanuelv1.html
Steven Fishman
http://www.religiousfreedomwatch.org/extremists/fishman1.html
Vickki Ford Cook
http://www.religiousfreedomwatch.org/extremists/fordv1.html
Phil Georgi
http://www.religiousfreedomwatch.org/extremists/jacobsen6.html
Scott Goehring
http://www.religiousfreedomwatch.org/extremists/goehrings1.html
Roger Gonnet
http://www.religiousfreedomwatch.org/extremists/gonnet1.html
Barbara Graham
http://www.religiousfreedomwatch.org/extremists/graham1.html
Gregg Hagglund
http://www.religiousfreedomwatch.org/extremists/hagglund1.html
Steve Hassan
http://www.religiousfreedomwatch.org/false_exp/hassan1.html
Tilman Hausherr
http://www.religiousfreedomwatch.org/extremists/hauser1.html
Andreas Heldal-Lund
http://www.religiousfreedomwatch.org/extremists/lund1.html
Keith Henson
http://www.religiousfreedomwatch.org/extremists/henson1.html
Deana Holmes
http://www.religiousfreedomwatch.org/extremists/holmes1.html
Jeff Jacobsen
http://www.religiousfreedomwatch.org/extremists/jacobsen1.html
Patrick Jost
http://www.religiousfreedomwatch.org/extremists/jost1.html
Charlotte Kates
http://www.religiousfreedomwatch.org/extremists/katesc1.html
Rod Keller
http://www.religiousfreedomwatch.org/extremists/keller1.html
Steven Kent
http://www.religiousfreedomwatch.org/false_exp/kent1.html
Arnie Lerma
http://www.religiousfreedomwatch.org/extremists/lerma1.html
Joe Lynn
http://www.religiousfreedomwatch.org/extremists/lynn1.html
Ted Mayett
http://www.religiousfreedomwatch.org/extremists/mayett1.html
Frank Oliver
http://www.religiousfreedomwatch.org/extremists/oliver.html
Kady O'Malley
http://www.religiousfreedomwatch.org/extremists/omalley1.html
Zenon Panoussis
http://www.religiousfreedomwatch.org/extremists/panoussis1.html
Ted Patrick
http://www.religiousfreedomwatch.org/false_exp/patrick1.html
Michael Pattinson
http://www.religiousfreedomwatch.org/extremists/pattinsonm1.html
Robert Peterson
http://www.religiousfreedomwatch.org/extremists/peterson1.html
Bruce/Kathleen Pettycrew
http://www.religiousfreedomwatch.org/extremists/pettycrew.html
Jesse Prince
http://www.religiousfreedomwatch.org/extremists/prince1.html
Roland Rashleigh-Berry
http://www.religiousfreedomwatch.org/extremists/rashleighb1.html
David Rice
http://www.religiousfreedomwatch.org/extremists/riced.html
Fred Rice
http://www.religiousfreedomwatch.org/extremists/ricef.html
Rick Ross
http://www.religiousfreedomwatch.org/false_exp/rossr1.html
Karin Spaink
http://www.religiousfreedomwatch.org/extremists/spaink1.html
David Touretzky
http://www.religiousfreedomwatch.org/extremists/touretzky1.html
Alan Walter
http://www.religiousfreedomwatch.org/extremists/walter1.html
Grady Ward
http://www.religiousfreedomwatch.org/extremists/ward.html
Johan Wevers
http://www.religiousfreedomwatch.org/extremists/weversj1.html
Hana/Jerry Whitfield
http://www.religiousfreedomwatch.org/false_exp/whitfield1.html
Larry Wollersheim
http://www.religiousfreedomwatch.org/extremists/wollersheim1.html
Sten-Arne Zerpe
http://www.religiousfreedomwatch.org/extremists/zerpesa1.html
--
http://www.religiousfreedomwatch.org
--
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvr74a$12pa$1@f1node01.rhrz.uni-bonn.de>
> Why should other c.l.l. readers not be informed what kind of man Dave
> Touretzky is? 

Because it's off topic here, and the only effect it will have is that it 
will cause harm to your reputation or that of the organization you are 
working for.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <n07yafsp.fsf@comcast.net>
> Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
>>
>> If you wish to continue this discussion, let's take it off line.
>> There is no content relevant to comp.lang.lisp

·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
> Why should other c.l.l. readers not be informed what kind of man Dave
> Touretzky is? 

A capital idea.  Should anyone be interested in Dr. Touretzky, I have
posted a link to his web site on my home page.  From his web site, you
may find much information about the DMCA, Freedom of Speech, Common
Lisp, and Scientology.  Alas, I was unable to find any pornography,
but perhaps others may be luckier.

> I don't go in private converstation with people who try to control
> freedom of speech, Joe.

Very well.  I will no longer reply to you in this forum unless you
have a question about Lisp.

-- 
~jrm
From: Christopher C. Stacy
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <usmhqya12.fsf@news.dtpq.com>
>>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:

 >> Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
 >>> 
 >>> If you wish to continue this discussion, let's take it off line.
 >>> There is no content relevant to comp.lang.lisp

 Joe> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
 >> Why should other c.l.l. readers not be informed what kind of man Dave
 >> Touretzky is? 

 Joe> A capital idea.  Should anyone be interested in Dr. Touretzky, I have
 Joe> posted a link to his web site on my home page.  From his web site, you
 Joe> may find much information about the DMCA, Freedom of Speech, Common
 Joe> Lisp, and Scientology.  Alas, I was unable to find any pornography,
 Joe> but perhaps others may be luckier.

Perhaps the latter was referring to some code that he wrote.
I know that in my life I've written some things like that...
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcv7jz2cva1.fsf@famine.OCF.Berkeley.EDU>
······@news.dtpq.com (Christopher C. Stacy) writes:

> >>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:
> 
>  Joe> Alas, I was unable to find any pornography,
>  Joe> but perhaps others may be luckier.
> 
> Perhaps the latter was referring to some code that he wrote.
> I know that in my life I've written some things like that...

Or maybe it's hidden in there secretly!  You never know ... just now I
found the following pin-up image hidden in the CLX (or is it CLXXX ?!?!)
sources!  If you change the spacing and line breaks slightly...

;;; appologies to Khamura for filling this image with CLX code..........
                                                    (def-clx-class
                                             (image(
                                      :constructor
                               nil)(:copier nil             )(:predicate
                   nil))(width       0 :type card16           :read-only
               t)           :read-only t       )(height      0     :type
            card16     :read-only                 t)       (       depth
           1         :type                          card8              ;
         :read-only  t)                             (plist             ;
         nil       :type                              list             )
        )         (                                   defmacro         ;
       image-name (                                    image)(getf     (
       image-plist,                                   image  ):name ))(;
       defmacro                                     image-x-hot  ( image
        )          `                               (               getf(
        image-plist,                             image           ):x-hot
         )        )                          (defmacro       image-y-hot
         (image  )       `(getf (image-plist                          ,
        ):y-hot))  (defmacro            image-red-mask                (
image)`        (getf                     (                   image-plist
       ,image):red-mask           )   )    (                           ;
defmacro image-red-mask          (image    )                           `
(getf(image-plist             ,  image    )                  :blue-mask
))(defmaco image-green-mask      (                                image
     )      `    getf                      (                 image-plist
    ,       image                          )                 :green-mask
     (        defun                              print-image      (image
 stream                                    depth  )(declare(type image
  image)                    (            ignore depth
    )   )               (   print-unreadable-object
     ( image            stream :type   t   )                           (
      when  (           image         )     (write-string        (string
       (image-name        image      ) )  stream)     (     write-string
        " "   stream              ))(prin1    (   image-width      image
         stream   )(write-string "x"    stream)(prin1(image-height image
         )(write-string"x"   stream )(prin1 (iamge-depth image)stream)))



Hmm, you don't see it?  Maybe you need to look harder.  Or maybe fuzz
your eyes a little bit.  Or maybe my ascii-art refilling emacs script
isn't very good :-)
The original is here:
  http://groups.google.com/groups?selm=bgghkc%24jp1%2403%241%40news.t-online.com

Okay, my lunch break is oficially over...

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402041720.73bb1d49@posting.google.com>
······@news.dtpq.com (Christopher C. Stacy) wrote in message news:<·············@news.dtpq.com>...
> >>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:
>  
>  Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
>  >>> 
>  >>> If you wish to continue this discussion, let's take it off line.
>  >>> There is no content relevant to comp.lang.lisp
> 
>  Joe> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
>  >> Why should other c.l.l. readers not be informed what kind of man Dave
>  >> Touretzky is? 
> 
>  Joe> A capital idea.  Should anyone be interested in Dr. Touretzky, I have
>  Joe> posted a link to his web site on my home page. 

If somebody makes bombs according to the Dave Touretzky bomb
instructions and throws them in police cars, as he learned on the
Touretzky website, and he came through your website to his website,
Joe, you should be also held responsible for any harm that is caused
by that.

Touretzky has also links to order all kinds of books to make weapons
of mass destructions and other weapons. And he is not pro free speech.
If he would be, why did he and his lawless buddies go after my four
sites that contained no falsehoods, but just critic of him and his
friends?

Barbara Schwarz
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402041738.3dd3e0dd@posting.google.com>
······@news.dtpq.com (Christopher C. Stacy) wrote in message news:<·············@news.dtpq.com>...
> >>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:
>  
>  Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.edu>...
>  >>> 
>  >>> If you wish to continue this discussion, let's take it off line.
>  >>> There is no content relevant to comp.lang.lisp
> 
>  Joe> ·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
>  >> Why should other c.l.l. readers not be informed what kind of man Dave
>  >> Touretzky is? 
> 
>  Joe> A capital idea.  Should anyone be interested in Dr. Touretzky, I have
>  Joe> posted a link to his web site on my home page.  From his web site, you
>  Joe> may find much information about the DMCA, Freedom of Speech, Common
>  Joe> Lisp, and Scientology.  Alas, I was unable to find any pornography,
>  Joe> but perhaps others may be luckier.

The porn you find under section Scientology, e-meter humor, "kinky
things to do with your old e-meter", blah, blah. He has removed one
picture of a man showing all he had, (and he had not much) in
perverted act with the e-meter. That was very insulting, esp. to
Scientologists, who don't use the e-meter for such activities. That is
the same as if somebody takes a religious symbol or property of
another religion and uses it for perverted sexual activites. He is
also otherwise not qualified as SCN critic. He is an idiot.

I bet he took that photo off after it was posted that the naked porn
guy is himself. One of the porn women on his site looks rather young.
She could be one of his students. Do the parents know?

Not long ago, he had nothing covering up anybody in his porn pictures.
But it is still porn. Everybody knows what is under the black stripe.

Dave Touretzky is a pig.

Barbara Schwarz (the only true one) 


       
> 
> Perhaps the latter was referring to some code that he wrote.
> I know that in my life I've written some things like that...
From: Thomas F. Burdick
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <xcvn07yasef.fsf@famine.OCF.Berkeley.EDU>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> The porn you find under section Scientology, e-meter humor, "kinky
> things to do with your old e-meter", blah, blah.

You call that porn?  Official civic celebrations in the city across
the bay (SF) are more explicit than that!  Don't you even know pr0n
when you see it?  I get tons via email every day ... and you call
yourself an internet kook, for shame!

[ I swear I'll leave this troll alone starting now .. er now .. real
  soon now.  When I stop laughing.  "pin needle size spy chips"!!!
  Ahem, I'm better now.  Well, not really, but I'll leave it alone.
  Hee hee hee, remote control porn letter rat-bot!!!!!! ]

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Dave Bird
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <VuF3+8AX7pIAFwKR@xemu.demon.co.uk>
In article<····························@posting.google.com>, The only
true Barbara Schwarz - other postings with my name are forgeries <ARS-
·········@myway.com> writes:
>······@news.dtpq.com (Christopher C. Stacy) wrote in message news:<usmhq
>········@news.dtpq.com>...
>> >>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:
>>  
>>  Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.ed
>u>...
>>  >>> 
>>  >>> If you wish to continue this discussion, let's take it off line.
>>  >>> There is no content relevant to comp.lang.lisp
>> 
>>  Joe> ·············@myway.com (The only true Barbara Schwarz - other postings 
>with my name are forgeries) writes:
>>  >> Why should other c.l.l. readers not be informed what kind of man Dave
>>  >> Touretzky is? 
>> 
>>  Joe> A capital idea.  Should anyone be interested in Dr. Touretzky, I have
>>  Joe> posted a link to his web site on my home page.  From his web site, you
>>  Joe> may find much information about the DMCA, Freedom of Speech, Common
>>  Joe> Lisp, and Scientology.  Alas, I was unable to find any pornography,
>>  Joe> but perhaps others may be luckier.
>
>The porn you find under section Scientology, e-meter humor, "kinky 
>things to do with your old e-meter", blah, blah. He has removed one 
>picture of a man showing all he had, (and he had not much) in perverted 
>act with the e-meter. That was very insulting, esp. to Scientologists, 

 It implied Scientologists are a bunch of pricks?  Pricks, unlike 
 $cientologists, are at least some use in the world.

-- 
 FUCK THE SKULL OF HUBBARD,  AND BUGGER THE DWARF  HE RODE IN ON!!
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 8====3  (O 0)    GROETEN --- PRINTZ XEMU EXTRAWL   no real OT has
          |n|    (COMMANDER,  FIFTH INVADER FORCE)   ever existed 
 .................................................................
 A society without a religion is like a maniac without a chainsaw.
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402070840.438bbb33@posting.google.com>
Dave Bird <···················@nospam.demon.co.uk> wrote in message news:<················@xemu.demon.co.uk>...
> In article<····························@posting.google.com>, The only
> true Barbara Schwarz - other postings with my name are forgeries <ARS-
> ·········@myway.com> writes:
> >······@news.dtpq.com (Christopher C. Stacy) wrote in message news:<usmhq
> >········@news.dtpq.com>...
> >> >>>>> On Wed, 04 Feb 2004 17:57:26 GMT, Joe Marshall ("Joe") writes:
> >>  
> >>  Joe Marshall <···@ccs.neu.edu> wrote in message news:<············@ccs.neu.ed
>  u>...
> >>  >>> 
> >>  >>> If you wish to continue this discussion, let's take it off line.
> >>  >>> There is no content relevant to comp.lang.lisp
> >> 
> >>  Joe> ·············@myway.com (The only true Barbara Schwarz - other postings 
>  with my name are forgeries) writes:
> >>  >> Why should other c.l.l. readers not be informed what kind of man Dave
> >>  >> Touretzky is? 
> >> 
> >>  Joe> A capital idea.  Should anyone be interested in Dr. Touretzky, I have
> >>  Joe> posted a link to his web site on my home page.  From his web site, you
> >>  Joe> may find much information about the DMCA, Freedom of Speech, Common
> >>  Joe> Lisp, and Scientology.  Alas, I was unable to find any pornography,
> >>  Joe> but perhaps others may be luckier.
> >
> >The porn you find under section Scientology, e-meter humor, "kinky 
> >things to do with your old e-meter", blah, blah. He has removed one 
> >picture of a man showing all he had, (and he had not much) in perverted 
> >act with the e-meter. That was very insulting, esp. to Scientologists, 
> 
>  It implied Scientologists are a bunch of pricks?  Pricks, unlike 
>  $cientologists, are at least some use in the world.


It implies that Dave Touretzky is a pig and that he does all he can to
insult Scientologists. Who else than he made those disgusting porn
photos telling Scientologists they should become perverted and use the
e-meter for those perversions.

I think law enforcement should look into it if one of the porn women
of David Touretzky is under age. One looks very young.

And as far as Dave Bird is concerned, he is also perverted. Does not
pull his pants up when he goes in the streets (see his picture on the
www.religiousfreedomwatch.org, the extremist pages), and he wants to
have sex with the skull of a deceased person, as you can read in his
signature line.


Barbara Schwarz (the only real one)


P.S. Postings with e-mail address ···············@emailaccount.com and
identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
and "Truth Speaker 2" are not done by me. Those are forgeries of
criminal, Aids infected, gay lunatic Garry Lynn Scarff who is a
fanatical Dave Touretzky defender. Scarff persecutes me from thread to
thread often using my name as identity for those crimes (!) and
verbally assaults me, threatens me, harasses me, sexually harasses me,
tries to intimidate me, libels, insults and lies about me. He also
lied that he spoke to a roomate of mine in the Utah mental health
hospital. I never was in that hospital, but he probably escaped from
one. Scarff is active member of the gay WeHo "church", that according
to Scarff applaudes Scarffs lawless behavior against me. An ex-WeHo
member wrote me that this "church" sanctions and promotes dishonorable
behavior and that he and his friends were raped and drugged by one of
their active members, and that one of their active members murdered
others under the guise of "drug overdose". The ex-WeHo wrote that the
gay men make sexual innuendo during sermon and "church" leadership
doesn't see what's wrong with that.



Barbara Graham Warr, self-proclaimed "caplain" of the A.R.S. newsgroup
and snakepit, another David Touretzky promoter, is a DUI offender and
pleaded guilty to possession and manufacturing of prohibited weapon
under California penal code. She congratulated the WeHo "congregation"
accepting Scarff's criminal behaviors against me. However, she posted
before that there is no God. She also posts with stolen identity de
Rothschild. - For more, click on the below links.



----------------------------------------------
Linda Anderson
http://www.religiousfreedomwatch.org/extremists/andersenl1.html
Gerald Armstrong
http://www.religiousfreedomwatch.org/extremists/armstrong1.html
Jim Beebe
http://www.religiousfreedomwatch.org/extremists/beebej1.html
Graham Berry
http://www.religiousfreedomwatch.org/extremists/berry.html
David Bird
http://www.religiousfreedomwatch.org/extremists/birdd1.html
Tory Christman
http://religiousfreedomwatch.org/extremists/christmant4.html
Ursula Caberta
http://www.religiousfreedomwatch.org/extremists/caberta.html
Ida Camburn
http://www.religiousfreedomwatch.org/extremists/camburn1.html
Joe Cisar
http://www.religiousfreedomwatch.org/extremists/cisarj1.html
Robert Clark
http://www.religiousfreedomwatch.org/extremists/clark1.html
Elizabeth Ann Cox
http://www.religiousfreedomwatch.org/extremists/coxea1.html
Mark Dallara 
http://www.religiousfreedomwatch.org/extremists/dallara1.html
Alexander Dvorkin
http://www.religiousfreedomwatch.org/extremists/dvorkin1.html
Valerie Emanuel
http://www.religiousfreedomwatch.org/extremists/emanuelv1.html
Steven Fishman
http://www.religiousfreedomwatch.org/extremists/fishman1.html
Vickki Ford Cook
http://www.religiousfreedomwatch.org/extremists/fordv1.html
Phil Georgi
http://www.religiousfreedomwatch.org/extremists/jacobsen6.html
Scott Goehring
http://www.religiousfreedomwatch.org/extremists/goehrings1.html
Roger Gonnet
http://www.religiousfreedomwatch.org/extremists/gonnet1.html
Barbara Graham
http://www.religiousfreedomwatch.org/extremists/graham1.html
Gregg Hagglund
http://www.religiousfreedomwatch.org/extremists/hagglund1.html
Steve Hassan
http://www.religiousfreedomwatch.org/false_exp/hassan1.html
Tilman Hausherr
http://www.religiousfreedomwatch.org/extremists/hauser1.html
Andreas Heldal-Lund
http://www.religiousfreedomwatch.org/extremists/lund1.html
Keith Henson
http://www.religiousfreedomwatch.org/extremists/henson1.html
Deana Holmes
http://www.religiousfreedomwatch.org/extremists/holmes1.html
Jeff Jacobsen
http://www.religiousfreedomwatch.org/extremists/jacobsen1.html
Patrick Jost
http://www.religiousfreedomwatch.org/extremists/jost1.html
Charlotte Kates
http://www.religiousfreedomwatch.org/extremists/katesc1.html
Rod Keller
http://www.religiousfreedomwatch.org/extremists/keller1.html
Steven Kent
http://www.religiousfreedomwatch.org/false_exp/kent1.html
Arnie Lerma
http://www.religiousfreedomwatch.org/extremists/lerma1.html
Joe Lynn
http://www.religiousfreedomwatch.org/extremists/lynn1.html
Ted Mayett
http://www.religiousfreedomwatch.org/extremists/mayett1.html
Frank Oliver
http://www.religiousfreedomwatch.org/extremists/oliver.html
Kady O'Malley
http://www.religiousfreedomwatch.org/extremists/omalley1.html
Zenon Panoussis
http://www.religiousfreedomwatch.org/extremists/panoussis1.html
Ted Patrick
http://www.religiousfreedomwatch.org/false_exp/patrick1.html
Michael Pattinson
http://www.religiousfreedomwatch.org/extremists/pattinsonm1.html
Robert Peterson
http://www.religiousfreedomwatch.org/extremists/peterson1.html
Bruce/Kathleen Pettycrew
http://www.religiousfreedomwatch.org/extremists/pettycrew.html
Jesse Prince
http://www.religiousfreedomwatch.org/extremists/prince1.html
Roland Rashleigh-Berry
http://www.religiousfreedomwatch.org/extremists/rashleighb1.html
David Rice
http://www.religiousfreedomwatch.org/extremists/riced.html
Fred Rice
http://www.religiousfreedomwatch.org/extremists/ricef.html
Rick Ross
http://www.religiousfreedomwatch.org/false_exp/rossr1.html
Karin Spaink
http://www.religiousfreedomwatch.org/extremists/spaink1.html
David Touretzky
http://www.religiousfreedomwatch.org/extremists/touretzky1.html
Alan Walter
http://www.religiousfreedomwatch.org/extremists/walter1.html
Grady Ward
http://www.religiousfreedomwatch.org/extremists/ward.html
Johan Wevers
http://www.religiousfreedomwatch.org/extremists/weversj1.html
Hana/Jerry Whitfield
http://www.religiousfreedomwatch.org/false_exp/whitfield1.html
Larry Wollersheim
http://www.religiousfreedomwatch.org/extremists/wollersheim1.html
Sten-Arne Zerpe
http://www.religiousfreedomwatch.org/extremists/zerpesa1.html
--
http://www.religiousfreedomwatch.org
--
From: ewsnead
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2qtVb.120589$U%5.598409@attbi_s03>
> It implies that Dave Touretzky is a pig and that he does all he can to
> insult Scientologists. Who else than he made those disgusting porn
> photos telling Scientologists they should become perverted and use the
> e-meter for those perversions.
>
> I think law enforcement should look into it if one of the porn women
> of David Touretzky is under age. One looks very young.
>
> And as far as Dave Bird is concerned, he is also perverted. Does not
> pull his pants up when he goes in the streets (see his picture on the
> www.religiousfreedomwatch.org, the extremist pages), and he wants to
> have sex with the skull of a deceased person, as you can read in his
> signature line.

LOL!

Barbara Schwartz, if you weren't already real, I fear someone might have to
invent you just out of spite.
You'll be the death of me yet.

ews
 -- 
* Effectively invalidating the case gains of Scientologists and ridiculing
the Scientology belief system since 1970. *
* So many body thetans, so little time. *

>
> Barbara Schwarz (the only real one)
>
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ad3yfrc8.fsf@thalassa.informatimago.com>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:
> P.S. Postings with e-mail address ···············@emailaccount.com and
> identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
> and "Truth Speaker 2" are not done by me. Those are forgeries of

I  won't believe that  until you  PGP-sign all  your messages  and the
other prove incapable of doing it  with the same secret key.  And even
then, I could still think that you're just schizophrene.

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: a
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <FijUb.61984$vn.164353@sea-read.news.verio.net>
"Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in message
···················@thalassa.informatimago.com...
>
> ·············@myway.com (The only true Barbara Schwarz - other postings
with my name are forgeries) writes:
> > P.S. Postings with e-mail address ···············@emailaccount.com and
> > identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
> > and "Truth Speaker 2" are not done by me. Those are forgeries of
>
> I  won't believe that  until you  PGP-sign all  your messages  and the
> other prove incapable of doing it  with the same secret key.  And even
> then, I could still think that you're just schizophrene.
>
> --
> __Pascal_Bourguignon__                     http://www.informatimago.com/
> There is no worse tyranny than to force a man to pay for what he doesn't
> want merely because you think it would be good for him.--Robert Heinlein
> http://www.theadvocates.org/

Why argue with an AI bot?
From: Christopher C. Stacy
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <uoesd5069.fsf@news.dtpq.com>
>>>>> On Thu, 05 Feb 2004 04:05:57 GMT, a  ("a") writes:

 a> "Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in message
 a> ···················@thalassa.informatimago.com...
 >> 
 >> ·············@myway.com (The only true Barbara Schwarz - other postings
 a> with my name are forgeries) writes:
 >> > P.S. Postings with e-mail address ···············@emailaccount.com and
 >> > identities "Barbara_Schwarz", "the real Barbara Schwarz de Rothschild"
 >> > and "Truth Speaker 2" are not done by me. Those are forgeries of
 >> 
 >> I  won't believe that  until you  PGP-sign all  your messages  and the
 >> other prove incapable of doing it  with the same secret key.  And even
 >> then, I could still think that you're just schizophrene.
 >> 
 >> --
 >> __Pascal_Bourguignon__                     http://www.informatimago.com/
 >> There is no worse tyranny than to force a man to pay for what he doesn't
 >> want merely because you think it would be good for him.--Robert Heinlein
 >> http://www.theadvocates.org/

 a> Why argue with an AI bot?

Why do you say why argue with an AI bot?
Earlier you said something about your lambda thetans.
Please go on.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <8yjhai40.fsf@comcast.net>
······@news.dtpq.com (Christopher C. Stacy) writes:


> Why do you say why argue with an AI bot?
Quick, sing me the BUDAPEST NATIONAL ANTHEM!!

> Earlier you said something about your lambda thetans.
YOW!  I can see 1987!!  PRESIDENT FORD is doing the REMAKE of "PAGAN
LOVE SONG"...he's playing ESTHER WILLIAMS!!

> Please go on.
If I pull this SWITCH I'll be RITA HAYWORTH!!  Or a SCIENTOLOGIST!
From: Karl A. Krueger
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvrb8f$538$1@baldur.whoi.edu>
In comp.lang.lisp The only true Barbara Schwarz - other postings with my name are forgeries <·············@myway.com> wrote:
> Because people don't know the real guy. He harassed me with a porn
> letter, he has porn on his website, he has links to the defamatory and
> sexually explointing article on Katy Johnson, he provided links to
> order all kinds of books to make weapons of mass destructions, the has
> bomb and porn instructions on his site, he makes racial remarks about
> others, he goes to sites with child porn and posts to his friends
> about the genitials of the kids, and he attacks the study tech of L.
> Ron Hubbard, which indeed works, he persecutes Narconon, drug rehab
> centers, gee, what a good man that is. I am so impressed!

Are you the low-tone bad operator who keeps running phony alter-is on
the Narconon and Scientology pages on Wikipedia?  That's strictly from a
condition of non-existence.


> You should read more about him and his friends below. Yes, also Heldal
> Lund, who wants to bake Scientologists. (You recommended his hateful
> website!)

Flunk for bypassing a misunderstood word!  Start over.

-- 
Karl A. Krueger <········@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped.  s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews
From: Lupo LeBoucher
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <peOdnfRt-6ZoWYPdRVn-vw@io.com>
In article <····························@posting.google.com>,
The only true Barbara Schwarz - other postings with my name are forgeries <·············@myway.com> wrote:
>Dave Roberts <·····@re-move.droberts.com> wrote in message
>news:<·······················@attbi_s51>...
>> David Golden wrote:
>> 
>> > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
>> > Introduction to Symbolic Computation" by David S. Touretzky might help you
>> > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
>
>
>How you can recommend anything that porn and bomb instruction guy Dave
>Touretzky wrote is beyond me. Perhaps you don't know enough about that
>man and never heard him in his own cheap words.

Whoa sweetness!
Had I known Touretzsky was into guns and bombs and abortion and nekkid lady pr0n 
and telling the truth about dysfunctional subcultures as much as I am, I would 
have bought his book years ago.

-Lupo
"Satan is the king of the world and he drives a big fucking Buick" <··@io.com>
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-033-738-KL2065E@naggum.no>
* ·············@myway.com
| The only true Barbara Schwarz - other postings with my name are forgeries

  Yeah, I can see how that can be a problem.

  �Religious freedom� includes the freedom to criticize religions and to
  be anti-religious, whatever that means.  When the religious prosecute
  their critics, you have �religious tyranny�, instead.

-- 
Erik Naggum | Oslo, Norway                                      2004-033

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402031042.4831b29e@posting.google.com>
Erik Naggum <····@naggum.no> wrote in message news:<····················@naggum.no>...
> * ·············@myway.com
> | The only true Barbara Schwarz - other postings with my name are forgeries
> 
>   Yeah, I can see how that can be a problem.
> 
>   �Religious freedom� includes the freedom to criticize religions and to
>   be anti-religious, whatever that means.  When the religious prosecute
>   their critics, you have �religious tyranny�, instead.

Dave Touretzky is no critic of Scientology. I rather would describe
him as religious persecutor. He also has not the foggiest about
Scientology, the study technology or Narconon.

Anyway, but talk about his work with rats and mice. (How impressive!)
I read some of his studies and found that he doesn't even know that
animals (as humans) can be run remote controlled. In order to make
reliable tests with animals, you have to check out if they are not
already programmed and run already by some other person with remote
controlled through pin needle size spy chips.

All animals tests that Dave Touretzky made are bogus, as he failed to
crack the code thru which the animals are controlled.

Barbara Schwarz (the only real one)
From: Joe Marshall
Subject: [NOISE] Re: Understanding #' and function variables
Date: 
Message-ID: <8yjkgelj.fsf_-_@ccs.neu.edu>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> In order to make reliable tests with animals, you have to check out
> if they are not already programmed and run already by some other
> person with remote controlled through pin needle size spy chips.

That's not sufficient because there is no way to tell if the
experimenter *himself* isn't already programmed!

Circles within circles.....
From: Erik Winkels
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ptcwnedm.fsf@xs4all.nl>
·············@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) wrote on 3 Feb 2004 10:42:17 -0800:
>
> In order to make reliable tests with animals, you have to check out
> if they are not already programmed and run already by some other
> person with remote controlled through pin needle size spy chips.

Are you a bad troll or a certified nutcase?

Either way, could you please trim comp.lang.lisp from your Newsgroups-
line?  I, for one, would be much obliged.


Kind regards,
Erik.
From: Ray Dillinger
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <401ED91C.10A7EB08@sonic.net>
The only true Barbara Schwarz - other postings with my name are forgeries wrote:
> 
> Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> > David Golden wrote:
> >
> > > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
> > > Introduction to Symbolic Computation" by David S. Touretzky might help you
> > > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
> 
> How you can recommend anything that porn and bomb instruction guy Dave
> Touretzky wrote is beyond me. Perhaps you don't know enough about that
> man and never heard him in his own cheap words.


Hey, anybody who's pissed off the Scientologists this much can't be 
all bad.  

And he's not anti-religious.  He's just anti-scientologist.  There's a 
big difference.  

			Bear

   (proponent of gay and polygamous marriage for those who want it,
    member of a Pagan Sex Cult, and able to review technical work 
    on its merits rather than judging by whether it's written by 
    people I like or not.)
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402031048.241aefb0@posting.google.com>
Ray Dillinger <····@sonic.net> wrote in message news:<·················@sonic.net>...
> The only true Barbara Schwarz - other postings with my name are forgeries wrote:
> > 
> > Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> > > David Golden wrote:
> > >
> > > > Downloading or otherwise finding a copy of "Common Lisp: A Gentle
> > > > Introduction to Symbolic Computation" by David S. Touretzky might help you
> > > > learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
> > 
> > How you can recommend anything that porn and bomb instruction guy Dave
> > Touretzky wrote is beyond me. Perhaps you don't know enough about that
> > man and never heard him in his own cheap words.
> 
> 
> Hey, anybody who's pissed off the Scientologists this much can't be 
> all bad.

Religious persecution is against the law. So, using your words, he
then is all bad.
   
> 
> And he's not anti-religious.  He's just anti-scientologist.  There's a 
> big difference. 

And you weirdo are the one who is able to determine what is a religion
and what not, right?
   
> 
> 			Bear
> 
>    (proponent of gay and polygamous marriage for those who want it,
>     member of a Pagan Sex Cult, and able to review technical work 
>     on its merits rather than judging by whether it's written by 
>     people I like or not.)

Not only Scientologists are concerned about David Touretzky. Did you
nerd read below article?

This article is about porn and bomb instruction guy Dave Touretzky.

http://www.wpxi.com/target11/2176679/detail.html.

CMU professor's website causing controversy, by Karen Welles, Target
11 investigator.


FBI agent Lane Bonner said about the bomb instruction website: "Having
been a law enforcement officer for a number of years, I consider it to
be very, very dangerous conduct and behavior."

Barbara Schwarz (the real one)
From: Ray Dillinger
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <4020688A.4C94DC7@sonic.net>
Barbara Schwarz crossposted:
> 
> Ray Dillinger <····@sonic.net> wrote in message news:<·················@sonic.net>...

> > Hey, anybody who's pissed off the Scientologists this much can't be
> > all bad.

> Not only Scientologists are concerned about David Touretzky. Did you
> nerd read below article?

Okay, in the first place, your response was crossposted from its 
origin on comp.lang.lisp to alt.religion.scientology and 
alt.clearing.technology.  That's rude.  Please don't do it anymore.  
I've fixed the newsgroups line.

What people have tried to explain to you is that this is a technical 
and engineering newsgroup, and work is to be judged here on its technical
and engineering merits.  If you continue to denigrate this work without 
addressing actual relevant issues (ie, its technical and engineering 
merits) then people (well, at least I) will ignore or ridicule you.

By the way, this "only true Barbara Schwarz" thing is silly and makes 
you sound desperate for credibility; you are posting from a free news 
account at Google Groups.  Absolutely anybody can post, under absolutely 
any name, from free news accounts at Google Groups.  If it's really so 
important to you that nobody should be able to forge your name on a post,
then your apparent helplessness to prevent it must be very frustrating.  
If that's the case, then you should learn how to use digital signatures. 

				Bear
From: The only true Barbara Schwarz - other postings with my name are forgeries
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <760804b4.0402061016.560f821@posting.google.com>
Dave Touretzky has new porn pictures of fat ladies on his site. I bet
he took the photos off. But he took the perverted male photo off,
after it was posted that this short thing could he his.

That man is not qualified to educated kids.

That was my website, he and his friends went after with lies, that it
would be libel.

WARNING
To parents of students at Carnegie Mellon University
If you are the parent of a student who attends Carnegie Mellon
University, this notice is posted to help you.

David Touretzky is a research scientist at Carnegie Mellon University.
He teaches some of your children. He claims to be an "educator." For
this reason you should be made aware of the kind of person he is.

David Touretzky owns a website (hosted by the university) that
publishes instructions on how to build bombs. One of these bomb
instructions encourages people to throw these bombs into police cars.
This website is a mirror of an illegal site that was removed by the
FBI after its original creator was arrested. David Touretzky says he
created the mirror as a matter of "free speech." He claims no
responsibility for what his students or other children surfing the net
might do with these instructions. Neither does Carnegie Mellon
University. They allow Touretzky to use the University's computer
server to post this website, on your tax dollar or your tuition fees.
They also appear to have no care for its dangerous content and the
students who might feel encouraged to use them out of false admiration
for their "teacher."

This is not an innocent lack of judgment by Touretzky for, as they
say, where there is smoke there is fire, and Touretzky is involved in
other dangerous and perverted activities. In private and during his
work time he associates with extremists on the internet who attack and
harass religions and ethnic groups. Some of these extremists post
death threats against the people they harass. Touretzky regularly
associates with these people and he supports and encourages their
activities.

Touretzky has perversions that the parents of the students he teaches
should be informed about. He is a customer of sex shops and purchases
sexual implements. The invoice posted on this website as evidence of
this activity shows that Touretzky uses his University office phone
number for this sex shop to contact him. You can compare the phone
number listed in the invoice - 412 268-7561- with the phone number
listed in the university directory which goes to David Touretzky,
www.ri.cmu.edu/people/touretzky_david.htm. You can also find this
connection by searching in Google for "412 268-7561" and "Touretzky".

I had challenged some members of an extremist group on the internet of
which Touretzky is a part but had not really paid much attention to
him. Then I received the evidence presented here, likely by Touretzky
himself as some strange form of harassment. Touretzky supports people
who sexually harass women as can be seen on his website. He also has
pornographic photographs on his website - right there for children to
see - in which he disgraces property belonging to a religion. At that
point I began to research what kind of man Touretzky is and openly
challenged him about his dangerous activities on the internet.

Why would Touretzky encourage extremists and provide instructions on
how to build explosives if he does not have some secret perverted wish
to see others blown to pieces? Why would a teacher of impressionable
students be involved in this? Most important, why does the University
knowingly allow this man to use their server to post information that
is against the law and encourages terrorism? Perhaps for the same
reason they allow Touretzky to use his office phone to order sex toys.
They obviously do not care about their students or the kind of people
who are teaching them or about what their students are being taught.

As an example here are some of the extremists Touretzky calls his
friends:

Robert Clark was arrested in 1990 for hacking into Los Alamos National
Laboratory and has posted bomb threats on the internet.

Zenon Panoussis is hosting websites containing bomb-making
instructions and was a member of the Anti-Olympic Committee which
supported bombings to sabotage the 2004 Olympics. He was arrested in
1999 for verbally assaulting a police officer.

David Rice suggested in a posting to kill members of the FBI. 

Frederic Rice has threatened governmental officials over the Internet.
He also hosts a site where he gives tips on how to kill bikers.

Andreas Heldal-Lund hosts a website with a message board that contains
death threats.

Arnie Lerma is a supporter of the Neo Nazis movement founded by Willis
Carto and is on the Board of Policy of Liberty Lobby, an anti-semitic
organization founded by Carto. He is also associated with the Utopian
Anarchist Party, that promotes the overthrowing of the U.S.
government, the killing of police officers and their website teaches
how to build bombs. Lerma is close to William White, spokesperson of
UAP who was arrested and convicted of battery and carrying a concealed
weapons.

These are the people that Touretzky associates with, people who
encourage terrorism. Touretzky's website also encourages terrorism no
matter his claims of innocence and "free speech". He knows that there
are people out there that want to know how to make explosives and who
will use them against innocent victims. Even if he claims no
responsibility, he is totally responsible for whatever he puts in
people's heads and the terrible results. Same for the Carnegie Mellon
University that sponsors this man and who lets him use facilities that
are sponsored by tax payers money.

Carnegie Mellon University is playing a dangerous game allowing David
Touretzky to continue to work at their university. How can a man with
such a warped mind be allowed to shape the minds of young students?

What if one of these kids uses the bomb instructions that Touretzky
put on the web to harm others?

Do you parents want to wait to find out how tragic the result will be
and if your child will be involved?

I encourage you to start asking questions now. Call the University and
speak to the Dean of Carnegie Mellon or the President (Dr. Jared L
Cohon) or contact the Board of Trustees. Let them know how you feel
about this so-called "educator" being allowed to teach your children.

Do not wait for another tragedy. 

Act now! 

Barbara Schwarz
From: Karl A. Krueger
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <c00s7d$i6$2@baldur.whoi.edu>
The only true Barbara Schwarz - other postings with my name are forgeries <·············@amway.com> wrote:
> Dave Touretzky has new porn pictures of fat ladies on his site. I bet
> he took the photos off. But he took the perverted male photo off,
> after it was posted that this short thing could he his.
> 
> That man is not qualified to educated kids.

Flunk for passing false data on an upstat!  Your stats are down, you are
in a condition of disgrace, please report to the Usenet Ethics Officer
for your sec check.

-- 
Karl A. Krueger <········@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped.  s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews
From: Hrvoje Blazevic
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <401ECADA.4000607@despammed.com>
The only true Barbara Schwarz - other postings with my name are
forgeries wrote:
> Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> 
>>David Golden wrote:
>>
>>
>>>Downloading or otherwise finding a copy of "Common Lisp: A Gentle
>>>Introduction to Symbolic Computation" by David S. Touretzky might help you
>>>learn lisp. http://www-2.cs.cmu.edu/~dst/LispBook/index.html
> 
> 
> 
> How you can recommend anything that porn and bomb instruction guy Dave
> Touretzky wrote is beyond me. Perhaps you don't know enough about that
> man and never heard him in his own cheap words.
> 

Hmmm...

It just dawned on me: I read Touretzkys Gentle Introduction some 10 
years ago as my first Lisp book, and have never been to church since. 
Ergo, this must be his fault -- not that I've ever been to church before 
either :-) :-)

-- Hrvoje
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <y8rmctl2.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> What may help me is to sort of describe a simplistic implementation
> of this in C terms, so I can make the translation.


First a bit of terminology.

A Lisp identifier can refer to a function or a variable (among other
things).  The first identifier in a form refers to a function,
subsequent identifiers refer to variables unless some provision is
made.  So in the expression

   (foo bar baz)

FOO refers to a function, BAR and BAZ refer to variables.

The FUNCALL function takes its first argument and invokes it on the
remaining arguments.  So in the form 

   (funcall foo bar baz)

FOO refers to a variable that will be invoked as a function upon BAR
and BAZ.

The FUNCTION form when used on an identifiers indicates that you wish
to refer to the function, not the variable.  So in the form

  (foo (function bar) baz)

FOO and BAR refer to functions (FOO will be invoked, BAR is just an
argument), baz will refer to a variable.


A variable reference reference may be `free', `bound', or `special'.
A function reference may be `free' or `bound'.  In this expression:

     (let ((x 22))
       (foo x y))

FOO is a free function reference, X is a bound variable, and Y is a
free variable.  In this expression:

    (flet ((foo (a b) (+ a b)))
      (foo 3 4))

FOO is a bound function.


Ok, so here are the rules:

Use FLET, LABELS, and MACROLET to bind functions.

Use LET, LAMBDA, and several other macros, to bind variables.

Free references to functions will use the value found in the function
cell of the appropriate symbol.

References to special variables will use the value found in the value
cell of the appropriate symbol.

Free references to variables will use the value found in the value
cell, but if that is what you want to do, you should declare the
variable special.

>> The other thing: there is nothing preventing a variable from being bound
>> to a function object.  You can do:
>> 
>> (let ((a (lambda (x) x)))
>>   (funcall a 1))
>> 
>> And feel somewhat Scheme-y.
>
> Yes, and this is one thing that confuses me. So what is happening in this
> case? 

The variable A is being bound to a function object.

Thus the reference to A in the second line refers to that function.
FUNCALL invokes this function on the number 1.

> By my probably incorrect notion of what's happening under the hood,
> the LET form is creating a new local symbol(?) named "a," and then binding
> the value portion(?) of that symbol to the lamba expression object. Is that
> right? 

No, the symbol `A' does not get involved here.

>> CL also has a namespace for variables that are to be bound exclusively
>> to functions.  In the above example, the symbol A names a variable bound
>> to a function.  In the following example, the symbol A names a function
>> variable bound to a function:
>> 
>> (flet ((a (x) x))
>>   (a 1))
>
> So is the best way to think about this as two different variables, one
> capable of holding functions and the other values, or is it better to think
> of a single named symbol ("A"), that has pointers/references, one to a
> value and the other to and object. 

For binding, there are two different variables, one in each namespace,
both with the same name.  Although variables can hold function
objects, there is no syntax by which you could put a non-function
object into a function binding.

> In other words, a symbol is implemented as a structure with these
> things along with a reference to a property list and all the other
> things that a symbol has.

A symbol does have these, but it is generally not involved when
binding values or functions.


>> By default, in the arguments of a function call, CL expects that symbols
>> will name ordinary variables.  If you want a symbol to name the function
>> variable in the alternate namespace, then you use #'A.
>> 
>> (let ((a (lambda (x) x)))  ; ordinary variable binding declaration
>>   (flet ((a (x) x))  ; function variable binding declaration
>>     (foo a)  ; A names the ordinary variable
>>     (foo #'a)))  ; #'A names the function variable
>
> So this brings up a good question:  If these are implemented as the same
> symbol with two "slots" (not to be confused with CLOS slots), then it seems
> like this would cause problems. 

Symbols aren't involved.

> If these are really two separate symbols in two separate namespaces
> (like if I was doing name mangling internally or something to
> value-A and function-A), that would seem to be better. The binding
> for "function-A" would go away as the FLET form was exited, while
> that would still leave "value-A" around until the LET form exited.

That's basically what happens.

-- 
~jrm
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <RUfTb.158105$5V2.827517@attbi_s53>
Joe Marshall wrote:

<a lot of good stuff...>


So the conclusion that I'm finally coming to is that I don't understand the
difference between a symbol and a variable. I had though previously that
they were basically the same thing.

So I had thought:

(setq foo 10)

and

(let ((foo 10))
        ...)

were basically creating the same sort of binding object, just that one was
at top-level and the other was local to the LET form. Your description of
all this leads me to believe that this is incorrect and there is something
fundamentally different about top-level vs. lexical bindings.

Now, there doesn't seem to be anything different between these
syntactically. I could just as easily write (+ foo 10), either at top-level
or in the LET scope. That suggests to me that they are the same in terms of
the implementation, but they just differ in scope.

For instance, say I'm in the LET form, I'm imagining the interpreter going
along, finding a reference to foo in (+ foo 10), and then searching for the
binding. It basically says, "Okay, I have this symbol in this list
representing the code of this function. Let's go find the binding for foo."
So it goes to the closest enclosing environment, in this case the one set
up by LET. It finds a binding there where the symbol foo is referenced, and
uses the value. Had it not found that binding there, it would have
progressed to the next greater environment, top-level. In that case, it
would have found a binding of foo there, set the SETQ form.

Is that right?

I'm reading the Gabriel/Pitman article and I got as far as the Notation and
Terminology section where they try to describe all this and I'm stopped,
rereading and rereading.

Specifically, I'm really struggling with the difference between symbol,
variable, binding, and lexical variable. I understand what an identifier
is.

-- Dave
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvk2a0$qh7$2@newsreader2.netcologne.de>
Dave Roberts wrote:

> Specifically, I'm really struggling with the difference between symbol,
> variable, binding, and lexical variable. I understand what an identifier
> is.

You may find http://www.flownet.com/gat/specials.pdf helpful.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2JhTb.75722$U%5.411524@attbi_s03>
Pascal Costanza wrote:

> 
> Dave Roberts wrote:
> 
>> Specifically, I'm really struggling with the difference between symbol,
>> variable, binding, and lexical variable. I understand what an identifier
>> is.
> 
> You may find http://www.flownet.com/gat/specials.pdf helpful.

Thanks. This looks helpful. I like the title. It's just how I'm feeling
right about now... ;-)

-- Dave
From: Bulent Murtezaoglu
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87llnm8d1h.fsf@cubx.internal>
>>>>> "DR" == Dave Roberts <·····@re-move.droberts.com> writes:
     Pascal Costanza wrote:
[...]
    PC> You may find http://www.flownet.com/gat/specials.pdf helpful.

    DR> Thanks. This looks helpful. I like the title. It's just how
    DR> I'm feeling right about now... ;-)

[The title starts with "The Idiot's Guide..." AFAIR]

Um, at the risk of sounding patronizing, might I suggest that you try 
coding a bit and let things sink in?  Common Lisp is not a tiny language 
but the learning process can be a lot of fun provided that you manage to 
strike the right balance between wanting to understand it all at once 
and letting mysterious brain processes crystallize into lucidity whatever 
you pick up from practice.  (yes I do see the smiley)

cheers,

BM
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <IAlTb.164048$nt4.740363@attbi_s51>
Bulent Murtezaoglu wrote:

>>>>>> "DR" == Dave Roberts <·····@re-move.droberts.com> writes:
>      Pascal Costanza wrote:
> [...]
>     PC> You may find http://www.flownet.com/gat/specials.pdf helpful.
> 
>     DR> Thanks. This looks helpful. I like the title. It's just how
>     DR> I'm feeling right about now... ;-)
> 
> [The title starts with "The Idiot's Guide..." AFAIR]
> 
> Um, at the risk of sounding patronizing, might I suggest that you try
> coding a bit and let things sink in?  Common Lisp is not a tiny language
> but the learning process can be a lot of fun provided that you manage to
> strike the right balance between wanting to understand it all at once
> and letting mysterious brain processes crystallize into lucidity whatever
> you pick up from practice.  (yes I do see the smiley)

That's not patronizing at all. In fact, I have started doing just that. Some
of this I'm going to just have to experience. Thanks.

-- Dave
From: Marco Antoniotti
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <NAtTb.12$xV.784@typhoon.nyu.edu>
Dave Roberts wrote:

> Joe Marshall wrote:
> 
> <a lot of good stuff...>
> 
> 
> So the conclusion that I'm finally coming to is that I don't understand the
> difference between a symbol and a variable. I had though previously that
> they were basically the same thing.
> 
> So I had thought:
> 
> (setq foo 10)
> 
> and
> 
> (let ((foo 10))
>         ...)
> 
> were basically creating the same sort of binding object, just that one was
> at top-level and the other was local to the LET form. Your description of
> all this leads me to believe that this is incorrect and there is something
> fundamentally different about top-level vs. lexical bindings.


(let ((foo 42))
    (setq foo #x2A))

What is SETQ doing here?


> 
> Now, there doesn't seem to be anything different between these
> syntactically. I could just as easily write (+ foo 10), either at top-level
> or in the LET scope. That suggests to me that they are the same in terms of
> the implementation, but they just differ in scope.
> 
> For instance, say I'm in the LET form, I'm imagining the interpreter going
> along, finding a reference to foo in (+ foo 10), and then searching for the
> binding. It basically says, "Okay, I have this symbol in this list
> representing the code of this function. Let's go find the binding for foo."
> So it goes to the closest enclosing environment, in this case the one set
> up by LET. It finds a binding there where the symbol foo is referenced, and
> uses the value. Had it not found that binding there, it would have
> progressed to the next greater environment, top-level. In that case, it
> would have found a binding of foo there, set the SETQ form.
> 
> Is that right?

Looks like you got the gist correctly.




> 
> I'm reading the Gabriel/Pitman article and I got as far as the Notation and
> Terminology section where they try to describe all this and I'm stopped,
> rereading and rereading.
> 
> Specifically, I'm really struggling with the difference between symbol,
> variable, binding, and lexical variable. I understand what an identifier
> is.
> 

The differences between these concepts usually do not matter much in 
everyday programmin.  The only rule that counts is: if you see "too 
many" SETF and SETQ's in a program, then something is non-kosher.

Cheers
--
Marco
From: Pascal Bourguignon
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87hdy9mi6s.fsf@thalassa.informatimago.com>
Marco Antoniotti <·······@cs.nyu.edu> writes:
> The differences between these concepts usually do not matter much in
> everyday programmin.  The only rule that counts is: if you see "too
> many" SETF and SETQ's in a program, then something is non-kosher.

Not at all!

The interest of  Lisp is that it's a  programming language that allows
all  programming  styles.   If  your  problem  warrant  an  imperative
solution, there's no problem with having a lot of assignments.



(However, I've  been trying for two  days to write a  small program in
imperative style (I'd like to  write similar demo in other programming
styles  too) in  Lisp  and I  find  it quite  difficult  to stay  100%
imperative...)

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <znc18qbn.fsf@ccs.neu.edu>
Dave Roberts <·····@re-move.droberts.com> writes:

> Joe Marshall wrote:
>
> <a lot of good stuff...>
>
>
> So the conclusion that I'm finally coming to is that I don't understand the
> difference between a symbol and a variable. I had though previously that
> they were basically the same thing.

No.  A symbol is a small data structure, a variable is an abstract
concept.

An identifier may refer to a `bound' variable, or it may be a `free'
variable.  There are two rules for evaluating a bound variable:  If the
variable is not `special', use the binding in the closest lexical
context.  If the variable *is* `special', look in the `value cell' of
the symbol with the same name as the variable.

There is a special evaluation rule for free variables:  always look in
the `value cell' of the symbol with the same name as the variable.

So the value of a variable *may* be stored in the symbol of the same
name, but it doesn't have to be.

> So I had thought:
>
> (setq foo 10)
>
> and
>
> (let ((foo 10))
>         ...)
>
> were basically creating the same sort of binding object, just that one was
> at top-level and the other was local to the LET form. Your description of
> all this leads me to believe that this is incorrect and there is something
> fundamentally different about top-level vs. lexical bindings.

Yes, they are different.  A lexical binding is maintained by the
interpreter or compiler in whatever way the interpreter or compiler
feels is appropriate.  A special or free reference, however, is stored
in the value cell of the symbol.

> Now, there doesn't seem to be anything different between these
> syntactically. I could just as easily write (+ foo 10), either at top-level
> or in the LET scope. That suggests to me that they are the same in terms of
> the implementation, but they just differ in scope.

They differ in implementation as well.  When (+ foo 10) is at top
level, FOO is a `free reference' and thus the value is looked up in
the value cell of the symbol FOO.

When (+ foo 10) is evaluated within the LET scope, however, it is a
`lexical reference' and the value is kept wherever the compiler or
interpreter puts such things.

> For instance, say I'm in the LET form, I'm imagining the interpreter going
> along, finding a reference to foo in (+ foo 10), and then searching for the
> binding. It basically says, "Okay, I have this symbol in this list
> representing the code of this function. Let's go find the binding for foo."
> So it goes to the closest enclosing environment, in this case the one set
> up by LET. It finds a binding there where the symbol foo is referenced, and
> uses the value. Had it not found that binding there, it would have
> progressed to the next greater environment, top-level. In that case, it
> would have found a binding of foo there, set the SETQ form.
>
> Is that right?

Close.  When the interpreter sees the reference to FOO, and it notices
that FOO is *not* lexically bound, it is required to apply the `free
reference' rule and look in the value cell of the symbol FOO. 

> Specifically, I'm really struggling with the difference between symbol,
> variable, binding, and lexical variable. I understand what an identifier
> is.

I think you understand what a variable, binding, and lexical variable
are, and I think you are trying to fit `symbol' into that picture.  A
symbol is a little data structure with a name, property list, package,
etc.  The `value cell' of a symbol is where the interpreter or
compiler is required to store the top-level value or current dynamic
value of a variable, and the `function cell' is where the interpreter
or compiler is required to store the top-level function value, but
otherwise the symbol is not used.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202040845250001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

>  A special or free reference, however, is stored
> in the value cell of the symbol.

This is often claimed, but is in fact incorrect.  It is an adequate model
in a single-threaded environment, but breaks badly in a multi-threaded
environment.  It really is best to think of both lexical and
special/dynamic variables in terms of bindings, with the difference being
only how the scope of those bindings is maintained.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <wu75uzn9.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
>
>>  A special or free reference, however, is stored
>> in the value cell of the symbol.
>
> This is often claimed, but is in fact incorrect.  

It is correct, as can be demonstrated by this conforming program:

(defvar *my-special-variable* 0)

(let ((*my-special-variable* 'bound))
  (symbol-value '*my-special-variable*))

=>  'bound

> It is an adequate model in a single-threaded environment, but breaks
> badly in a multi-threaded environment.  

The model does not break.  What would break is a naive implementation
of the model.  A multi-threaded environment would have to ensure that
the dynamic bindings in each thread behaved as if the value cell was
where the value were stored.  Many multi-threaded implementations do
this by swapping the values in and out during thread switches, but
others do it by maintaining thread-local versions of the values. 
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041032030001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
> >
> >>  A special or free reference, however, is stored
> >> in the value cell of the symbol.
> >
> > This is often claimed, but is in fact incorrect.  
> 
> It is correct

Misleading then.  What is misleading is the implication through the use of
the singular article "the" (referring to "the value cell") that a symbol
has one and only one value cell.  It doesn't.  It has (potentially) one
value cell per thread, plus a global value cell.

> as can be demonstrated by this conforming program:
> 
> (defvar *my-special-variable* 0)
> 
> (let ((*my-special-variable* 'bound))
>   (symbol-value '*my-special-variable*))
> 
> =>  'bound

All this demonstrates is that the value of a special binding can be
accessed by the symbol-value function.  Yes, I know that the spec says
that the symbol-value function is an accessor that accesses "the symbol's
value cell" but note the care that Kent takes in his phraseology to avoid
applying the singular article "the" to "value cell".  BTW the spec then
goes on to define value cell as "The place which holds the value, if any,
of the dynamic variable named by that symbol, and which is accessed by
symbol-value."  So these definitions are circular.


> > It is an adequate model in a single-threaded environment, but breaks
> > badly in a multi-threaded environment.  
> 
> The model does not break.

The model of a symbol having a single value cell which can be referred to
as "*the* value cell of the symbol" does break in a multithreaded
environment (which is outside the scope of the spec), as can be easily
demonstrated by the following code:

(defvar *foo* 1)
(defun f1 () (loop (print *foo*)))
(defun f2 () (let ( (*foo* 2) ) (f1)))
(process-run-function f1)
(process-run-function f2)

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hdy9uuu0.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
>
>> ·········@jpl.nasa.gov (Erann Gat) writes:
>> 
>> > In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
>> >
>> >>  A special or free reference, however, is stored
>> >> in the value cell of the symbol.
>> >
>> > This is often claimed, but is in fact incorrect.  
>> 
>> It is correct
>
> Misleading then.  What is misleading is the implication through the use of
> the singular article "the" (referring to "the value cell") that a symbol
> has one and only one value cell.  It doesn't.  It has (potentially) one
> value cell per thread, plus a global value cell.

In Allegro 6, there is one value cell in a symbol and the symbol-value
function fetches the contents.  Dynamic binding mutates that value
cell.  When a thread switch occurs, the values that have been
dynamically bound in the thread that is exiting will be saved, and the
values bound in the thread that is entered will be restored.

This is also true in Lispworks, Liquid (nee Lucid) Common Lisp, and
how it worked on the Lisp Machine.  In fact, the only major
implementation that I know of that *doesn't* do it this way is Corman
Common Lisp.

> The model of a symbol having a single value cell which can be referred to
> as "*the* value cell of the symbol" does break in a multithreaded
> environment (which is outside the scope of the spec), as can be easily
> demonstrated by the following code:
>
> (defvar *foo* 1)
> (defun f1 () (loop (print *foo*)))
> (defun f2 () (let ( (*foo* 2) ) (f1)))
> (process-run-function f1)
> (process-run-function f2)

I don't know how this is supposed to demonstrate the model breaking.

Lisps that have extended the specification to include multiple threads
generally do so in a way that each thread preserves the illusion that
it is the only thread vis-a-vis dynamic binding.  I grant you that the
implementation may be quite a bit more complicated.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041234580001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
> >
> >> ·········@jpl.nasa.gov (Erann Gat) writes:
> >> 
> >> > In article <············@ccs.neu.edu>, Joe Marshall
<···@ccs.neu.edu> wrote:
> >> >
> >> >>  A special or free reference, however, is stored
> >> >> in the value cell of the symbol.
> >> >
> >> > This is often claimed, but is in fact incorrect.  
> >> 
> >> It is correct
> >
> > Misleading then.  What is misleading is the implication through the use of
> > the singular article "the" (referring to "the value cell") that a symbol
> > has one and only one value cell.  It doesn't.  It has (potentially) one
> > value cell per thread, plus a global value cell.
> 
> In Allegro 6, there is one value cell in a symbol and the symbol-value
> function fetches the contents.  Dynamic binding mutates that value
> cell.  When a thread switch occurs, the values that have been
> dynamically bound in the thread that is exiting will be saved, and the
> values bound in the thread that is entered will be restored.
> 
> This is also true in Lispworks, Liquid (nee Lucid) Common Lisp, and
> how it worked on the Lisp Machine.  In fact, the only major
> implementation that I know of that *doesn't* do it this way is Corman
> Common Lisp.

Time slicing is not the only way to implement threads.  The implementation
strategy you describe will fail on a multiprocessor.  Or are you really
insisting that the Standard requires the language to be implemented in a
way that fails when used with parallel processors?

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <vfmptaxc.fsf@ccs.neu.edu>
·········@jpl.nasa.gov (Erann Gat) writes:

> Time slicing is not the only way to implement threads.  The implementation
> strategy you describe will fail on a multiprocessor.  Or are you really
> insisting that the Standard requires the language to be implemented in a
> way that fails when used with parallel processors?

No, of course not.  I'm just pointing out that the implementation
strategy, while non-optimal and fraught with difficulty, has been the
de-facto standard for quite some time.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041517510001@k-137-79-50-101.jpl.nasa.gov>
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > Time slicing is not the only way to implement threads.  The implementation
> > strategy you describe will fail on a multiprocessor.  Or are you really
> > insisting that the Standard requires the language to be implemented in a
> > way that fails when used with parallel processors?
> 
> No, of course not.  I'm just pointing out that the implementation
> strategy, while non-optimal and fraught with difficulty, has been the
> de-facto standard for quite some time.

Think about what you just wrote, and ask yourself: on the assumption that
your goal is to show Common Lisp in a good light, is this a fact that you
really want to trumpet to the world?

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <d68xc52i.fsf@comcast.net>
·········@jpl.nasa.gov (Erann Gat) writes:

> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
>
>> ·········@jpl.nasa.gov (Erann Gat) writes:
>> 
>> > Time slicing is not the only way to implement threads.  The implementation
>> > strategy you describe will fail on a multiprocessor.  Or are you really
>> > insisting that the Standard requires the language to be implemented in a
>> > way that fails when used with parallel processors?
>> 
>> No, of course not.  I'm just pointing out that the implementation
>> strategy, while non-optimal and fraught with difficulty, has been the
>> de-facto standard for quite some time.
>
> Think about what you just wrote, and ask yourself: on the assumption that
> your goal is to show Common Lisp in a good light, is this a fact that you
> really want to trumpet to the world?

My goal was to help Dave Roberts understand lexical and dynamic
binding and how it relates to symbols.

-- 
~jrm
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <YsPTb.173501$nt4.762755@attbi_s51>
Joe Marshall wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
>> In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu>
>> wrote:
>>
>>> ·········@jpl.nasa.gov (Erann Gat) writes:
>>> 
>>> > Time slicing is not the only way to implement threads.  The
>>> > implementation
>>> > strategy you describe will fail on a multiprocessor.  Or are you
>>> > really insisting that the Standard requires the language to be
>>> > implemented in a way that fails when used with parallel processors?
>>> 
>>> No, of course not.  I'm just pointing out that the implementation
>>> strategy, while non-optimal and fraught with difficulty, has been the
>>> de-facto standard for quite some time.
>>
>> Think about what you just wrote, and ask yourself: on the assumption that
>> your goal is to show Common Lisp in a good light, is this a fact that you
>> really want to trumpet to the world?
> 
> My goal was to help Dave Roberts understand lexical and dynamic
> binding and how it relates to symbols.
> 

For which I thank you. BTW, this discussion is very enlightening. You guys
go ahead and discuss it. I'll just watch. Seriously, I'm learning a lot.
;-)

-- Dave
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvmnsq$st4$1@newsreader2.netcologne.de>
Joe Marshall wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
>>Time slicing is not the only way to implement threads.  The implementation
>>strategy you describe will fail on a multiprocessor.  Or are you really
>>insisting that the Standard requires the language to be implemented in a
>>way that fails when used with parallel processors?
> 
> No, of course not.  I'm just pointing out that the implementation
> strategy, while non-optimal and fraught with difficulty, has been the
> de-facto standard for quite some time.

I think you are talking at cross purposes. I agree with Erann that it 
doesn't matter how dynamically scoped variables are implemented. The 
important thing is to have a correct mental model of what is happening 
when you bind them, set them or look them up. (I don't agree with both 
of you that there is one single right model.)

I think it's important to note where they come from. I have always found 
the fact enlightening that they were the natural way to implement 
variables in the original interpreted Lisp, as is described in The Art 
of the Interpreter. Shallow binding and deep binding were developed 
later on. It's interesting to note that most implementation techniques 
effectively try to keep the semantics of the interpreter-based semantics.

I don't think there is a right way to describe them, there are just 
different perspectives. Each of them helps you to better understand the 
issues involved.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-033-934-KL2065E@naggum.no>
* Erann Gat
| Or are you really insisting that the Standard requires the language to
| be implemented in a way that fails when used with parallel processors?

  Another annoying straw man argument.

  The standard has specified the semantics of several operators, and
  that is the only interface you need to worry about.  If you start to
  worry about the implementation being in conflict with the standard,
  you are either a vendor or just plain nuts.  As a vendor, you would do
  whatever is necessary to remain conforming.  As just plain nuts, you
  would keep arguing that you cannot figure something out, so therefore
  there must be a flaw in reality.

  The function SYMBOL-VALUE is defined to return the value of the global
  binding of that symbol in the dynamic environment.  How it arranges
  for this is none of your business.  Whether there is a system-wide or
  a universe-wide global binding that you can modify or not is not part
  of the standardized interface.

-- 
Erik Naggum | Oslo, Norway                                      2004-033

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Frode Vatvedt Fjeld
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2hznc11c2w.fsf@vserver.cs.uit.no>
Joe Marshall <···@ccs.neu.edu> writes:

> In Allegro 6, there is one value cell in a symbol and the
> symbol-value function fetches the contents.  Dynamic binding mutates
> that value cell.  When a thread switch occurs, the values that have
> been dynamically bound in the thread that is exiting will be saved,
> and the values bound in the thread that is entered will be restored.

The problem with this approach is that it is fundamentally
incompatible with true concurrency, i.e. SMP systems. Presumably it
also breaks if OS threads are used, when the lisp system doesn't have
sufficient control over context switches.

> This is also true in Lispworks, Liquid (nee Lucid) Common Lisp, and
> how it worked on the Lisp Machine.  In fact, the only major
> implementation that I know of that *doesn't* do it this way is
> Corman Common Lisp.

From what little I know about SBCL, I guess it's false also for this
implementation.

-- 
Frode Vatvedt Fjeld
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <4qu9utm7.fsf@ccs.neu.edu>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> Joe Marshall <···@ccs.neu.edu> writes:
>
>> In Allegro 6, there is one value cell in a symbol and the
>> symbol-value function fetches the contents.  Dynamic binding mutates
>> that value cell.  When a thread switch occurs, the values that have
>> been dynamically bound in the thread that is exiting will be saved,
>> and the values bound in the thread that is entered will be restored.
>
> The problem with this approach is that it is fundamentally
> incompatible with true concurrency, i.e. SMP systems. Presumably it
> also breaks if OS threads are used, when the lisp system doesn't have
> sufficient control over context switches.

Yes.  Allegro 6 does not support OS threads.
From: Edi Weitz
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <m3smhtp75f.fsf@bird.agharta.de>
On Mon, 02 Feb 2004 15:14:08 -0500, Joe Marshall <···@ccs.neu.edu> wrote:

> Yes.  Allegro 6 does not support OS threads.

According to

  <http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm>

it does on Windows.

Edi.
From: Carl Shapiro
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ouysmhtb3x4.fsf@panix3.panix.com>
Edi Weitz <···@agharta.de> writes:

> According to
> 
>   <http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm>
> 
> it does on Windows.

Allegro on Win32 supports native threads in the same half-hearted way
that LispWorks for Windows does: by scheduling all of the native
threads serially.  There may be some exceptional corner-cases, but on
those two Lisps you cannot have more than one Lisp thread in effect at
a time.  Corman Common Lisp does not have this limitation.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <hdy9c58x.fsf@comcast.net>
Carl Shapiro <·············@panix.com> writes:

> Edi Weitz <···@agharta.de> writes:
>
>> According to
>> 
>>   <http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm>
>> 
>> it does on Windows.
>
> Allegro on Win32 supports native threads in the same half-hearted way
> that LispWorks for Windows does: by scheduling all of the native
> threads serially.  There may be some exceptional corner-cases, but on
> those two Lisps you cannot have more than one Lisp thread in effect at
> a time.  Corman Common Lisp does not have this limitation.

It appears that Allegro 6.2 has overcome this limitation.

-- 
~jrm
From: Carl Shapiro
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ouybrogyccc.fsf@panix3.panix.com>
Joe Marshall <·············@comcast.net> writes:

> It appears that Allegro 6.2 has overcome this limitation.

I was was unable to find any documentation which would suggest that
the situation has changed in this regard.  On the other hand, section
1.8 of the "Foreign Function Interface" documentation would support my
previous assertion.  Do you have information to the contrary?  I have
been lead to believe by the good people at Franz that this feature,
while not currently present in their Lisp, is to appear in a future
release.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <4qu8czgf.fsf@comcast.net>
Carl Shapiro <·············@panix.com> writes:

> Joe Marshall <·············@comcast.net> writes:
>
>> It appears that Allegro 6.2 has overcome this limitation.
>
> I was was unable to find any documentation which would suggest that
> the situation has changed in this regard.  On the other hand, section
> 1.8 of the "Foreign Function Interface" documentation would support my
> previous assertion.  Do you have information to the contrary?  I have
> been lead to believe by the good people at Franz that this feature,
> while not currently present in their Lisp, is to appear in a future
> release.

Duane Rettig informs me that this section describes it:
See
http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm#wide-binding-1


-- 
~jrm
From: Carl Shapiro
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ouyfzdsnq88.fsf@panix3.panix.com>
Joe Marshall <·············@comcast.net> writes:

> Duane Rettig informs me that this section describes it:
> See
> http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm#wide-binding-1

Yes, as far as the binding model is concerned, you are correct.
Sorry, I think I was talking past you; having not realizing that the
multiprocessing-friendly binding mechanism is what was only being
referenced.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <znc1tb1a.fsf@ccs.neu.edu>
Edi Weitz <···@agharta.de> writes:

> On Mon, 02 Feb 2004 15:14:08 -0500, Joe Marshall <···@ccs.neu.edu> wrote:
>
>> Yes.  Allegro 6 does not support OS threads.
>
> According to
>
>   <http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm>
>
> it does on Windows.

Whoops!  My mistake on that one.

However, releases of Allegro prior to version 6.2 used shallow binding
and therefore needed to wind and unwind the binding stack upon thread
switches.
From: Duane Rettig
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <4ektcd4x7.fsf@franz.com>
Joe Marshall <···@ccs.neu.edu> writes:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> > In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
> >
> >> ·········@jpl.nasa.gov (Erann Gat) writes:
> >> 
> >> > In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
> >> >
> >> >>  A special or free reference, however, is stored
> >> >> in the value cell of the symbol.
> >> >
> >> > This is often claimed, but is in fact incorrect.  
> >> 
> >> It is correct
> >
> > Misleading then.  What is misleading is the implication through the use of
> > the singular article "the" (referring to "the value cell") that a symbol
> > has one and only one value cell.  It doesn't.  It has (potentially) one
> > value cell per thread, plus a global value cell.
> 
> In Allegro 6, there is one value cell in a symbol and the symbol-value
> function fetches the contents.  Dynamic binding mutates that value
> cell.  When a thread switch occurs, the values that have been
> dynamically bound in the thread that is exiting will be saved, and the
> values bound in the thread that is entered will be restored.
> 
> This is also true in Lispworks, Liquid (nee Lucid) Common Lisp, and
> how it worked on the Lisp Machine.  In fact, the only major
> implementation that I know of that *doesn't* do it this way is Corman
> Common Lisp.

These two paragraphs are at odds with each other.  When you first
described Allegro 6 (which I took to mean Allegro CL 6.0), I thought
to myself that you were leading up to the next point, which was that
later versions in fact do have one value cell per thread.  But then,
you went on to say that Corman was the only lisp to do this.  I can
only conclude then, that you've never tried Allegro CL 6.2, which
supports a concept we call "wide binding".  It is slightly different
than Corman's concept, which allocates an array of value cells per
thread and then assigns each symbol an index; Wide-binding allocates
the vector to the symbol, and thus has one cell per thread index.
Conceptually, though, they are the same; each implement a
two-dimensional matrix of value-per-thread, but instead of being
a question of row-major vs column-major, the differences here are
thread-major vs symbol-major...

See
http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm#wide-binding-1


-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <8yjkczia.fsf@comcast.net>
Duane Rettig <·····@franz.com> writes:

> These two paragraphs are at odds with each other.  When you first
> described Allegro 6 (which I took to mean Allegro CL 6.0), I thought
> to myself that you were leading up to the next point, which was that
> later versions in fact do have one value cell per thread.  But then,
> you went on to say that Corman was the only lisp to do this.  I can
> only conclude then, that you've never tried Allegro CL 6.2, which
> supports a concept we call "wide binding".  It is slightly different
> than Corman's concept, which allocates an array of value cells per
> thread and then assigns each symbol an index; Wide-binding allocates
> the vector to the symbol, and thus has one cell per thread index.
> Conceptually, though, they are the same; each implement a
> two-dimensional matrix of value-per-thread, but instead of being
> a question of row-major vs column-major, the differences here are
> thread-major vs symbol-major...
>
> See
> http://www.franz.com/support/documentation/6.2/doc/multiprocessing.htm#wide-binding-1

Yes.  I knew that multiple value cells were going to be added to
Allegro, but I did not know that Allegro 6.2 had them already.

My apologies to Franz.

To restate correctly, both Corman Common Lisp and Franz Allegro
(version 6.2 and later) support a shallow binding model in which
multiple value cells are kept for each symbol.


-- 
~jrm
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-033-838-KL2065E@naggum.no>
* Joe Marshall
> A special or free reference, however, is stored in the value cell of
> the symbol.

* Erann Gat
| This is often claimed, but is in fact incorrect.  It is an adequate
| model in a single-threaded environment, but breaks badly in a
| multi-threaded environment.

  So, since the same symbol exists in different Common Lisp worlds on
  different computers all across the Internet, it is �misleading� to
  refer to a symbol's value cell as a unique place.  Right?

  There is no way in Common Lisp to refer to symbols in any but the
  current thread.  All references to values of symbols will therefore be
  those in the current thread.  Whether there exist some other values or
  some other dimension or some other invocation of the Common Lisp world
  on some other computer somewhere else, is completely irrelevant.

  One of the beauties of the Common Lisp environments and their thread
  support is that it does not violate the conceptual models we have.
  What you obsess about is immaterial, irrelevant, and very annoying
  because /you/ violate the conceptual models of the language.

  What I cannot quite come to grips with is that during 2003, you have
  learned exactly /nothing/.  The same stupid discussions keep going
  around and around and you make the same stupid arguments in 2004 as
  you did in 2002.  It was annoying then, and it's annoying now.  *sigh*

-- 
Erik Naggum | Oslo, Norway                                      2004-033

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041515110001@k-137-79-50-101.jpl.nasa.gov>
In article <····················@naggum.no>, Erik Naggum <····@naggum.no> wrote:

>   There is no way in Common Lisp to refer to symbols in any but the
>   current thread.  All references to values of symbols will therefore be
>   those in the current thread.

Hogwash.

? (defvar *x* 1)
*X*
? (defvar *p* (process-run-function "p" (lambda () (let ( (*x* 2) ) (loop)))))
*P*
? *x*
1
? (symbol-value-in-process '*x* *p*)
2
? 

>   What I cannot quite come to grips with is that during 2003, you have
>   learned exactly /nothing/.  The same stupid discussions keep going
>   around and around and you make the same stupid arguments in 2004 as
>   you did in 2002.

What you are having a hard time coming to grips with, it seems to me, is
that I understand this better than you do.

>  It was annoying then, and it's annoying now.  *sigh*

Now there at least is something we can agree on.

E.
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-034-AZW-KL2065E@naggum.no>
* Erik Naggum
> There is no way in Common Lisp to refer to symbols in any but the
> current thread.  All references to values of symbols will therefore be
> those in the current thread.

* Erann Gat
| Hogwash.
| 
| ? (defvar *x* 1)
| *X*
| ? (defvar *p* (process-run-function "p" (lambda () (let ( (*x* 2) ) (loop)))))
| *P*
| ? *x*
| 1
| ? (symbol-value-in-process '*x* *p*)
| 2
| ? 

  Hogwash?  And PROCESS-RUN-FUNCTION and SYMBOL-VALUE-IN-PROCESS are
  specified /where/ in ANSI X3.226-1994?

  If you add extensions, it's your duty to maintain the semantics of the
  standard to which you purport to conform.  If you fail in this duty,
  it is not the standard's fault.

  Upgrade your brain to acquire the concept of �context�, please.

-- 
Erik Naggum | Oslo, Norway                                      2004-034

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0202041717500001@192.168.1.51>
In article <····················@naggum.no>, Erik Naggum <····@naggum.no> wrote:

> * Erik Naggum
> > There is no way in Common Lisp to refer to symbols in any but the
> > current thread.  All references to values of symbols will therefore be
> > those in the current thread.
> 
> * Erann Gat
> | Hogwash.
> | 
> | ? (defvar *x* 1)
> | *X*
> | ? (defvar *p* (process-run-function "p" (lambda () (let ( (*x* 2) )
(loop)))))
> | *P*
> | ? *x*
> | 1
> | ? (symbol-value-in-process '*x* *p*)
> | 2
> | ? 
> 
>   Hogwash?

Hogwash.  Bunkum.  Nonsense.  Bullsh*t.  Flim flam.  Horse hockey. 
Self-evidently untrue to anyone with half a brain.  Am I making myself
clear?

>  And PROCESS-RUN-FUNCTION and SYMBOL-VALUE-IN-PROCESS are
>   specified /where/ in ANSI X3.226-1994?

The standard doesn't mention threads at all, so any discussion of threads
necessarily presumes extensions to the standard.  (Sigh.  I get so tired
of explaining elementary logic to you.)

Editorial note: It would require one to have less wit than God gave to a
hamster to take the standard as a complete specification.  The standard
mentions neither threads, nor TCP streams, nor database connectivity, nor
foreign function interfaces, nor any of a dozen other things that are part
and parcel of today's computing world but which cannot be implemented
except as extensions to the standard.  An implementation that adhered
strictly to the standard with no extensions would be laughably useless.

>   If you add extensions, it's your duty to maintain the semantics of the
>   standard to which you purport to conform.  If you fail in this duty,
>   it is not the standard's fault.

Are you saying that MCL is not a conforming implementation?

>   Upgrade your brain to acquire the concept of �context�, please.

Please upgrade your aphorisms.  That one is *so* two-years-ago.

E.
From: Daniel Barlow
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <871xpc72d9.fsf@noetbook.telent.net>
·········@jpl.nasa.gov (Erann Gat) writes:

>> | ? (symbol-value-in-process '*x* *p*)

OK, so MCL has a means of getting the binding of a special that
another thread is currently using.  Is it reasonable to call this 
"a place associated with the symbol"?  What if I create a weak hash
table whose keys are symbols, and an accessor (my-new-place symbol)
which stores and retrieves the values in this hash?  Is that also now
a place associated with the symbol?

I dont know how this is implemented in MCL, but I think I remember
Gary saying that OpenMCL 0.14 uses deep binding, so the symbol-value
accessor is looking in a place which is not (in low-level
implementation terms) part of the symbol either.  So how is that
different from my weak hash table, except that symbol-value is part of
CL and my weak hash table isn't?

In SBCL (as in Corman Lisp, and I believe also in Scieneer) we
implement per-thread bindings with a field in the low-level symbol
primitive object that holds an index into a block of thread-local
storage.  There's no supported way to get a symbol's value in another
thread, but there's always the SAP-REF-32 function (allows the user to
read the value at any memory location) and MAKE-LISP-OBJ which can
interpret the tag bits of the value returned to turn it back into a
lisp object.  So if you know the internal layouts you could in
principle write an accessor to get the symbol's value in some other
thread - or if you add 4, you could get some other symbol's value
instead.  Is the symbol-value of NIL in thread 2 associated with T in
thread 1?

How many more increasingly silly examples do I need to produce to
illustrate the essential meaninglessness of this discussion?  The next 
one will involve RPC and use of the RANDOM function.



-dan
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0302040759240001@192.168.1.51>
In article <··············@noetbook.telent.net>, Daniel Barlow
<···@telent.net> wrote:

> ·········@jpl.nasa.gov (Erann Gat) writes:
> 
> >> | ? (symbol-value-in-process '*x* *p*)
> 
> OK, so MCL has a means of getting the binding of a special that
> another thread is currently using.  Is it reasonable to call this 
> "a place associated with the symbol"?

Of course.  Why would you doubt it?

>  What if I create a weak hash
> table whose keys are symbols, and an accessor (my-new-place symbol)
> which stores and retrieves the values in this hash?  Is that also now
> a place associated with the symbol?

Of course.  Why would you doubt it?

> I dont know how this is implemented in MCL, but I think I remember
> Gary saying that OpenMCL 0.14 uses deep binding, so the symbol-value
> accessor is looking in a place which is not (in low-level
> implementation terms) part of the symbol either.

So what?  What if global values are stored in a single global hash table? 
Then the places are not "part of" the symbol (whatever that means) but the
user would never know it.

> So how is that
> different from my weak hash table, except that symbol-value is part of
> CL and my weak hash table isn't?

That is the only difference.  And your point would be...?

> In SBCL (as in Corman Lisp, and I believe also in Scieneer) we
> implement per-thread bindings with a field in the low-level symbol
> primitive object that holds an index into a block of thread-local
> storage.  There's no supported way to get a symbol's value in another
> thread, but there's always the SAP-REF-32 function (allows the user to
> read the value at any memory location) and MAKE-LISP-OBJ which can
> interpret the tag bits of the value returned to turn it back into a
> lisp object.  So if you know the internal layouts you could in
> principle write an accessor to get the symbol's value in some other
> thread - or if you add 4, you could get some other symbol's value
> instead.  Is the symbol-value of NIL in thread 2 associated with T in
> thread 1?

MU.  Once you push through the last abstraction barrier and start dealing
with the raw bits, everything is associated with everything else -- or
nothing is associated with anything, or "association" is no longer a
meaningful concept -- take your pick.

> How many more increasingly silly examples do I need to produce to
> illustrate the essential meaninglessness of this discussion?  The next 
> one will involve RPC and use of the RANDOM function.

Heck, I would have conceded the essential meaninglessness of this
discussion right off the bat without all that rigamarole.  All you had to
do was ask.  Push hard enough on any metaphor and it will break.  At root
everything is a quantum wave function.  Nonetheless, metaphors and
abstractions are useful things, and so people can reasonably choose not to
lean too hard on them and just accept them for their utility.

There is a meaningful distinction to be made between those abstractions
that are provided in the standard, those abstractions that are provided as
vendor-implemented extensions, those that are provided by user code, and
even those that are provided by the raw bits (because bits are an
abstraction too).  Threads, by the way, are also an abstraction.  They are
an abstraction of the second sort, as is SYMBOL-VALUE-IN-FUNCTION.  These
things don't have any "essential meaning".  They are purely artificial
constructs.  But they are nonetheless useful.

E.
From: Erik Naggum
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <2004-034-338-KL2065E@naggum.no>
* Erann Gat
| Hogwash.  Bunkum.  Nonsense.  Bullsh*t.  Flim flam.  Horse hockey.
| Self-evidently untrue to anyone with half a brain.  Am I making myself
| clear?

  You are coming through more loud than clear, but your insanity is
  getting in the way of the argument, if any.

  You win, Erann, as you have already done in your own mind.

  I don't have the energy to explain things to the likes of you,
  anymore.

-- 
Erik Naggum | Oslo, Norway                                      2004-034

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0302040826490001@192.168.1.51>
In article <····················@naggum.no>, Erik Naggum <····@naggum.no> wrote:

>   I don't have the energy to explain things to the likes of you,
>   anymore.

What a lame excuse.  You are the most prolific and doggedly persistent
person I have ever known.  (These are good qualities by the way.)  To say
nothing of the fact that you made no attempt to explain anything, you just
posted on bald assertion, one which was easily shown to be false.  (You
are now falling back on your tired old strategy of using insults when
logic fails you.)

What you lack is the ability to seriously consider the possibility that
you might be wrong.  I can understand why.  If you seriously entertain the
possibility that you are wrong about one thing then you have to entertain
the possibility that you were wrong about other things, and then all of a
sudden all that abuse you've heaped on people over the years is no longer
justified and you have to come to grips with it.  You have to take
responsibility for your actions, and that scares the living daylights out
of you.  It's quite understandable.

Erik, trust me, it won't be so bad.  People are very forgiving.

E.
From: Pascal Costanza
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <bvmo92$t95$1@newsreader2.netcologne.de>
Erik Naggum wrote:

>   So, since the same symbol exists in different Common Lisp worlds on
>   different computers all across the Internet, it is �misleading� to
>   refer to a symbol's value cell as a unique place.  Right?
> 
>   There is no way in Common Lisp to refer to symbols in any but the
>   current thread.  All references to values of symbols will therefore be
>   those in the current thread.

You can "uncover" the previous binding of a symbol by leaving the 
dynamic environment that introduced the current binding. So it makes 
sense to say that a symbol has more than one value at the same time 
because previous bindings are not lost.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <jQHTb.207820$I06.2312583@attbi_s01>
Joe Marshall wrote:

> No.  A symbol is a small data structure, a variable is an abstract
> concept.
> 
> An identifier may refer to a `bound' variable, or it may be a `free'
> variable.  There are two rules for evaluating a bound variable:  If the
> variable is not `special', use the binding in the closest lexical
> context.  If the variable *is* `special', look in the `value cell' of
> the symbol with the same name as the variable.
> 
> There is a special evaluation rule for free variables:  always look in
> the `value cell' of the symbol with the same name as the variable.
> 
> So the value of a variable *may* be stored in the symbol of the same
> name, but it doesn't have to be.

Okay, this now makes sense.

> Yes, they are different.  A lexical binding is maintained by the
> interpreter or compiler in whatever way the interpreter or compiler
> feels is appropriate.  A special or free reference, however, is stored
> in the value cell of the symbol.

Okay. I get it.

> They differ in implementation as well.  When (+ foo 10) is at top
> level, FOO is a `free reference' and thus the value is looked up in
> the value cell of the symbol FOO.

Got it.

> 
> When (+ foo 10) is evaluated within the LET scope, however, it is a
> `lexical reference' and the value is kept wherever the compiler or
> interpreter puts such things.

Got it. So wherever the compiler or interpreter puts such things could be on
the stack, in a register, etc. There is no official data structure holding
this value.

> Close.  When the interpreter sees the reference to FOO, and it notices
> that FOO is *not* lexically bound, it is required to apply the `free
> reference' rule and look in the value cell of the symbol FOO.
> 
>> Specifically, I'm really struggling with the difference between symbol,
>> variable, binding, and lexical variable. I understand what an identifier
>> is.
> 
> I think you understand what a variable, binding, and lexical variable
> are, and I think you are trying to fit `symbol' into that picture.  A
> symbol is a little data structure with a name, property list, package,
> etc.  The `value cell' of a symbol is where the interpreter or
> compiler is required to store the top-level value or current dynamic
> value of a variable, and the `function cell' is where the interpreter
> or compiler is required to store the top-level function value, but
> otherwise the symbol is not used.

Yes. What I was missing was the differences of free references and the
special "free reference rule" that you describe above. I was thinking that
there was just some top-level environment and that lexical environments
were basically just scoped hierarchically, with some sort of "root"
environment being used for top-level. That's sort of the behavior, but with
the value slot of a symbol being used to hold the bindings at top-level,
right?

-- Dave
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <znc0bkuq.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

>
> Yes. What I was missing was the differences of free references and the
> special "free reference rule" that you describe above. I was thinking that
> there was just some top-level environment and that lexical environments
> were basically just scoped hierarchically, with some sort of "root"
> environment being used for top-level. That's sort of the behavior, but with
> the value slot of a symbol being used to hold the bindings at top-level,
> right?

Sounds like you got it.


-- 
~jrm
From: Harald Hanche-Olsen
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <pcooesio2ff.fsf@thoth.math.ntnu.no>
+ Dave Roberts <·····@re-move.droberts.com>:

| Matthew Danish wrote:
| 
| > (let ((a (lambda (x) x)))
| >   (funcall a 1))
| > 
| > And feel somewhat Scheme-y.
| 
| Yes, and this is one thing that confuses me. So what is happening in this
| case? By my probably incorrect notion of what's happening under the hood,
| the LET form is creating a new local symbol(?) named "a,"

No, actually the reader creates the symbol.  The program is defined
not in terms of the text, but in terms of the data structures (conses,
symbols, and a number in this case) which results from the above
textual representation being read.

| and then binding the value portion(?) of that symbol to the lamba
| expression object.

The LET creates a new lexical variable.  The name of that variable is
the symbol A, but no "value portion" of the symbol is affected by the
binding, unless the variable has been declared special (and even then,
the true story is a bit more complicated).  In fact, the compiler will
allocate a location for the variable and make sure all accesses to A
within the scope refer to that location.  There is no further
connection between the symbol and the value, except that the debugger
is informed so it can help you inspect the variable.

| Is that right? So what's a variable as opposed to a symbol/binding?

A variable in CL /is/ a binding.  More precisely, it is a binding in a
particular name space, the "variable" one.  A symbol is something
whose primary attribute is its identity.  It is the thing being
bound. 

| > CL also has a namespace for variables that are to be bound exclusively
| > to functions.  In the above example, the symbol A names a variable bound
| > to a function.  In the following example, the symbol A names a function
| > variable bound to a function:
| > 
| > (flet ((a (x) x))
| >   (a 1))
| 
| So is the best way to think about this as two different variables,
| one capable of holding functions and the other values, or is it
| better to think of a single named symbol ("A"), that has
| pointers/references, one to a value and the other to and object.

A bit like the latter, but the references aren't really part of the
symbol at all.  You may think of the name spaces as the abstract
objects that bind symbols to values.

| In other words, a symbol is implemented as a structure with these
| things along with a reference to a property list and all the other
| things that a symbol has.

No!  The global value and function bindings may be part of the symbol
object, and though this is not a requirement, it probably doesn't hurt
to think of them that way.  But lexical bindings are totally divorced
from their names at runtime, with the exception of information
available to the debugger, as I mentioned before.

| > (let ((a (lambda (x) x)))  ; ordinary variable binding declaration
| >   (flet ((a (x) x))  ; function variable binding declaration
| >     (foo a)  ; A names the ordinary variable
| >     (foo #'a)))  ; #'A names the function variable
| 
| So this brings up a good question: If these are implemented as the
| same symbol with two "slots" (not to be confused with CLOS slots),
| then it seems like this would cause problems.

Good observation.  That is why they are not implemented that way.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <QAgTb.156592$Rc4.1238201@attbi_s54>
Harald Hanche-Olsen wrote:

> The LET creates a new lexical variable.  The name of that variable is
> the symbol A, but no "value portion" of the symbol is affected by the
> binding, unless the variable has been declared special (and even then,
> the true story is a bit more complicated).  In fact, the compiler will
> allocate a location for the variable and make sure all accesses to A
> within the scope refer to that location.  There is no further
> connection between the symbol and the value, except that the debugger
> is informed so it can help you inspect the variable.

Okay, I think I get that. The issue that is now causing me trouble is the
different handlig of top-level versus lexical scopes. Can you give me
something on the different handling of a name (say "foo") when it is in a
lexical scope versus top-level.

> 
> | Is that right? So what's a variable as opposed to a symbol/binding?
> 
> A variable in CL /is/ a binding.  More precisely, it is a binding in a
> particular name space, the "variable" one.  A symbol is something
> whose primary attribute is its identity.  It is the thing being
> bound.

Okay, so that makes sense now, I think.
 
> | So is the best way to think about this as two different variables,
> | one capable of holding functions and the other values, or is it
> | better to think of a single named symbol ("A"), that has
> | pointers/references, one to a value and the other to and object.
> 
> A bit like the latter, but the references aren't really part of the
> symbol at all.  You may think of the name spaces as the abstract
> objects that bind symbols to values.

So now I'm getting confused again.

> | In other words, a symbol is implemented as a structure with these
> | things along with a reference to a property list and all the other
> | things that a symbol has.
> 
> No!  The global value and function bindings may be part of the symbol
> object, and though this is not a requirement, it probably doesn't hurt
> to think of them that way.  But lexical bindings are totally divorced
> from their names at runtime, with the exception of information
> available to the debugger, as I mentioned before.

Actually, I think it is hurting me to think of them that way. It sounds like
the programming model is that symbols are just interned strings. That's it.
Just a string of characters, with each one guaranteed to be unique such
that you can use a pointer to it rather than repeat the characters
everywhere. Then it sounds like there are two namespaces in the system, one
for values and the other for functions. These spaces seem logically
separate (two totally different sets of bindings). Then it seems like an
environment stores a set of bindings for values, and a set of bindings for
functions, again totally separate.

Now, the thing that I'm still struggling with is that it seems like symbols
are not simple interned strings in at least some of the literature I have
read. For instance, the Gabriel/Pitman article that I'm reading says in its
terminology definitions: "A symbol is a Lisp data structure that has a
value cell, a property list, a function cell (in Common Lisp), and so on."

> | > (let ((a (lambda (x) x)))  ; ordinary variable binding declaration
> | >   (flet ((a (x) x))  ; function variable binding declaration
> | >     (foo a)  ; A names the ordinary variable
> | >     (foo #'a)))  ; #'A names the function variable
> | 
> | So this brings up a good question: If these are implemented as the
> | same symbol with two "slots" (not to be confused with CLOS slots),
> | then it seems like this would cause problems.
> 
> Good observation.  That is why they are not implemented that way.

Okay, so now I'm struggling with the Gabriel/Pitman quote above.

-- Dave
From: Gareth McCaughan
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87ad42b6rg.fsf@g.mccaughan.ntlworld.com>
Dave Roberts <·····@re-move.droberts.com> writes:

> That said, I don't think I understand the above paragraph. Part of it is
> that I'm struggling with the various CL terminology for "cell," "object,"
> "symbol," "variable," and "binding."

I'm not sure whether other people's replies have already got
all this completely sorted out for you, but ...

A "variable" is purely a compile-time thing. At run time,
there may not *be* anything that quite corresponds to
a single variable. (Some variables may disappear entirely
in compilation, as a result of optimization. Some may
have their contents put in memory, others in registers,
others in some combination of the two. Some may get
transformed so that instead of anything storing "i",
"4*i" gets put in a register so it can be used more
efficiently as an array index. And so on.

A "symbol" is *not* a purely compile-time thing; symbols
continue to exist at run time too. A symbol is a real
honest-to-goodness object. It has a name, a value, a
value-as-a-function, a property list, and some other
stuff. You can think of it as a structure with fields
called "name", "value" and so on, if you must. (The
value and function-value aren't necessarily set;
usually at most one is set and often neither is.)

Symbols appear in Lisp source code, where they may
(among other functions) represent variables. But a
variable called FOO does *not* necessarily have anything
to do with the symbol called FOO, apart from the fact
that the latter is used as the name for the former.
So, for instance, if you write

    (let ((foo 123))
      (do-something-with foo))

then the chances are that this will simply be transformed
into the equivalent of

    (do-something-with 123)

And if you write

    (loop for foo from 0 to 100 do
      (do-something-with foo))

then the chances are that the thing that counts from 0 to 100
will live in a register and have nothing to do with the symbol
FOO at run time.

However, there are some circumstances in which the variable
and the symbol coincide. Specifically, it is possible to
declare that a symbol represents a "special variable". That
means that any variable named by that symbol gets treated
differently. This has two possibly interesting consequences.
The first is that the variable is "dynamically scoped"; I
shan't explain what that means right now, but it's quite
interesting. The second, closely related to the first, is
that now the value of the variable is always the same as
the value of the symbol.

I think those are the key points. But I should say a little
about the other words you mentioned.

A "binding" is an association between a name and a value.
Every symbol that has a value constitutes a binding, for
instance; these bindings exist at run time. And every
time you write LET or LAMBDA or any of a whole lot of
other such things, you establish some bindings at compile
time. Unless the variables they bind have been declared
special, those bindings *only* exist at compile time.
(Well, some record of them may remain for the sake of
the debugger.)

There's more than one meaning for "cell". For instance,
the objects of which lists are composed are called "cons
cells". A symbol has a "value cell" and a "function cell";
these are probably the meanings you have in mind, and in
that context "cell" means roughly the same as "field" or
"slot" (i.e., one value-holding thing in a structure).
The general meaning is in fact something like "value-holding
thing".

An "object" is much the same as a "value". Objects are the
things one computes with. An integer, a string, a character,
a CLOS instance, a symbol, a closure, all are objects. You
could say, with apologies to W V O Quine, "To be an object
is to be potentially the value of a variable"; that's true
and possibly helpful, but it feels rather the wrong way around.
(In some languages "object" means "instance of a class" and
"class" means "user-defined data structure that fits into
an inheritance hierarchy". Not in Common Lisp.)

-- 
Gareth McCaughan
.sig under construc
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <XylTb.160314$sv6.881667@attbi_s52>
Gareth McCaughan wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> That said, I don't think I understand the above paragraph. Part of it is
>> that I'm struggling with the various CL terminology for "cell," "object,"
>> "symbol," "variable," and "binding."
> 
> I'm not sure whether other people's replies have already got
> all this completely sorted out for you, but ...

Nope, they haven't, and this posting was hugely helpful for me. Thanks.

> A "variable" is purely a compile-time thing. At run time,
> there may not *be* anything that quite corresponds to
> a single variable. (Some variables may disappear entirely
> in compilation, as a result of optimization. Some may
> have their contents put in memory, others in registers,
> others in some combination of the two. Some may get
> transformed so that instead of anything storing "i",
> "4*i" gets put in a register so it can be used more
> efficiently as an array index. And so on.

Okay, I understand that things may be optimized away. This is no different
than any other programming language. The question is, assuming an
interpreter or very naive compiler that keeps all variables around, how is
a variable structured? I'm looking for a quickie definition like you have
for symbol below. I think this is part of my problem. That is, how does a
variable named "foo" relate to a symbol named "foo," and in particular to
the value of symbol "foo?"

> A "symbol" is *not* a purely compile-time thing; symbols
> continue to exist at run time too. A symbol is a real
> honest-to-goodness object. It has a name, a value, a
> value-as-a-function, a property list, and some other
> stuff. You can think of it as a structure with fields
> called "name", "value" and so on, if you must. (The
> value and function-value aren't necessarily set;
> usually at most one is set and often neither is.)

Okay, so a symbol really is more than just an interned string name. It
really does have other properties. So, following up on the question right
above, when I say:

(let ((foo 1))
        (setq foo 10))

1. What is the relationship between the variable I have created in the LET
form and the symbol named FOO that is created by the reader when this code
is consumed?

2. When I say (setq foo 10), am I setting the value slot of the symbol?

3. What if I do (setq foo 10) at top-level?

I think that these three questions here represent most of my confusion. I
think I understand lexical variables pretty well. I'm not sure I understand
the relationship between them and symbols, however.

I just read Erann Gat's "Idiot's Guide to Special Variables and Lexical
Closures," and that helped quite a bit. I still feel like I don't quite
understand the "rules" for how identifiers are treated differently in
top-level versus lexical scopes, however.

> Symbols appear in Lisp source code, where they may
> (among other functions) represent variables. But a
> variable called FOO does *not* necessarily have anything
> to do with the symbol called FOO, apart from the fact
> that the latter is used as the name for the former.
> So, for instance, if you write
> 
>     (let ((foo 123))
>       (do-something-with foo))
> 
> then the chances are that this will simply be transformed
> into the equivalent of
> 
>     (do-something-with 123)
> 
> And if you write
> 
>     (loop for foo from 0 to 100 do
>       (do-something-with foo))
> 
> then the chances are that the thing that counts from 0 to 100
> will live in a register and have nothing to do with the symbol
> FOO at run time.

So this all makes sense. This is what I would expect from just about any
other language. It basically acts like a local variable in all my other
experience. Again, it's the difference between that and a variable at
top-level that are confusing me.

> However, there are some circumstances in which the variable
> and the symbol coincide. Specifically, it is possible to
> declare that a symbol represents a "special variable". That
> means that any variable named by that symbol gets treated
> differently. This has two possibly interesting consequences.
> The first is that the variable is "dynamically scoped"; I
> shan't explain what that means right now, but it's quite
> interesting. The second, closely related to the first, is
> that now the value of the variable is always the same as
> the value of the symbol.

Erann Gat's paper explains this, but I'm still not quite sure I understand
it. I thought I did when I read the paper, but after playing around with
SBCL for a bit, the behavior isn't consistent with what I thought the
explanation was.

For instance, why does this happen the way it does:
* (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special
 
BAR
* (setq bar 100)
 
100
* (let ((bar 5000))
bar)
 
5000
* bar ;;; <== why didn't the LET form set this to 5000 if bar is a special
var?
 
100  
* (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
(setq bar 6000) ;; shouldn't this at least set bar to 6000?
bar)
 
6000   <== Looks like the local gets set instead...
* bar  
 
100    <== ...but not the top-level symbol
*

> I think those are the key points. But I should say a little
> about the other words you mentioned.
> 
> A "binding" is an association between a name and a value.
> Every symbol that has a value constitutes a binding, for
> instance; these bindings exist at run time. And every
> time you write LET or LAMBDA or any of a whole lot of
> other such things, you establish some bindings at compile
> time. Unless the variables they bind have been declared
> special, those bindings *only* exist at compile time.
> (Well, some record of them may remain for the sake of
> the debugger.)

So this is causing me confusion. It seems like a variable is a binding. I
mean, that's really what it does, right? It has a name and a storage
location, right? Now, so does a symbol, but for whatever reason, variables
and symbols aren't the same thing, right? But a variable references a
symbol for its name, right?

> There's more than one meaning for "cell". For instance,
> the objects of which lists are composed are called "cons
> cells". A symbol has a "value cell" and a "function cell";
> these are probably the meanings you have in mind, and in
> that context "cell" means roughly the same as "field" or
> "slot" (i.e., one value-holding thing in a structure).
> The general meaning is in fact something like "value-holding
> thing".

Okay, got it. I was trying to determine if that meant a formal cons cell or
not.

> An "object" is much the same as a "value". Objects are the
> things one computes with. An integer, a string, a character,
> a CLOS instance, a symbol, a closure, all are objects. You
> could say, with apologies to W V O Quine, "To be an object
> is to be potentially the value of a variable"; that's true
> and possibly helpful, but it feels rather the wrong way around.
> (In some languages "object" means "instance of a class" and
> "class" means "user-defined data structure that fits into
> an inheritance hierarchy". Not in Common Lisp.)

Yes. I think I get this.

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0102042225290001@192.168.1.51>
In article <·······················@attbi_s52>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> For instance, why does this happen the way it does:
> * (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special
>  
> BAR
> * (setq bar 100)
>  
> 100
> * (let ((bar 5000))
> bar)
>  
> 5000
> * bar ;;; <== why didn't the LET form set this to 5000 if bar is a special
> var?

It did, but only inside the (dynamic) scope of the let form.

>  
> 100  
> * (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
> (setq bar 6000) ;; shouldn't this at least set bar to 6000?
> bar)

It does.  It changes the value of the visible (dynamic) binding of bar.

>  
> 6000   <== Looks like the local gets set instead...
> * bar  
>  
> 100    <== ...but not the top-level symbol
> *

Try this:

(defun print-bar () (print bar))

(let ( (bar 'foo) )
  (print-bar)
  (setq bar 'baz)
  (print-bar))

Does that help?


> > A "binding" is an association between a name and a value.
> > Every symbol that has a value constitutes a binding, for
> > instance; these bindings exist at run time. And every
> > time you write LET or LAMBDA or any of a whole lot of
> > other such things, you establish some bindings at compile
> > time. Unless the variables they bind have been declared
> > special, those bindings *only* exist at compile time.
> > (Well, some record of them may remain for the sake of
> > the debugger.)
> 
> So this is causing me confusion. It seems like a variable is a binding. I
> mean, that's really what it does, right?

Right.

> It has a name and a storage location, right?

Yep.

> Now, so does a symbol

No.  People sometimes talk about symbols "having a value slot" but this is
misleading (and flat-out wrong in multi-threaded environments).  The best
place to get the authoritative scoop about this sort of thing is the
hyperspec.

> but for whatever reason, variables
> and symbols aren't the same thing, right?

That's right.  Symbols are the names of variables.  Symbols are not
themselves variables.

> But a variable references a symbol for its name, right?

That's odd phraseology but I think the idea behind it is correct.

E.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <EDHTb.214433$na.352757@attbi_s04>
Erann Gat wrote:

> Try this:
> 
> (defun print-bar () (print bar))
> 
> (let ( (bar 'foo) )
>   (print-bar)
>   (setq bar 'baz)
>   (print-bar))
> 
> Does that help?

I think so. So let me try to explain it and then you can correct me:

1. So I first execute a DEFVAR form that marks BAR as special. Bar is a
top-level symbol.

2. When I execute the LET form, LET determines (at run time or compile
time?) that BAR is special. The LET form saves the old value of the BAR
symbol value slot and sets the slot to 'FOO.

3. The PRINT-BAR function gets called. When it goes to print the value of
BAR, it determines that BAR is a free variable, so it retrieves the value
slot of the BAR symbol (which is now 'FOO).

4. When the SETQ form executes, it also determines that BAR is special and
therefore sets the value slot of the BAR symbol to 'BAZ.

5. When PRINT-BAR gets called again, it once again retrieves the value for
BAR from the value slot of the BAR symbol.

6. When the LET form goes out of scope, it returns the value slot of the BAR
symbol back to its previous value before the LET form was entered.


Also, I tried a similar example in SBCL where I had not executed a DEFVAR
previously, just a top-level SETQ, for a different name. The same value
gets printed out each time. I guess this means that SETQ creates a
top-level variable that is not special. Is that right? Therefore, the LET
form just shadows the top-level form without settings its value, and the
PRINT-BAR routine retrieves the top-level value.

> No.  People sometimes talk about symbols "having a value slot" but this is
> misleading (and flat-out wrong in multi-threaded environments).  The best
> place to get the authoritative scoop about this sort of thing is the
> hyperspec.

Hmmmm.... So the Gabriel and Pitman paper defines symbol as:
"A symbol is a Lisp data structure that has a value cell, a property list, a
function cell (in Common Lisp), and so on."

Is this not right?

> 
>> but for whatever reason, variables
>> and symbols aren't the same thing, right?
> 
> That's right.  Symbols are the names of variables.  Symbols are not
> themselves variables.

Okay, so if that's true, when I execute a SETQ or DEFVAR form at top-level,
what is happening?

>> But a variable references a symbol for its name, right?
> 
> That's odd phraseology but I think the idea behind it is correct.

Maybe "a variable binds a name represent by a symbol to a storage location"
??

Does that work better?

-- Dave
From: Erann Gat
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <gNOSPAMat-0302040848320001@192.168.1.51>
In article <······················@attbi_s04>, Dave Roberts
<·····@re-move.droberts.com> wrote:

> Erann Gat wrote:
> 
> > Try this:
> > 
> > (defun print-bar () (print bar))
> > 
> > (let ( (bar 'foo) )
> >   (print-bar)
> >   (setq bar 'baz)
> >   (print-bar))
> > 
> > Does that help?
> 
> I think so. So let me try to explain it and then you can correct me:
> 
> 1. So I first execute a DEFVAR form that marks BAR as special. Bar is a
> top-level symbol.

There is no such thing as a top-level symbol.


> 2. When I execute the LET form, LET determines (at run time or compile
> time?)

That is implementation-dependent, but it's invariably done at compile time
(if you are compiling your code).

> that BAR is special. The LET form saves the old value of the BAR
> symbol value slot and sets the slot to 'FOO.

That model works only for single-threaded code.  It fails for
multi-threaded code.  It really is best for long-term understanding to
think about it as creating a new binding with dynamic scope.

> 3. The PRINT-BAR function gets called. When it goes to print the value of
> BAR, it determines that BAR is a free variable, so it retrieves the value
> slot of the BAR symbol (which is now 'FOO).
>
> 4. When the SETQ form executes, it also determines that BAR is special and
> therefore sets the value slot of the BAR symbol to 'BAZ.
> 
> 5. When PRINT-BAR gets called again, it once again retrieves the value for
> BAR from the value slot of the BAR symbol.

Close enough.

> 6. When the LET form goes out of scope, it returns the value slot of the BAR
> symbol back to its previous value before the LET form was entered.

Better to think of it as: you exit the dynamic scope of the binding that
the LET created, and so that binding disappears.

> Also, I tried a similar example in SBCL where I had not executed a DEFVAR
> previously, just a top-level SETQ, for a different name. The same value
> gets printed out each time. I guess this means that SETQ creates a
> top-level variable that is not special. Is that right?

Right.  Strictly speaking doing a top-level setq without a corresponding
defvar has undefined consequences.  CMUCL (from which SBCL was derived
IIRC) "helpfully" did a defvar for you under those circumstances, but
enough people found this behavior annoying that it was changed.

> Therefore, the LET
> form just shadows the top-level form without settings its value, and the
> PRINT-BAR routine retrieves the top-level value.

No, the LET creates a lexical binding for BAR.  The scope of this binding
does not include the PRINT-BAR function, so PRINT-BAR can only access the
top-level binding.

The confusion caused by this state of affairs is precisely the reason why
a top-level setq without a defvar has undefined behavior.


> > No.  People sometimes talk about symbols "having a value slot" but this is
> > misleading (and flat-out wrong in multi-threaded environments).  The best
> > place to get the authoritative scoop about this sort of thing is the
> > hyperspec.
> 
> Hmmmm.... So the Gabriel and Pitman paper defines symbol as:
> "A symbol is a Lisp data structure that has a value cell, a property list, a
> function cell (in Common Lisp), and so on."
> 
> Is this not right?

It's a reasonable approximation to the truth which tacitly assumes a
single thread.

> >> but for whatever reason, variables
> >> and symbols aren't the same thing, right?
> > 
> > That's right.  Symbols are the names of variables.  Symbols are not
> > themselves variables.
> 
> Okay, so if that's true, when I execute a SETQ or DEFVAR form at top-level,
> what is happening?

The answer to those two questions are different and long.  The best I can
do is point you back to the Idiot's Guide, where this is explained at
length.

> 
> >> But a variable references a symbol for its name, right?
> > 
> > That's odd phraseology but I think the idea behind it is correct.
> 
> Maybe "a variable binds a name represent by a symbol to a storage location"
> ??
> 
> Does that work better?

Very nearly.  A variable binds a name to a storage location.  But the name
is not *represented* by a symbol, the name *is* a symbol.  There is no
fundamental reason why a name must be a symbol, it is simply a constraint
of the design of Common Lisp that the names of variables must be symbols. 
One can design Lisp dialects where the names of variables could be other
things.

Note that there are things in Common Lisp that have names that do not have
to be symbols.  For example, functions can have names that are lists
beginning with the symbol SETF.  Symbols *are* names (of variables) and
they also *have* names (which are strings).  It gets very confusing.

E.
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <vfmobkme.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> 2. When I execute the LET form, LET determines (at run time or compile
> time?) that BAR is special. The LET form saves the old value of the BAR
> symbol value slot and sets the slot to 'FOO.

At compile time.

> Also, I tried a similar example in SBCL where I had not executed a DEFVAR
> previously, just a top-level SETQ, for a different name. The same value
> gets printed out each time. I guess this means that SETQ creates a
> top-level variable that is not special. Is that right? Therefore, the LET
> form just shadows the top-level form without settings its value, and the
> PRINT-BAR routine retrieves the top-level value.

This *may* be the behavior, but at least one Lisp implementation
`helpfully' interprets a top-level SETQ as meaning that you want the
variable to be special.

-- 
~jrm
From: Brian Downing
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <1CJTb.82389$U%5.446419@attbi_s03>
In article <······················@attbi_s04>,
Dave Roberts  <·····@re-move.droberts.com> wrote:
> > That's right.  Symbols are the names of variables.  Symbols are not
> > themselves variables.
> 
> Okay, so if that's true, when I execute a SETQ or DEFVAR form at top-level,
> what is happening?

I'll try to answer what happens in those cases, and why symbols are not
variables.

First, some definitions from the hyperspec:

    binding n. an association between a name and that which the name
    denotes.

    symbol n. an object of type symbol.

    value cell n. Trad. (of a symbol) The place which holds the value,
    if any, of the dynamic variable named by that symbol, and which is
    accessed by symbol-value.

    variable n. a binding in the ``variable'' namespace.

You mentioned you liked getting down and dirty with the implementation,
right?  Well, here goes.  Do you know about MACROEXPAND?  You should.
It will expand macros (like DEFVAR, incidentally) so you can see what
code they will turn into.  This is exactly what will happen when you
run DEFVAR.

CL-USER> (macroexpand '(defvar *name* 'value))
(PROGN
 (DECLAIM (SPECIAL *NAME*))
 (UNLESS (BOUNDP '*NAME*) 
   (SET '*NAME* 'VALUE))
 '*NAME*)

So, first this makes any bindings named by *NAME* dynamic.  Then, unless
there is already a dynamic binding for the name *NAME*, it runs
(SET '*NAME* 'VALUE).

SET is a very low level function, and should rarely if ever be called
from normal code.  The definition of SET is:

    (set symbol value) => value

    set changes the contents of the value cell of symbol to the given
    value.

So we're setting the value cell named by the symbol *NAME* to the value
VALUE.

So a symbol names a value cell, which now has a value.  But the symbol
is NOT a 'variable' as the specification defines a variable.  This can 
be determined by the four definitions above.

The behavior from the top level for (setq *name* 'value) will be the
same as that of (SET '*NAME* 'VALUE) described above, ONLY if the symbol
*name* has already been declared special.  Otherwise, the behavior is
undefined.

Unless I'm wrong about all of this crap, in which case I apologize in
advance.  :)

Really, I think the best thing you could do is just sit down with a CL
implementation and play with it for a long time.  It's the best way to
figure out what's up.  Just remember to always DEFVAR or DEVPARAMETER
any variable you want to use globally or with dynamic scope, and you
shouldn't wander into any undefinied behavior.

-bcd
--
*** Brian Downing <bdowning at lavos dot net> 
From: Brian Downing
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <5OJTb.208204$I06.2314393@attbi_s01>
In article <······················@attbi_s04>,
Dave Roberts  <·····@re-move.droberts.com> wrote:
> > That's right.  Symbols are the names of variables.  Symbols are not
> > themselves variables.
> 
> Okay, so if that's true, when I execute a SETQ or DEFVAR form at top-level,
> what is happening?

I'll try to answer what happens in those cases, and why symbols are not
variables.

First, some definitions from the hyperspec:

    binding n. an association between a name and that which the name
    denotes.

    symbol n. an object of type symbol.

    value cell n. Trad. (of a symbol) The place which holds the value,
    if any, of the dynamic variable named by that symbol, and which is
    accessed by symbol-value.

    variable n. a binding in the ``variable'' namespace.

You mentioned you liked getting down and dirty with the implementation,
right?  Well, here goes.  Do you know about MACROEXPAND?  You should.
It will expand macros (like DEFVAR, incidentally) so you can see what
code they will turn into.  This is exactly what will happen when you
run DEFVAR.

CL-USER> (macroexpand '(defvar *name* 'value))
(PROGN
 (DECLAIM (SPECIAL *NAME*))
 (UNLESS (BOUNDP '*NAME*) 
   (SET '*NAME* 'VALUE))
 '*NAME*)

So, first this makes any bindings named by *NAME* dynamic.  Then, unless
there is already a dynamic binding for the name *NAME*, it runs
(SET '*NAME* 'VALUE).

SET is a very low level function, and should rarely if ever be called
from normal code.  The definition of SET is:

    (set symbol value) => value

    set changes the contents of the value cell of symbol to the given
    value.

So we're setting the value cell named by the symbol *NAME* to the value
VALUE.

So a symbol names a value cell, which now has a value.  But the symbol
is NOT a 'variable' as the specification defines a variable.  This can 
be determined by the four definitions above.

The behavior from the top level for (setq *name* 'value) will be the
same as that of (SET '*NAME* 'VALUE) described above, ONLY if the symbol
*name* has already been declared special.  Otherwise, the behavior is
undefined.

Unless I'm wrong about all of this crap, in which case I apologize in
advance.  :)

Really, I think the best thing you could do is just sit down with a CL
implementation and play with it for a long time.  It's the best way to
figure out what's up.  Just remember to always DEFVAR or DEFPARAMETER
any variable you want to use globally or with dynamic scope, and you
shouldn't wander into any undefined behavior.

-bcd
--
*** Brian Downing <bdowning at lavos dot net> 
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <vfmp8pw3.fsf@ccs.neu.edu>
Dave Roberts <·····@re-move.droberts.com> writes:

> Okay, so a symbol really is more than just an interned string name. It
> really does have other properties. So, following up on the question right
> above, when I say:
>
> (let ((foo 1))
>         (setq foo 10))
>
> 1. What is the relationship between the variable I have created in the LET
> form and the symbol named FOO that is created by the reader when this code
> is consumed?

None whatsoever.

> 2. When I say (setq foo 10), am I setting the value slot of the symbol?

If FOO is lexically bound, the lexical value is modified.  The value
slot of the symbol has nothing to do with it.

> 3. What if I do (setq foo 10) at top-level?

Since FOO is a free-reference, the value cell of the symbol FOO will
be modified.

> Erann Gat's paper explains this, but I'm still not quite sure I understand
> it. I thought I did when I read the paper, but after playing around with
> SBCL for a bit, the behavior isn't consistent with what I thought the
> explanation was.
>
> For instance, why does this happen the way it does:
> * (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special

Yes.  BAR is now considered a special variable everywhere.
This means that *all* binding is done through the value cell of the
symbol BAR.

> * (setq bar 100)
>  
> 100

BAR is a special variable, the symbol value cell is modified.

> * (let ((bar 5000))
> bar)
>  
> 5000

BAR is a special variable, the symbol value cell is temporarily
modified during the evaluation of the LET form.

> * bar ;;; <== why didn't the LET form set this to 5000 if bar is a special
> var?
>  
> 100  

When the LET form exited, BAR was restored to its old value.

> * (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
> (setq bar 6000) ;; shouldn't this at least set bar to 6000?
> bar)
>  
> 6000   <== Looks like the local gets set instead...

No, the LET form saves the old contents of the value cell of the
symbol BAR and temporarily modifies it to be 5000.  The SETQ form
modifies the value cell to hold 6000.  The evaluation of BAR looks in
the value cell to find the 6000.  The LET form exits and restores the
old value.

> So this is causing me confusion.  It seems like a variable is a
> binding. 

A binding is how a variable gets a value.

> I mean, that's really what it does, right? It has a name and a storage
> location, right?  Now, so does a symbol, but for whatever reason, variables
> and symbols aren't the same thing, right?  But a variable references a
> symbol for its name, right?

If the variable is a special variable, the value cell of the symbol
holds the current value of the variable.  If the variable is lexically
bound, the symbol is irrelevant.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ScHTb.214375$na.351165@attbi_s04>
Joe Marshall wrote:

>> 2. When I say (setq foo 10), am I setting the value slot of the symbol?
> 
> If FOO is lexically bound, the lexical value is modified.  The value
> slot of the symbol has nothing to do with it.

So this is what is screwing me up. ;-) I guess I don't understand why a free
variable is handled differently than a lexical variable. Put another way,
way is a top-level "variable" handled as a slot associated with the symbol
rather than, I guess, a global, top-level lexical environment or something?

>> 3. What if I do (setq foo 10) at top-level?
> 
> Since FOO is a free-reference, the value cell of the symbol FOO will
> be modified.

So why this and not a top-level lexical environment? I guess I'm now
confused about why this would be implemented that way. At the risk of
opening up another can of worms, what is the advantage of doing this rather
than a top-level lexical environment??

>> Erann Gat's paper explains this, but I'm still not quite sure I
>> understand it. I thought I did when I read the paper, but after playing
>> around with SBCL for a bit, the behavior isn't consistent with what I
>> thought the explanation was.
>>
>> For instance, why does this happen the way it does:
>> * (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special
> 
> Yes.  BAR is now considered a special variable everywhere.
> This means that *all* binding is done through the value cell of the
> symbol BAR.

Okay, but the examples are then confusing...

>> * (setq bar 100)
>>  
>> 100
> 
> BAR is a special variable, the symbol value cell is modified.
> 
>> * (let ((bar 5000))
>> bar)
>>  
>> 5000
> 
> BAR is a special variable, the symbol value cell is temporarily
> modified during the evaluation of the LET form.
> 
>> * bar ;;; <== why didn't the LET form set this to 5000 if bar is a
>> special var?
>>  
>> 100
> 
> When the LET form exited, BAR was restored to its old value.

Okay, okay. It's now sinking in. So this is what allows me to have dynamic
bindings. Because a free variable in another function will refer back to
the value slot of the symbol, having the LET alter a special variable in
this way allows me to then make a call to another function where BAR is
free and have it see the new value that I set in the local LET.

>> * (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
>> (setq bar 6000) ;; shouldn't this at least set bar to 6000?
>> bar)
>>  
>> 6000   <== Looks like the local gets set instead...
> 
> No, the LET form saves the old contents of the value cell of the
> symbol BAR and temporarily modifies it to be 5000.  The SETQ form
> modifies the value cell to hold 6000.  The evaluation of BAR looks in
> the value cell to find the 6000.  The LET form exits and restores the
> old value.

Okay, I'm getting it.

>> So this is causing me confusion.  It seems like a variable is a
>> binding.
> 
> A binding is how a variable gets a value.
> 
>> I mean, that's really what it does, right? It has a name and a storage
>> location, right?  Now, so does a symbol, but for whatever reason,
>> variables
>> and symbols aren't the same thing, right?  But a variable references a
>> symbol for its name, right?
> 
> If the variable is a special variable, the value cell of the symbol
> holds the current value of the variable.  If the variable is lexically
> bound, the symbol is irrelevant.

If the variable is lexically bound, the symbol is the name of the variable,
right? I mean, it isn't irrelevant, at least in an interpreter. Yes, in a
compiler, it could optimize all that away, but at least when it's
interpreted, the variable references a symbol for its name, right?

-- Dave
From: Joe Marshall
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <r7xcbkf3.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Joe Marshall wrote:
>
>>> 2. When I say (setq foo 10), am I setting the value slot of the symbol?
>> 
>> If FOO is lexically bound, the lexical value is modified.  The value
>> slot of the symbol has nothing to do with it.
>
> So this is what is screwing me up. ;-) I guess I don't understand why a free
> variable is handled differently than a lexical variable. Put another way,
> way is a top-level "variable" handled as a slot associated with the symbol
> rather than, I guess, a global, top-level lexical environment or something?

You got it.

>>> 3. What if I do (setq foo 10) at top-level?
>> 
>> Since FOO is a free-reference, the value cell of the symbol FOO will
>> be modified.
>
> So why this and not a top-level lexical environment?  I guess I'm now
> confused about why this would be implemented that way. At the risk of
> opening up another can of worms, what is the advantage of doing this rather
> than a top-level lexical environment??

History.  Early lisp implementations were dynamically scoped.

> If the variable is lexically bound, the symbol is the name of the variable,
> right? I mean, it isn't irrelevant, at least in an interpreter. Yes, in a
> compiler, it could optimize all that away, but at least when it's
> interpreted, the variable references a symbol for its name, right?

Yes, the symbol is used only because it is a name for the variable.
The other parts of the symbol are not used.

-- 
~jrm
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <7rQTb.216554$na.354232@attbi_s04>
Joe Marshall wrote:

>> So why this and not a top-level lexical environment?  I guess I'm now
>> confused about why this would be implemented that way. At the risk of
>> opening up another can of worms, what is the advantage of doing this
>> rather than a top-level lexical environment??
> 
> History.  Early lisp implementations were dynamically scoped.

Okay, got it.

>> If the variable is lexically bound, the symbol is the name of the
>> variable, right? I mean, it isn't irrelevant, at least in an interpreter.
>> Yes, in a compiler, it could optimize all that away, but at least when
>> it's interpreted, the variable references a symbol for its name, right?
> 
> Yes, the symbol is used only because it is a name for the variable.
> The other parts of the symbol are not used.

Right. Now I understand.
From: Alain Picard
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87broiaqxy.fsf@memetrics.com>
Dave Roberts <·····@re-move.droberts.com> writes:

Another attempt at elucidation:

> Okay, so a symbol really is more than just an interned string name. It
> really does have other properties. So, following up on the question right
> above, when I say:
>
> (let ((foo 1))
>         (setq foo 10))
>
> 1. What is the relationship between the variable I have created in the LET
> form and the symbol named FOO that is created by the reader when this code
> is consumed?

Don't think of it as "creating a variable".  You have "established
a (lexical) binding".  A binding is an association between the
symbol and the value it can hold.

> 2. When I say (setq foo 10), am I setting the value slot of the symbol?

You are modifying the binding currently in effect in such a way
that further accesses to the value of FOO will return the value 10.

> 3. What if I do (setq foo 10) at top-level?

Unless FOO has been globally declared special previously
(in which case, in 1, the binding was _not_, in fact, lexical),
this is undefined.  Pretend that it will make your computer
explode, taking all your backups with it in the deflagration.

> I think that these three questions here represent most of my confusion. I
> think I understand lexical variables pretty well. I'm not sure I understand
> the relationship between them and symbols, however.

The Hyperspec defines a "variable" as a binding in the ``variable'' namespace.
Substitute "variable" for binding, and you more clearly see that
all we're talking about are _associations_ of values.

BTW, this is explained to extreme (some might say tedious) length
in "Lisp: by Winston and Horne".
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <wjHTb.212028$xy6.1099728@attbi_s02>
Alain Picard wrote:

>> 1. What is the relationship between the variable I have created in the
>> LET form and the symbol named FOO that is created by the reader when this
>> code is consumed?
> 
> Don't think of it as "creating a variable".  You have "established
> a (lexical) binding".  A binding is an association between the
> symbol and the value it can hold.

Hmmmm... so I feel like I'm running circles in the terminology. Okay, that's
how I used to think of things. A binding is basically an association
between a name (the symbol) and a storage location that holds a value. No?

If that's so, then what's a "variable?"

And it sounds like from Joe Marshall's post that a binding (or variable?)
has nothing to do with a symbol. At least it appears to have nothing to do
with the value slot of a symbol.

>> 2. When I say (setq foo 10), am I setting the value slot of the symbol?
> 
> You are modifying the binding currently in effect in such a way
> that further accesses to the value of FOO will return the value 10.

But I'm not modifying the value slot of the symbol, right?

>> 3. What if I do (setq foo 10) at top-level?
> 
> Unless FOO has been globally declared special previously
> (in which case, in 1, the binding was _not_, in fact, lexical),
> this is undefined.  Pretend that it will make your computer
> explode, taking all your backups with it in the deflagration.

Okay, from Erann Gat's paper, it said that this is technically undefined,
but that many CLs just execute an implicit DEFVAR for you. I do notice that
SBCL spits out a warning at me when I do this before using DEFVAR.

>> I think that these three questions here represent most of my confusion. I
>> think I understand lexical variables pretty well. I'm not sure I
>> understand the relationship between them and symbols, however.
> 
> The Hyperspec defines a "variable" as a binding in the ``variable''
> namespace. Substitute "variable" for binding, and you more clearly see
> that all we're talking about are _associations_ of values.

Ah ha! Okay, now the terminology is making more sense. So a variable is a
value binding, as opposed to a function binding.

> BTW, this is explained to extreme (some might say tedious) length
> in "Lisp: by Winston and Horne".

Is it available online?
From: Alain Picard
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87fzdso1li.fsf@memetrics.com>
Dave Roberts <·····@re-move.droberts.com> writes:

> But I'm not modifying the value slot of the symbol, right?

There isn't a "value slot" for the symbol.  (Well, okay,
there is one, but that has to do with dynamic variables only,
so just pretend there is no such thing).  You are modifying
the association between a symbol and a value for a specific binding.

> Ah ha! Okay, now the terminology is making more sense. So a variable is a
> value binding, as opposed to a function binding.

Yes.  DEFUN establishes "global bindings" between symbols and functions.
FLET establishes "lexical bindings"  between symbols and functions.
DEFVAR establishes "global bindings" between symbols and values.
LET establishes "lexical bindings"  between symbols and values.

So There. 

Actually, I found re-reading chapter 3 of the Hyperspec  (as
a result of this thread) to be quite fun and instructive.    :-)

>> BTW, this is explained to extreme (some might say tedious) length
>> in "Lisp: by Winston and Horne".
>
> Is it available online?

Not to my knowledge.  Anybody else know?
From: Lars Brinkhoff
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <851xpcpf4d.fsf@junk.nocrew.org>
Alain Picard <············@memetrics.com> writes:
> Dave Roberts <·····@re-move.droberts.com> writes:
> > > "Lisp: by Winston and Horne"
> > Is it available online?
> Not to my knowledge.  Anybody else know?

It's still very much in print, so probably not.

Author webpage:
  http://www.ai.mit.edu/people/phw/Books/#Lisp
Publisher webpage:
  http://www.aw.com/catalog/academic/product/0,4096,0201083191,00.html

-- 
Lars Brinkhoff,         Services for Unix, Linux, GCC, HTTP
Brinkhoff Consulting    http://www.brinkhoff.se/
From: Pascal Bourguignon
Subject: Re: Lexical variables  (Understanding #' and function variables)
Date: 
Message-ID: <87ptcxmiqz.fsf_-_@thalassa.informatimago.com>
Dave Roberts <·····@re-move.droberts.com> writes:
>
> Okay, so a symbol really is more than just an interned string name. It
> really does have other properties. So, following up on the question right
> above, when I say:
>
> (let ((foo 1))
>         (setq foo 10))
>
> 1. What is the relationship between the variable I have created in the LET
> form and the symbol named FOO that is created by the reader when this code
> is consumed?

This relationship is very weak.   It only appears at an implementation
dependant  level,  deep  inside  the  compiler,  and  not  anymore  at
run-time.  [If  we were to  generalize lexical variables, we  could as
well accept anything as variable name:

    (LET ((#1=(+ 3 4) :UNDEFINED)) (SETQ #1# 7))

That would work as well  as symbols for lexical variable name, because
(+ 3 4) or'foo is only used as a _symbolic_ name in the source.]



(in-package "COMMON-LISP-USER")


      +-----------+                         +------------+
+---->| name     -|---> "FOO"               | name      -|--->"COMMON-LISP-USER"
|     | package  -|------------------------>| nicknames  |
|     | value    -|------------------+      | use-list   |
|     | function -|----------------+ |      +------------+
|     | plist    -|-------------+  | |
|     +-----------+             |  | |
|                               |  | |
|                               |  | v      +---------+
|     +-----------+           +-|->+-+----->| unbound |
|     | name     -|---> "NIL" | |  ^        +---------+
|     | package  -|-------+   | |  |        +---+---+
|     | value    -|-------|---|>+--|-+->+-->|car|cdr|
|     | function -|-------|---+ ^  | |  |   +---+---+
|     | plist    -|-------|-----|--|-+  |     |   |
|     +-----------+       |     |  |    +-----+<--+
|                         |     |  |
|                         +-----|--|-+
|                               |  | |
|     +-----------+             |  | |      +------------+
| +-->| name     -|---> "LET"   |  | v      | name      -|--->"COMMON-LISP"
| |   | package  -|-------------|--|-+----->| nicknames  |
| |   | value    -|-------------|--+ ^      | use-list   |
| |   | function -|-------------|--^-|--+   +------------+
| |   | plist    -|-------------+  | |  |   +-----------------------+
| |   +-----------+             ^  | |  +-->| special-operator: let |
| |                             |  | |      +-----------------------+
| |                             |  | |
| |   +-----------+             |  | |
| |+->| name     -|---> "SETQ"  |  | |
| ||  | package  -|-------------|--|-+
| ||  | value    -|-------------|--+        +------------------------+
| ||  | function -|-------------|---------->| special-operator: setq |
| ||  | plist    -|-------------+           +------------------------+
| ||  +-----------+             ^
| ||                            |
| ||                            +----------+<----------------------+
| ||                                       |                       |
| ||  (let ((foo 1)) (setq foo 3))         |                       |
| ||                                       |                       |
| ||    +---+---+   +---+---+   +---+---+  |                       |
| ||    |car|cdr|-->|car|cdr|-->|car|cdr|--+                       |
| ||    +---+---+   +---+---+   +---+---+                          |
| ||      |           |           |                                |
| +|------+           |           v                                |
|  |                  |         +---+---+   +---+---+   +---+---+  |
|  |                  |         |car|cdr|-->|car|cdr|-->|car|cdr|--+
|  |                  |         +---+---+   +---+---+   +---+---+  ^
|  |                  |           |           |   |                |
|  +------------------------------+           |   |                |
|                     |                       |   v                |
+<--------------------------------------------+ +-------------+    |
|                     |                         | integer:  3 |    |
|                     V                         +-------------+    |
|                   +---+---+   +---+---+                 ^        |
|                   |car|cdr|-->|car|cdr|-----------------|--------+
|                   +---+---+   +---+---+                 |
|                     |               |                   | after (setq foo 3)
+---------------------+               v                   |
^                               +-------------+   before  |
|                               | integer:  1 |<----------+-------+
|                               +-------------+                   |
|        +------------------------+   ^                +------+   |
|        | compiler-symbol-table: |   |           +--->|      |   |
|        +------------------------+   |           |    |      |   |
+--------|-symbol     | address  -|---+           |    |      |   |
         |            |           |               |    |      |   |
         |            |           |               |    |      |   |
         +------------------------+               |    |      |   |
                                                  |    +------+   |
         +-------------------+                    | +->|      |   |
         | run-time-stack   -|--------------------+ |  +------+   |
         +-------------------+                      |  | (*) -|---+
                                                    |  +------+
         +-------------------+                      |  |      |
         | current-frame    -|----------------------+  |      |
         +-------------------+                         |      |
                                                       +------+


    (*) is the place of the lexical variable named "FOO".





> 2. When I say (setq foo 10), am I setting the value slot of the symbol?

No, not when the symbol is not declared special.


> 3. What if I do (setq foo 10) at top-level?

This is undefined.  It could very well light a lamp in Elbonia or shut
down the nuclear plant of Springfield.


You can also see the difference by disassembling these two functions:

(progn
(defvar bar 10)
(defun ranfun (x))
(defun barfun () (let ((bar 10)) (setq bar (ranfun bar))))
(defun foofun () (let ((foo 10)) (setq foo (ranfun foo))))
(compile 'barfun)
(compile 'foofun)
(disassemble 'barfun)
(disassemble 'foofun)
)

Disassembly of function BARFUN
(CONST 0) = 10
(CONST 1) = BAR
(CONST 2) = RANFUN
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
reads special variable: (BAR)
writes special variable : (BAR)
7 byte-code instructions:
0     (CONST 0)                           ; 10
1     (BIND 1)                            ; BAR
3     (GETVALUE&PUSH 1)                   ; BAR
5     (CALL1 2)                           ; RANFUN
7     (SETVALUE 1)                        ; BAR
9     (UNBIND1)
10    (SKIP&RET 1)


Disassembly of function FOOFUN
(CONST 0) = 10
(CONST 1) = RANFUN
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
5 byte-code instructions:
0     (CONST&PUSH 0)                      ; 10
1     (LOAD&PUSH 0)
2     (CALL1 1)                           ; RANFUN
4     (VALUES1)
5     (SKIP&RET 2)
NIL


Note how in the case of barfun, there is a reference to the symbol BAR
(as (CONST 1)), while in foofun, there's no more any reference to foo,
only use of a stack (CONST&PUSH, LOAD&PUSH, VALUES1).

The  compiler-symbol-table   is  not  needed  once   the  function  or
expression is compiled.



--
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Erann Gat
Subject: Re: Lexical variables  (Understanding #' and function variables)
Date: 
Message-ID: <gNOSPAMat-0202041050270001@k-137-79-50-101.jpl.nasa.gov>
In article <·················@thalassa.informatimago.com>, Pascal
Bourguignon <····@thalassa.informatimago.com> wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> >
> > Okay, so a symbol really is more than just an interned string name. It
> > really does have other properties. So, following up on the question right
> > above, when I say:
> >
> > (let ((foo 1))
> >         (setq foo 10))
> >
> > 1. What is the relationship between the variable I have created in the LET
> > form and the symbol named FOO that is created by the reader when this code
> > is consumed?
> 
> This relationship is very weak.   It only appears at an implementation
> dependant  level,  deep  inside  the  compiler,  and  not  anymore  at
> run-time.

More strictly correct would be to say not *necessarily* any more at run
time.  Implementations are free to maintain the relationship at run time
to help in debugging, and some do.  (MCL for example.)

E.
From: Gareth McCaughan
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <87oesh9i75.fsf@g.mccaughan.ntlworld.com>
Dave Roberts wrote:

> Okay, I understand that things may be optimized away. This is no different
> than any other programming language.

Right. I wanted to stress it for two reasons.

1. In Lisp, unlike most other programming languages, there are
   *also* these things called symbols that have values and can
   readily be confused with variables :-). So it's important
   to make the distinction as explicit as possible.

2. The nature of a "variable" in Lisp is a little different
   from in C++, for instance, where there's a certain amount
   of what typically looks to Lispers like confusion between
   variables and objects. (That's "objects" in the broad sense,
   not as in "instances of classes".) So, again, it's worth
   being quite explicit...

>                                      The question is, assuming an
> interpreter or very naive compiler that keeps all variables around, how is
> a variable structured?

And the answer is: that's just a Wrong Question, a sign that
you're thinking of all this the wrong way. It's possible that
the best answer is a Zen-like slap in the face, but I'm not
the physically aggressive sort so I'll just repeat: it's a
Wrong Question. Like asking "Where does the number 3 live?"
or "Where in an electron is its mass stored?".

>                        I'm looking for a quickie definition like you have
> for symbol below. I think this is part of my problem. That is, how does a
> variable named "foo" relate to a symbol named "foo," and in particular to
> the value of symbol "foo?"

If the variable has been declared special, then (ignoring
some subtleties to do with multithreaded programs) you can
think of the value of the variable *being* the value of
the symbol: as if the compiler magically turned references
to the variable into slot accesses on the symbol.

Those subtleties are real, though, so you should think of
the above as a crutch rather than an ultimate reality :-).

If the variable has *not* been declared special (and,
please note, the huge majority of variables are not
special), the only relationship between the variable
and the symbol is that at compile time the symbol is
used as a name for the variable. The value of the
symbol doesn't come into it in the least.

> Okay, so a symbol really is more than just an interned string name. It
> really does have other properties. So, following up on the question right
> above, when I say:
> 
> (let ((foo 1))
>         (setq foo 10))
> 
> 1. What is the relationship between the variable I have created in the LET
> form and the symbol named FOO that is created by the reader when this code
> is consumed?

See above. The only relationship is that the symbol names the
variable.

> 2. When I say (setq foo 10), am I setting the value slot of the symbol?

No.

> 3. What if I do (setq foo 10) at top-level?

If you haven't declared the variable special, then the effects
of setting it at top level are not defined. Some implementations
will assume you meant to declare it special, and proceed as if
you'd issued such a declaration. Some will treat it as a "top-level
lexical variable" ("lexical" as opposed to "dynamic" binding),
in which case the effect will be as if the entire universe were
contained within a LET binding for that variable. In this case,
the value slot of the symbol is irrelevant.

> I think that these three questions here represent most of my confusion. I
> think I understand lexical variables pretty well. I'm not sure I understand
> the relationship between them and symbols, however.

The only relationship is that symbols are used as names for
variables.

> So this all makes sense. This is what I would expect from just about any
> other language. It basically acts like a local variable in all my other
> experience. Again, it's the difference between that and a variable at
> top-level that are confusing me.

Right.

> > However, there are some circumstances in which the variable
> > and the symbol coincide. Specifically, it is possible to
> > declare that a symbol represents a "special variable". That
> > means that any variable named by that symbol gets treated
> > differently. This has two possibly interesting consequences.
> > The first is that the variable is "dynamically scoped"; I
> > shan't explain what that means right now, but it's quite
> > interesting. The second, closely related to the first, is
> > that now the value of the variable is always the same as
> > the value of the symbol.
> 
> Erann Gat's paper explains this, but I'm still not quite sure I understand
> it. I thought I did when I read the paper, but after playing around with
> SBCL for a bit, the behavior isn't consistent with what I thought the
> explanation was.
> 
> For instance, why does this happen the way it does:
> * (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special

And Erann Gat's paper is right :-).

> BAR
> * (setq bar 100)
>  
> 100
> * (let ((bar 5000))
> bar)
>  
> 5000
> * bar ;;; <== why didn't the LET form set this to 5000 if bar is a special
> var?

It *did*, for the duration of the LET form. Here's another
"crutch". When a variable is special, you can pretend (modulo
all sorts of important issues that I'm not going to mention)
that

    (let ((a-special-var 1234))
      ...)

means

    (let ((old-value a-special-var))
      (setq a-special-var 1234)
      ...
      (setq a-special-var old-value))

> 100  
> * (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
> (setq bar 6000) ;; shouldn't this at least set bar to 6000?
> bar)
>  
> 6000   <== Looks like the local gets set instead...

The local *is* the top-level symbol, but when the LET is done with
it gets its old value back.

> > A "binding" is an association between a name and a value.
> > Every symbol that has a value constitutes a binding, for
> > instance; these bindings exist at run time. And every
> > time you write LET or LAMBDA or any of a whole lot of
> > other such things, you establish some bindings at compile
> > time. Unless the variables they bind have been declared
> > special, those bindings *only* exist at compile time.
> > (Well, some record of them may remain for the sake of
> > the debugger.)
> 
> So this is causing me confusion. It seems like a variable is a binding. I
> mean, that's really what it does, right? It has a name and a storage
> location, right? Now, so does a symbol, but for whatever reason, variables
> and symbols aren't the same thing, right? But a variable references a
> symbol for its name, right?

I didn't explain it very well, for which I apologize.

Yes, a variable has a name (at compile time) and a storage
location (at run time). A symbol has a name (at both compile
and run time) and a storage location (at both compile and
run time).

Variables and symbols are not the same thing for all sorts
of reasons.

  - Implementing all variable bindings in terms of symbols
    at run time would be terribly inefficient.

  - Implementing variable bindings with symbols is only
    a natural thing to do when the bindings have dynamic
    rather than lexical scope, but lexical scoping is
    almost always what you actually want.

  - Symbols have lots of machinery associated with them
    that you don't need for variable bindings in general.

A variable's name is a symbol, but I wouldn't say that a
variable "references a symbol" any more than a variable in
C++ references whatever internal compiler data structure
is used to contain *its* name.

-- 
Gareth McCaughan
.sig under construc
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <CsITb.167709$sv6.909630@attbi_s52>
Gareth McCaughan wrote:

> And the answer is: that's just a Wrong Question, a sign that
> you're thinking of all this the wrong way. It's possible that
> the best answer is a Zen-like slap in the face, but I'm not
> the physically aggressive sort so I'll just repeat: it's a
> Wrong Question. Like asking "Where does the number 3 live?"
> or "Where in an electron is its mass stored?".

That's cool. Slap away. All this is helping. ;-)

> If the variable has been declared special, then (ignoring
> some subtleties to do with multithreaded programs) you can
> think of the value of the variable *being* the value of
> the symbol: as if the compiler magically turned references
> to the variable into slot accesses on the symbol.

So are the issues with multithreaded programs that each thread keeps it own
dynamic state for each variale and thus it's as if every symbol has a slot
per thread?

> If the variable has *not* been declared special (and,
> please note, the huge majority of variables are not
> special), the only relationship between the variable
> and the symbol is that at compile time the symbol is
> used as a name for the variable. The value of the
> symbol doesn't come into it in the least.

Even for a top-level variable?

>> 3. What if I do (setq foo 10) at top-level?
> 
> If you haven't declared the variable special, then the effects
> of setting it at top level are not defined. Some implementations
> will assume you meant to declare it special, and proceed as if
> you'd issued such a declaration. Some will treat it as a "top-level
> lexical variable" ("lexical" as opposed to "dynamic" binding),
> in which case the effect will be as if the entire universe were
> contained within a LET binding for that variable. In this case,
> the value slot of the symbol is irrelevant.

Okay, so this is part of what was screwing me up. So it seems odd that CL
wouldn't define the behavior of issuing a SETQ at top-level before issuing
a DEFVAR or something. Why did they leave this undefined? I'm using SBCL on
my machine at it seems to take the "top-level lexical variable" approach
you describe, which seems fairly natural to me.

> Yes, a variable has a name (at compile time) and a storage
> location (at run time). A symbol has a name (at both compile
> and run time) and a storage location (at both compile and
> run time).
> 
> Variables and symbols are not the same thing for all sorts
> of reasons.
> 
>   - Implementing all variable bindings in terms of symbols
>     at run time would be terribly inefficient.
> 
>   - Implementing variable bindings with symbols is only
>     a natural thing to do when the bindings have dynamic
>     rather than lexical scope, but lexical scoping is
>     almost always what you actually want.
> 
>   - Symbols have lots of machinery associated with them
>     that you don't need for variable bindings in general.
> 
> A variable's name is a symbol, but I wouldn't say that a
> variable "references a symbol" any more than a variable in
> C++ references whatever internal compiler data structure
> is used to contain *its* name.

Okay, I think I understand. That helped.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ExlTb.209274$na.341193@attbi_s04>
Gareth McCaughan wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> That said, I don't think I understand the above paragraph. Part of it is
>> that I'm struggling with the various CL terminology for "cell," "object,"
>> "symbol," "variable," and "binding."
> 
> I'm not sure whether other people's replies have already got
> all this completely sorted out for you, but ...

Nope, they haven't, and this posting was hugely helpful for me. Thanks.

> A "variable" is purely a compile-time thing. At run time,
> there may not *be* anything that quite corresponds to
> a single variable. (Some variables may disappear entirely
> in compilation, as a result of optimization. Some may
> have their contents put in memory, others in registers,
> others in some combination of the two. Some may get
> transformed so that instead of anything storing "i",
> "4*i" gets put in a register so it can be used more
> efficiently as an array index. And so on.

Okay, I understand that things may be optimized away. This is no different
than any other programming language. The question is, assuming an
interpreter or very naive compiler that keeps all variables around, how is
a variable structured? I'm looking for a quickie definition like you have
for symbol below. I think this is part of my problem. That is, how does a
variable named "foo" relate to a symbol named "foo," and in particular to
the value of symbol "foo?"

> A "symbol" is *not* a purely compile-time thing; symbols
> continue to exist at run time too. A symbol is a real
> honest-to-goodness object. It has a name, a value, a
> value-as-a-function, a property list, and some other
> stuff. You can think of it as a structure with fields
> called "name", "value" and so on, if you must. (The
> value and function-value aren't necessarily set;
> usually at most one is set and often neither is.)

Okay, so a symbol really is more than just an interned string name. It
really does have other properties. So, following up on the question right
above, when I say:

(let ((foo 1))
        (setq foo 10))

1. What is the relationship between the variable I have created in the LET
form and the symbol named FOO that is created by the reader when this code
is consumed?

2. When I say (setq foo 10), am I setting the value slot of the symbol?

3. What if I do (setq foo 10) at top-level?

I think that these three questions here represent most of my confusion. I
think I understand lexical variables pretty well. I'm not sure I understand
the relationship between them and symbols, however.

I just read Erann Gat's "Idiot's Guide to Special Variables and Lexical
Closures," and that helped quite a bit. I still feel like I don't quite
understand the "rules" for how identifiers are treated differently in
top-level versus lexical scopes, however.

> Symbols appear in Lisp source code, where they may
> (among other functions) represent variables. But a
> variable called FOO does *not* necessarily have anything
> to do with the symbol called FOO, apart from the fact
> that the latter is used as the name for the former.
> So, for instance, if you write
> 
>     (let ((foo 123))
>       (do-something-with foo))
> 
> then the chances are that this will simply be transformed
> into the equivalent of
> 
>     (do-something-with 123)
> 
> And if you write
> 
>     (loop for foo from 0 to 100 do
>       (do-something-with foo))
> 
> then the chances are that the thing that counts from 0 to 100
> will live in a register and have nothing to do with the symbol
> FOO at run time.

So this all makes sense. This is what I would expect from just about any
other language. It basically acts like a local variable in all my other
experience. Again, it's the difference between that and a variable at
top-level that are confusing me.

> However, there are some circumstances in which the variable
> and the symbol coincide. Specifically, it is possible to
> declare that a symbol represents a "special variable". That
> means that any variable named by that symbol gets treated
> differently. This has two possibly interesting consequences.
> The first is that the variable is "dynamically scoped"; I
> shan't explain what that means right now, but it's quite
> interesting. The second, closely related to the first, is
> that now the value of the variable is always the same as
> the value of the symbol.

Erann Gat's paper explains this, but I'm still not quite sure I understand
it. I thought I did when I read the paper, but after playing around with
SBCL for a bit, the behavior isn't consistent with what I thought the
explanation was.

For instance, why does this happen the way it does:
* (defvar bar 10) ;; <== Erann Gat's paper says this makes bar special
 
BAR
* (setq bar 100)
 
100
* (let ((bar 5000))
bar)
 
5000
* bar ;;; <== why didn't the LET form set this to 5000 if bar is a special
var?
 
100  
* (let ((bar 5000)) ;; again, shouldn't this set bar to 5000?
(setq bar 6000) ;; shouldn't this at least set bar to 6000?
bar)
 
6000   <== Looks like the local gets set instead...
* bar  
 
100    <== ...but not the top-level symbol
*

> I think those are the key points. But I should say a little
> about the other words you mentioned.
> 
> A "binding" is an association between a name and a value.
> Every symbol that has a value constitutes a binding, for
> instance; these bindings exist at run time. And every
> time you write LET or LAMBDA or any of a whole lot of
> other such things, you establish some bindings at compile
> time. Unless the variables they bind have been declared
> special, those bindings *only* exist at compile time.
> (Well, some record of them may remain for the sake of
> the debugger.)

So this is causing me confusion. It seems like a variable is a binding. I
mean, that's really what it does, right? It has a name and a storage
location, right? Now, so does a symbol, but for whatever reason, variables
and symbols aren't the same thing, right? But a variable references a
symbol for its name, right?

> There's more than one meaning for "cell". For instance,
> the objects of which lists are composed are called "cons
> cells". A symbol has a "value cell" and a "function cell";
> these are probably the meanings you have in mind, and in
> that context "cell" means roughly the same as "field" or
> "slot" (i.e., one value-holding thing in a structure).
> The general meaning is in fact something like "value-holding
> thing".

Okay, got it. I was trying to determine if that meant a formal cons cell or
not.

> An "object" is much the same as a "value". Objects are the
> things one computes with. An integer, a string, a character,
> a CLOS instance, a symbol, a closure, all are objects. You
> could say, with apologies to W V O Quine, "To be an object
> is to be potentially the value of a variable"; that's true
> and possibly helpful, but it feels rather the wrong way around.
> (In some languages "object" means "instance of a class" and
> "class" means "user-defined data structure that fits into
> an inheritance hierarchy". Not in Common Lisp.)

Yes. I think I get this.

-- Dave
From: Tayssir John Gabbour
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <866764be.0402021156.38e0db13@posting.google.com>
Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
> That said, I don't think I understand the above paragraph. Part of it is
> that I'm struggling with the various CL terminology for "cell," "object,"
> "symbol," "variable," and "binding." I'm coming from a C->C++->Java sort of
> background and so that's clouding my thinking. What may help me is to sort
> of describe a simplistic implementation of this in C terms, so I can make
> the translation. I have bits and pieces of it, and just when I think I'm
> making some headway, I read something like the paragraph above that shows
> that I don't yet have it. ;-)

Some others have better explanations than I could give.  However, you
seem to have a vaguely similar background as I do (I futzed with VHDL
before programming normal software), and there is a perspective I
found useful in creating lisp programs.  Perhaps you'll find it useful
to shake things up in your head and break out of preconceptions.

The lisp system interprets s-expressions and pretends they're
programs.  It gives roles to various things; it imagines that symbols
are great for the role of keys, which you can use to ask the lisp
system for the data it associates with them at some point in the
program.  Since symbols are full-fledged pieces of data in
s-expressions, lisp can't ignore them like Java does.  So you can
return them from functions or whatever you imagine.  You may not think
they have intrinsic meaning, but do numbers or strings?  Some
languages don't even give you the chance to make really big numbers,
so it's not surprising they don't let you seriously use symbols
either.

If you want Java analogies, imagine making a class Symbol while
simulating a really simple lisp.  (That is, class
org.pentaside.lisp.example.Symbol.)  You have a Java program read in
s-expressions, creating objects as they're read in.  There'd be a
HashMap for simulating variables (forget about performance) where the
keys are Symbols and the values are objects like BigIntegers or
Strings.  There'd be a separate HashMap for function names; and you'd
have a little mechanism that simulates how functions would work.  This
I think is a better analogy than trying to compare lisp to Java. 
Instead, compare it to a Java program.  Java itself hides too much.

Lisp's interpretation of symbols has various useful properties.  You
can look at CLtL 2nd ed. (free online!) in the tiny and lucid ch.10
for the skinny on them.

I like how lisp really deals with s-expressions and not text.  The
program you type onto the harddrive is converted into some abstract
representation.  The parentheses eventually stop existing in any real
way.  (Though programs are influenced by a desire to make the text and
parens look pretty.  If you had some GUI lisp where pictures represent
symbols, the programs would probably be really different.)

In this way, macros appear pretty simple; they just take my
s-expressions at compiletime and transform them into a more efficient,
safer or lispsystem-understandable s-expression.  I probably wanted to
write a pretty program the lisp system couldn't make heads or tails
of; with macros, I can have them silently transformed into something
the lisp system does.

Hope this made any sense at all.
From: Dave Roberts
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <CfITb.165640$Rc4.1286372@attbi_s54>
Tayssir John Gabbour wrote:

> The lisp system interprets s-expressions and pretends they're
> programs.  It gives roles to various things; it imagines that symbols
> are great for the role of keys, which you can use to ask the lisp
> system for the data it associates with them at some point in the
> program.  Since symbols are full-fledged pieces of data in
> s-expressions, lisp can't ignore them like Java does.  So you can
> return them from functions or whatever you imagine.  You may not think
> they have intrinsic meaning, but do numbers or strings?  Some
> languages don't even give you the chance to make really big numbers,
> so it's not surprising they don't let you seriously use symbols
> either.
> 
> If you want Java analogies, imagine making a class Symbol while
> simulating a really simple lisp.  (That is, class
> org.pentaside.lisp.example.Symbol.)  You have a Java program read in
> s-expressions, creating objects as they're read in.  There'd be a
> HashMap for simulating variables (forget about performance) where the
> keys are Symbols and the values are objects like BigIntegers or
> Strings.  There'd be a separate HashMap for function names; and you'd
> have a little mechanism that simulates how functions would work.  This
> I think is a better analogy than trying to compare lisp to Java.
> Instead, compare it to a Java program.  Java itself hides too much.

Thanks. That's just the sort of under-the-covers look I was wanting. I
wasn't actually wanting to compare Lisp to another language, just trying to
understand the naive implementation of it, using another language that I
understand as the way to describe that other implementation. You
description is spot on for what I was wanting.

> Lisp's interpretation of symbols has various useful properties.  You
> can look at CLtL 2nd ed. (free online!) in the tiny and lucid ch.10
> for the skinny on them.
> 
> I like how lisp really deals with s-expressions and not text.  The
> program you type onto the harddrive is converted into some abstract
> representation.  The parentheses eventually stop existing in any real
> way.  (Though programs are influenced by a desire to make the text and
> parens look pretty.  If you had some GUI lisp where pictures represent
> symbols, the programs would probably be really different.)
> 
> In this way, macros appear pretty simple; they just take my
> s-expressions at compiletime and transform them into a more efficient,
> safer or lispsystem-understandable s-expression.  I probably wanted to
> write a pretty program the lisp system couldn't make heads or tails
> of; with macros, I can have them silently transformed into something
> the lisp system does.

Yes, agreed fully. It seems one of the greatest strengths of Lisp is its
macro facility. Manipulating the parse tree at compilation time is really
cool!

> Hope this made any sense at all.

Absolutely, thanks. It helped.

-- Dave
From: Thomas A. Russ
Subject: Re: Understanding #' and function variables
Date: 
Message-ID: <ymi65em643d.fsf@sevak.isi.edu>
Dave Roberts <·····@re-move.droberts.com> writes:
> 
> > By default, in the arguments of a function call, CL expects that symbols
> > will name ordinary variables.  If you want a symbol to name the function
> > variable in the alternate namespace, then you use #'A.
> > 
> > (let ((a (lambda (x) x)))  ; ordinary variable binding declaration
> >   (flet ((a (x) x))  ; function variable binding declaration
> >     (foo a)  ; A names the ordinary variable
> >     (foo #'a)))  ; #'A names the function variable
> 
> So this brings up a good question: If these are implemented as the same
> symbol with two "slots" (not to be confused with CLOS slots), then it seems
> like this would cause problems.

I wouldn't worry too much about "implementation" issues at this stage.
What is important is to get the concept down and just assume that clever
compiler writers have figured out how to get the "magic" to work.

If you think about it, most other programming languages like Java also
have similar constructs.  For example, if you have a variable named
"bar" in your Java program, you can also have a method named "bar" at
the same time.  And you could also have a class named "bar" as well.  In
fact you could write a class "bar" that had a method "bar" and a slot
"bar" and everything would still work.

Similarly in Common Lisp, the association between symbols and values,
functions or classes is maintained separately.  Which of the
associations you get depends on the context in which the evaluation of
the name (symbol) takes place.  If the symbol appears in a function
position, you use the function lookup procedure.  If it appears in an
argument position, you use the value lookup procedure.  If it is used as
a class name in MAKE-INSTANCE, you use the class lookup procedure.

The only time things get a little confusing is when you want to use a
non-standard lookup method on the name.  The APPLY and FUNCALL methods
take arguments, and for consistency function arguments are all looked up
in the same way, namely by getting their values.  If you wanted to write
a function that takes a class as an argument then you would need to
write code that explicitly gets the class:

    (f (get-class 'a))

similarly if you want your function argument to be a function, you need
to do the lookup as a function:

    (f (function a))

Since this happens often, Common Lisp provides #' as a shortcut to
writing (FUNCTION ...) around it.  An example closer to the one above
for classes would be

    (f (symbol-function 'a))

but it is not quite the same.  That is because SYMBOL-FUNCTION will get
the global value of the function associated with A and not any locally
bound values from FLET or LABELS.  The presence of these lexical binding
constructs for values (LET) and functions means that things are slightly
more complicated than for other lookup procedures.

The principle behind this is that an attempt is made to make the most
common programming action be the simplest to write, with shortcuts to
make other not quite so common forms also fairly compact, and only
require the most verbose solutions to the least common idioms.

For an exercise, why not examine how one would go about writing
something like a FUNCALL function in Java?  That would give you some
appreciation for all of the detail in looking up various things that
Lisp makes so much easier....

> If these are really two separate symbols in
> two separate namespaces (like if I was doing name mangling internally or
> something to value-A and function-A), that would seem to be better. The
> binding for "function-A" would go away as the FLET form was exited, while
> that would still leave "value-A" around until the LET form exited. If these
> are the same symbol, "A," with just two slots, I'm not sure how it would be
> handled when the FLET form went out of scope and yet I was still in the LET
> scope.

If you insist on thinking in terms of implementations, then there must
be some connection between the variable and the value to which it is
bound.  At scope exit some process (which we don't need to understand in
detail) makes the binding go away.  There is no reason to suppose that
this process cares whether it needs to have a separate symbol for each
type of binding or whether it just needs to know how to undo it.

If you really insist on a Java-esque example of how this might work,
consider the following, abbreviated Java example.

Assume a class Symbol with slots value and function.

    Symbol a = new Symbol();
    ...
    Object old_value = a.value;
    try {
      a.value = ... //  (lambda (x) x)
      Function old_function = a.function;
      try {
         a.function = ...  //  (x) x
         foo((Function)a.value);
         foo(a.function);
      } finally {
        a.function = old_function;
      }
     // At this point the function binding is restored!
   } finally {
     a.value = old_value;
   }

But this is much more ugly in Java :)


> 
> -- Dave
> 

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Erik Naggum
Subject: Re: State machine representation
Date: 
Message-ID: <2004-032-873-KL2065E@naggum.no>
* Dave Roberts
| Specifically, I was comparing CL's way of handling functions bound to
| symbols with that of Scheme, which honestly does seem cleaner, in my
| not so educated opinion.

  So the first language you learned is better than the next language you
  set out to learn?  That attitude is the reason people never learn to
  speak anything but their first language well.

  I just commented on this phenomenon over in misc.metric-system, in
  <····················@naggum.no>.  It certainly applies here, too.

| Anyway, I was not trying to offend.  If you believe there is a lot of
| advantage in CL's way of doing things, please share.  I want to
| understand if there is something I may have missed.

  What you have missed is that languages are the products of evolution.
  Just learn the language at hand.  Do not compare it to anything else,
  or you will continue to write and think in whatever you compare with.

  Have you ever tried to compare a potential girlfriend with your first?
  The urge to compare may be human, but if so, it ranks up there with
  errare humanum est -- you expend effort not to make mistakes precisely
  because it is so human.  There is no way to avoid offending people if
  you keep comparing them to other people all the time.  Languages are
  the products of people and all those who use them are people.  Imagine
  someone who compares you to some other bloke all the time if you have
  a hard time with the metaphors I have used, and you should be able to
  realize that the act of comparing is the fundamental insult.  Not only
  does comparing with something else prevent you from appreciating what
  something is on its own merits, you will naturally resist comparisons
  that make it evident that it is superior to what you compare it with.

  If you wish to speak Common Lisp with a strong Scheme accent, you are
  well on your way.  I cannot imagine why anyone would /want/ to speak
  with a strong accent, but then again, I have been known to be hostile
  to people who use their dialects outside of their home town and have
  this incredibly annoying urge to tell me where they grew up instead of
  anything worth hearing about.  While this bizarre ritual is somehow a
  human right in the eyes of those who do it, the computer will not be
  impressed with your heritage, will not consider you a honorary member
  of its tribe because you exhibit the same regionally accepted speech
  impediments, and will not congratulate you on how well you speak a
  foreign language despite the rather annoying and obvious flaws.  So my
  advice to you, and this is pretty strongly felt because I believe that
  the first thing you learn is an irrelevant accident of timing which
  must not prevent you from learning new things that accidentally arrive
  within your sensory experiences later, is that you completely forget
  everything you learned from Scheme and start afresh with Common Lisp
  in its own right, on its own merits.

  Otherwise, I may want to compare you to all the other people who have
  never learned Common Lisp because they were stuck in Compareville.

-- 
Erik Naggum | Oslo, Norway                                      2004-032

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <5%eTb.200508$I06.2212979@attbi_s01>
Erik Naggum wrote:

> * Dave Roberts
> | Specifically, I was comparing CL's way of handling functions bound to
> | symbols with that of Scheme, which honestly does seem cleaner, in my
> | not so educated opinion.
> 
>   So the first language you learned is better than the next language you
>   set out to learn?  That attitude is the reason people never learn to
>   speak anything but their first language well.

No, not at all. Indeed, if this was true, I would not have progressed
through BASIC -> Assembly Language -> Pascal -> Forth -> C -> Fortran ->
bit of CL -> bit of Scheme -> C++ -> Java -> CL.

Comparisons between things are one way we check whether we understand
something. Rote learning is certainly possible, but I find it terribly
difficult. I do far better when I understand the "why" behind something,
even if it's just "no reason, that's just the way we did it." Further, I
think this is well supported by lots of research into memorization. The
more "hooks" you have between things you already know and the material you
are learning, the better you are able to retain the new information.
Without these hooks, your alternative is to simply keep repeating the
material until it eventually sets in. This can be quite a long process,
however.

Note that I'm not saying, "X is correct because I learned it first." It's
just natural to say, "Hmmm... Y does this differently than X, and X seems
cleaner, not because I learned it first, but just because it seems
cleaner." Without background as to why things are done the way they are, it
actually presents a barrier to learning. I would note that others were very
quick to suggest many other references that explain the issue to me, while
you seem to be suggesting that I'm wrong to even ask the question.

As a check, is that what you're really trying to tell me?

> | Anyway, I was not trying to offend.  If you believe there is a lot of
> | advantage in CL's way of doing things, please share.  I want to
> | understand if there is something I may have missed.
> 
>   What you have missed is that languages are the products of evolution.
>   Just learn the language at hand.  Do not compare it to anything else,
>   or you will continue to write and think in whatever you compare with.

I think that is foolish. Certainly Lisp compares itself all the time with
other languages. Indeed, one reason that I'm learning Lisp is after reading
through some of Paul Graham's claims that Lisp is a "better" language than
others. Certainly, I should be allowed to weigh the evidence of such claims
by comparisons to other languages, right?

>   If you wish to speak Common Lisp with a strong Scheme accent, you are
>   well on your way.  I cannot imagine why anyone would /want/ to speak
>   with a strong accent, but then again, I have been known to be hostile
>   to people who use their dialects outside of their home town and have
>   this incredibly annoying urge to tell me where they grew up instead of
>   anything worth hearing about.  While this bizarre ritual is somehow a
>   human right in the eyes of those who do it, the computer will not be
>   impressed with your heritage, will not consider you a honorary member
>   of its tribe because you exhibit the same regionally accepted speech
>   impediments, and will not congratulate you on how well you speak a
>   foreign language despite the rather annoying and obvious flaws.  So my
>   advice to you, and this is pretty strongly felt because I believe that
>   the first thing you learn is an irrelevant accident of timing which
>   must not prevent you from learning new things that accidentally arrive
>   within your sensory experiences later, is that you completely forget
>   everything you learned from Scheme and start afresh with Common Lisp
>   in its own right, on its own merits.

Fair enough, and I actually agree with some of that. The learning process
natually causes comparisons, however. I figured CL was "tough enough" to
handle a newbie asking questions, however. My goal is not to "speak CL with
a Scheme accent." My goal is to become proficient at CL (indeed, that was
what caused me to post my initial question about how to represent state
machines). The fact that Scheme is another lisp dialect that is somewhat
related in some of its ideas naturally causes one to see differences and
ask questions, however.

>   Otherwise, I may want to compare you to all the other people who have
>   never learned Common Lisp because they were stuck in Compareville.

Hmmm... Not sure what to say here. I'm making an honest effort to try to
learn and understand. If you don't or can't respect that, I suppose that's
your choice. I hope that others populating this group will be kind enough
to help me and not take the same attitude. Indeed, many have already been
so in precisely this thread.

-- Dave
From: Erik Naggum
Subject: Re: State machine representation
Date: 
Message-ID: <2004-032-917-KL2065E@naggum.no>
* Erik Naggum
> What you have missed is that languages are the products of evolution.
> Just learn the language at hand.  Do not compare it to anything else,
> or you will continue to write and think in whatever you compare with.

* Dave Roberts
| I think that is foolish.

  OK.  Goodbye, then.

-- 
Erik Naggum | Oslo, Norway                                      2004-032

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Vijay L
Subject: Re: State machine representation
Date: 
Message-ID: <1eaf81aa.0402030523.6f7a7cd5@posting.google.com>
Dave Roberts <·····@re-move.droberts.com> wrote in message news:<························@attbi_s01>...
> Erik Naggum wrote:
 
[snip]
 
> >   What you have missed is that languages are the products of evolution.
> >   Just learn the language at hand.  Do not compare it to anything else,
> >   or you will continue to write and think in whatever you compare with.
> 
> I think that is foolish. Certainly Lisp compares itself all the time with
> other languages. Indeed, one reason that I'm learning Lisp is after reading
> through some of Paul Graham's claims that Lisp is a "better" language than
> others. Certainly, I should be allowed to weigh the evidence of such claims
> by comparisons to other languages, right?
> 

This is said in the abstract of "The evolution of Lisp" by Guy L.
Steele Jr. and Richard P. Gabriel

~ Overall, the evolution of Lisp has been guided more by institutional
rivalry,
~ one-upsmanship, and the glee born of technical cleverness that is 
~ characteristic of the "hacker culture" than by sober assessments of
technical
~ requirements.

I remember reading somewhere (I think on some quotes page) that
language desigers are also human...driven by their own...

Cheers,
Vijay
From: Harald Hanche-Olsen
Subject: Re: State machine representation
Date: 
Message-ID: <pcosmhuo4lc.fsf@thoth.math.ntnu.no>
+ Dave Roberts <·····@re-move.droberts.com>:

| Specifically, I was comparing CL's way of handling functions bound
| to symbols with that of Scheme, which honestly does seem cleaner, in
| my not so educated opinion.

I suggest you go back and search this newsgroup for discussions on the
single name space issue.  Once more, I can recommend Kent Pitman's
articles.  (I have no idea how hard they will be to find using the
standard search engines, but it's worth the effort.  And I am sure we
wouldn't care to rehash the whole discussion all over again.  We could
use some artificial intelligence scanning the newsgroup and indexing
stuff by topic, not just by words and phrases.)

| In general, Scheme seems more clean and streamlined ("regular" ?).

Ah, but to borrow a metaphor from Neal Stephenson's Cryptonomicon, so
does a drill made for the home user when compared to one made for the
professional builder.  The latter may look ugly, but it is totally
reliable and gets the job done with a minimum of fuzz.  And the
ugliness just fades away as you begin to appreciate the tool for what
it can do.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <C1fTb.200524$I06.2213130@attbi_s01>
Harald Hanche-Olsen wrote:

> + Dave Roberts <·····@re-move.droberts.com>:
> 
> | Specifically, I was comparing CL's way of handling functions bound
> | to symbols with that of Scheme, which honestly does seem cleaner, in
> | my not so educated opinion.
> 
> I suggest you go back and search this newsgroup for discussions on the
> single name space issue.  Once more, I can recommend Kent Pitman's
> articles.  (I have no idea how hard they will be to find using the
> standard search engines, but it's worth the effort.  And I am sure we
> wouldn't care to rehash the whole discussion all over again.  We could
> use some artificial intelligence scanning the newsgroup and indexing
> stuff by topic, not just by words and phrases.)

Yes, people have sent me the reference, which I appreciate, BTW. My goal
wasn't to inflame here, but it seems I have really stepped on some toes...
;-)

> | In general, Scheme seems more clean and streamlined ("regular" ?).
> 
> Ah, but to borrow a metaphor from Neal Stephenson's Cryptonomicon, so
> does a drill made for the home user when compared to one made for the
> professional builder.  The latter may look ugly, but it is totally
> reliable and gets the job done with a minimum of fuzz.  And the
> ugliness just fades away as you begin to appreciate the tool for what
> it can do.

Yes, fair enough. Hence my questions about this. One very valid answer, as
I'm now finding out, is simply, "Dave, you're a clueless newbie. Here's why
we did it this way and it's actually better than the alternative: ..."

I think the Gabriel & Pitman paper probably goes into it all, but I'm still
answering posts here and haven't read more than the first couple of
paragraphs yet. ;-)

-- Dave
From: Kenny Tilton
Subject: Re: State machine representation
Date: 
Message-ID: <YdfTb.170910$4F2.20301661@twister.nyc.rr.com>
Dave Roberts wrote:
> Yes, people have sent me the reference, which I appreciate, BTW. My goal
> wasn't to inflame here, but it seems I have really stepped on some toes...
> ;-)

It is pretty funny how you have managed to set off just about every land 
mine in the joint in your first few questions. If you dig into Google 
and read every thread we have seen on namespaces and tail recursion and 
CL vs Scheme, when you finish in six months you will understand that... 
well, you are lucky to be alive at this point.

:)

kenny

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvllnmfm7u.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Dave Roberts wrote:
> > Yes, people have sent me the reference, which I appreciate, BTW. My goal
> > wasn't to inflame here, but it seems I have really stepped on some toes...
> > ;-)
> 
> It is pretty funny how you have managed to set off just about every land 
> mine in the joint in your first few questions. If you dig into Google 
> and read every thread we have seen on namespaces and tail recursion and 
> CL vs Scheme, when you finish in six months you will understand that... 
> well, you are lucky to be alive at this point.
> 
> :)

To head off the next one: continuations are a bad idea in an
industrial strength language like CL.  They're not missing, their lack
is a feature. ;-)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <QEfTb.200775$I06.2213770@attbi_s01>
Thomas F. Burdick wrote:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
>> Dave Roberts wrote:
>> > Yes, people have sent me the reference, which I appreciate, BTW. My
>> > goal wasn't to inflame here, but it seems I have really stepped on some
>> > toes... ;-)
>> 
>> It is pretty funny how you have managed to set off just about every land
>> mine in the joint in your first few questions. If you dig into Google
>> and read every thread we have seen on namespaces and tail recursion and
>> CL vs Scheme, when you finish in six months you will understand that...
>> well, you are lucky to be alive at this point.
>> 
>> :)
> 
> To head off the next one: continuations are a bad idea in an
> industrial strength language like CL.  They're not missing, their lack
> is a feature. ;-)
> 

Whew! Glad you said that... ;-)

Seriously, I actually have never understood continuations that well. They
always sort of make my head hurt. Even when they do come into focus every
now and then, they seem very inefficient. It would appear that a good Lisp
with threads would be far better. Yes, you may not be able to do some of
the fancy things that continuations allow, but they handle all the standard
cases pretty well, thank you.

Anyway, I won't ask that question. Anything else I should steer clear of?

-- Dave
From: Joe Marshall
Subject: Re: State machine representation
Date: 
Message-ID: <n0818o8t.fsf@ccs.neu.edu>
Dave Roberts <·····@re-move.droberts.com> writes:

>
> Anyway, I won't ask that question. Anything else I should steer clear of?

We like parenthesis.

If you like tail recursion, turn it on.  Most implementations can do
it.

Some people actually like LOOP.

No one writes stand-alone C or Java programs, so don't complain about lisp.

Lisp *is* case sensitive, the reader folds case by default, but you
can change that.

If you want to talk about Scheme, go to comp.lang.scheme

Lisp has been compiled since before you were born.  If not, you are
old enough to know better.

Lisp is 44 years old.  Name an idea and it's been tried before.

Here's a primer I wrote a couple of years back:

1.  Read before posting.  If you intend to join the community long
    term, it would be a good idea to read it for several weeks before
    joining in.

2.  Do your homework.  If you have a quick question, check the
    archives to see if it has already been discussed or answered.

3.  At least *attempt* to do your homework.  If you have a homework
    problem that you can't solve, show us what you have so far.

4.  Keep it technical and on topic.  If you have a question, ask it.
    Remember that opinions are like assholes:  everyone's got one, and
    no one wants to look at anybody else's.

5.  Don't take it personally.  You haven't arrived until someone damns
    you to eternal perdition or cast aspersions on the genetic makeup
    of your ancestors.  Remember, it is better to keep your mouth shut
    and have people suspect you are an idiot than to open it and
    dismiss all doubt.  If you don't like someone, no one is forcing
    you to even *read* their posts, let alone respond.

6.  This is comp.lang.lisp, not comp.lang.scheme, comp.lang.perl,
    or comp.lang.c++  If you prefer these languages, hang out there.
    Believe it or not, many of the people in comp.lang.lisp actually
    program in languages other than lisp and are up to date on the
    latest trends in computing.

7.  Write your own lisp system before complaining about others. There
    are people here that hack lisp professionally and have done so for
    a *long time*.  They don't want to hear criticism from someone who
    read about lisp in a book.
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <uaITb.167863$5V2.855304@attbi_s53>
Joe Marshall wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>>
>> Anyway, I won't ask that question. Anything else I should steer clear of?
> 
> We like parenthesis.

They're growing on me rapidly.

> If you like tail recursion, turn it on.  Most implementations can do
> it.

I can see the pros and cons. As a programming style, I like it. As a
debugging issue, I can see the problem.

> Some people actually like LOOP.

The jury is still out on that one. I'll ask for opinions in a couple of
weeks... ;-)

> No one writes stand-alone C or Java programs, so don't complain about
> lisp.

I think I understand with respect to Java. I don't with respect to C. Please
educate me.

> Lisp *is* case sensitive, the reader folds case by default, but you
> can change that.

Right. You can change just about anything in Lisp, I'm learning. This is one
of its greatest attributes, from what I can tell.

> If you want to talk about Scheme, go to comp.lang.scheme

After my last comment on Scheme, I'm thinking I'll never mention it again.
Besides CL is really growing on me.

> Lisp has been compiled since before you were born.  If not, you are
> old enough to know better.

Hmmmm... When was that?

> Lisp is 44 years old.  Name an idea and it's been tried before.

Good point.

-- Dave
From: Jacek Generowicz
Subject: Re: State machine representation
Date: 
Message-ID: <tyfn080sgf6.fsf@pcepsft001.cern.ch>
Dave Roberts <·····@re-move.droberts.com> writes:

> > No one writes stand-alone C or Java programs, so don't complain about
> > lisp.
> 
> I think I understand with respect to Java. I don't with respect to C. Please
> educate me.

Just a couple of days ago a friend of mine had a little accident with
his /var directory. Suddenly _ALL_ af his "stand alone" C and C++
programs (which are nowhere near the /var directory) don't work ... to
the extent that his computer is completely unusable.
From: Joe Marshall
Subject: Re: State machine representation
Date: 
Message-ID: <n080bi62.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Joe Marshall wrote:
>
>> No one writes stand-alone C or Java programs, so don't complain about
>> lisp.
>
> I think I understand with respect to Java. I don't with respect to C. Please
> educate me.

A compiled Lisp program needs a Lisp run-time environment to execute.
A compiled Java program needs a Java run-time environment to execute.
A compiled C program needs a C run-time environment to execute.

The difference is that you usually have a C run-time environment
installed and the operating system program launcher knows how to link
to it.  You can generally assume that the target platform has a C
run-time and often get away with distributing only part of the program
(which is the executable).  But these days, people don't even do that.
A C program comes as an executable and a bunch of dynamic libraries
and an implicit requirement that you have a C run-time.

>> Lisp has been compiled since before you were born.  If not, you are
>> old enough to know better.
>
> Hmmmm... When was that?

I have no idea when you were born.  I thought you'd know.

From  http://www-formal.stanford.edu/jmc/history/lisp/lisp.html
  ``The first successful LISP compiler was programmed by Timothy Hart and
    Michael Levin. It was written in LISP and was claimed to be the first
    compiler written in the language to be compiled.''

That would be circa 1962.  See 
  ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-039.pdf

-- 
~jrm
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <IoQTb.209818$I06.2320857@attbi_s01>
Joe Marshall wrote:

> A compiled Lisp program needs a Lisp run-time environment to execute.
> A compiled Java program needs a Java run-time environment to execute.
> A compiled C program needs a C run-time environment to execute.
> 
> The difference is that you usually have a C run-time environment
> installed and the operating system program launcher knows how to link
> to it.  You can generally assume that the target platform has a C
> run-time and often get away with distributing only part of the program
> (which is the executable).  But these days, people don't even do that.
> A C program comes as an executable and a bunch of dynamic libraries
> and an implicit requirement that you have a C run-time.

Right. But since most OSs cater to that, that's perceived as the "right way"
(TM) to deliver that for most users. You may be arguing well from a
technical basis, but I'm not sure that matters when this issue comes up.
What people are more interested in is how the user perceives the
application. If it requires more incantations or fiddling than the
"equivalent" C program, then the other system loses. This has hurt Java
adoption somewhat.

I guess I'd say, there is a real issue here from a user perception point of
view. Make sure you don't sweep it under the rug. Yes, technically, under
the hood, you're absolutely right, but it's a C world, and that's the way
it will likely remain.

Note that this applies only to end-user apps, whether shrink-wrapped or
freeware.

> 
>>> Lisp has been compiled since before you were born.  If not, you are
>>> old enough to know better.
>>
>> Hmmmm... When was that?
> 
> I have no idea when you were born.  I thought you'd know.
> 
> From  http://www-formal.stanford.edu/jmc/history/lisp/lisp.html
>   ``The first successful LISP compiler was programmed by Timothy Hart and
>     Michael Levin. It was written in LISP and was claimed to be the first
>     compiler written in the language to be compiled.''
> 
> That would be circa 1962.  See
>   ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-039.pdf

Okay, that really is before I was born (1967). Just checking. I have been
programming for about 25 years, though, so it's not like I'm some
snot-nosed kid raised on nothing but VB and C# (he says, flexing his ego
somewhat... ;-)

-- Dave
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvvfmododh.fsf@famine.OCF.Berkeley.EDU>
Dave Roberts <·····@re-move.droberts.com> writes:

> I guess I'd say, there is a real issue here from a user perception point of
> view. Make sure you don't sweep it under the rug. Yes, technically, under
> the hood, you're absolutely right, but it's a C world, and that's the way
> it will likely remain.

All the major Lisp systems have reasonable ways of delivering things
that behave as normal apps, for all the end user knows or cares.
They're not optimized for "Hello, World!", but some of them bring
along only 1-2Mb of bloat (CLISP, LispWorks, probably ECL).  Others a
little bit more (MCL, OpenMCL, CMUCL), and others a lot (SBCL).  Given
Lisp's emphasis on big systems to solve hard problems, I'm still
somewhat impressed that there are delivery options for little apps.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Henrik Motakef
Subject: Re: State machine representation
Date: 
Message-ID: <x7vfmojabp.fsf@crocket.internal.henrik-motakef.de>
Dave Roberts <·····@re-move.droberts.com> writes:

> Right. But since most OSs cater to that, that's perceived as the "right way"
> (TM) to deliver that for most users. You may be arguing well from a
> technical basis, but I'm not sure that matters when this issue comes up.
> What people are more interested in is how the user perceives the
> application. If it requires more incantations or fiddling than the
> "equivalent" C program, then the other system loses. This has hurt Java
> adoption somewhat.
> 
> I guess I'd say, there is a real issue here from a user perception point of
> view. Make sure you don't sweep it under the rug. Yes, technically, under
> the hood, you're absolutely right, but it's a C world, and that's the way
> it will likely remain.

But this is kinda the point. Very few people really need "standalone"
(perhaps "native" would be better, in the sense as "working as every
other damn program on this OS) executables, they need their programs
to be easy to install and use. This is trivial to do with any
implementation I know, and the low-tech way of providing a starter
script has no serious disadvantages, neither for users nor for the
programmer.

(A short investigation on my local system reveals that starter scripts
are good enough at least for Mozilla and Opera, both of which are
end-user applications and definitely not implemented in Common Lisp or
any other fancy runtime-dependend language.)

I understand that sometimes size is an issue - you just cannot
currently use CMUCL to implement a small utility to carry around on a
floppy disk. But I don't think that this is what motivates most of the
questions on that topic here, and after all, you /can/ build such
things with other implementations.

At least it is unlikely that users of Lisp apps run into problems due
to an incompatible runtime version, since any Lisp programmer shipping
binaries will probably expect that no Lisp runtime is already
installed anyway and just include it. So the X3J13 committee will
never have to sue Microsoft because the CL implementation shipped with
Windows is not ANSI-compliant, like Sun had to because of the MS
JRE. :-)
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvfzdsdlmc.fsf@famine.OCF.Berkeley.EDU>
Henrik Motakef <············@henrik-motakef.de> writes:

> I understand that sometimes size is an issue - you just cannot
> currently use CMUCL to implement a small utility to carry around on a
> floppy disk. But I don't think that this is what motivates most of the
> questions on that topic here, and after all, you /can/ build such
> things with other implementations.

Floppy disk!  You're killing me!  :-)
"Hmm, this is a funny looking CD..."

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Henrik Motakef
Subject: Re: State machine representation
Date: 
Message-ID: <x7isioj612.fsf@crocket.internal.henrik-motakef.de>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Henrik Motakef <············@henrik-motakef.de> writes:
> 
> > I understand that sometimes size is an issue - you just cannot
> > currently use CMUCL to implement a small utility to carry around on a
> > floppy disk. But I don't think that this is what motivates most of the
> > questions on that topic here, and after all, you /can/ build such
> > things with other implementations.
> 
> Floppy disk!  You're killing me!  :-)
> "Hmm, this is a funny looking CD..."

No kidding. Two of the most frequenty mentioned advantages of the
Putty SSH client for Windows are that it is a "standalone executable"
(not requiring any installation step, only a multi-gigabyte and
-kilodollar operating system), and that it is small enough to fit on a
floppy disk. (The fact that it is one of very few Win32 SSH clients
that are actually usable at all is not frequently mentioned for some
reason) Indeed, I even used to carry a floppy with important things
like my private key and a PGP version for Windows and Linux on a
floppy with my until a few months ago myself, and I still can think of
situations where tomsrtbt is useful.

Unfortunately, floppy disks are still at least as usefull even in 2004
than, say, multiple mouse buttons...
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcv1xpbevy5.fsf@famine.OCF.Berkeley.EDU>
Henrik Motakef <············@henrik-motakef.de> writes:

> Unfortunately, floppy disks are still at least as usefull even in 2004
> than, say, multiple mouse buttons...

I guess it depends on what world you're in.  When was the last time
you saw a Mac or a laptop with a floppy drive?  A DOS-formatted
diskette is almost useless to me, personally (although I can power up
the Linux box and move the data across the network).

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Henrik Motakef
Subject: Re: State machine representation
Date: 
Message-ID: <x7znbzj0a4.fsf@crocket.internal.henrik-motakef.de>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Henrik Motakef <············@henrik-motakef.de> writes:
> 
> > Unfortunately, floppy disks are still at least as usefull even in 2004
> > than, say, multiple mouse buttons...
> 
> I guess it depends on what world you're in.  When was the last time
> you saw a Mac or a laptop with a floppy drive?

I haven't had much contanct with Macs (obviously?), but unfortunatly,
I do have to deal with laptops that have a (non-removable) floppy
drive and cannot deal with CDs, let alone DVDs or USB sticks. Yes,
sometimes life sucks. I'm happy if they have a pentium processor.

And no, I don't think that this should be an environment most CL apps
should have to care about. :-)
From: Christopher C. Stacy
Subject: Re: State machine representation
Date: 
Message-ID: <uwu74vszx.fsf@news.dtpq.com>
>>>>> On 03 Feb 2004 20:51:21 +0100, Henrik Motakef ("Henrik") writes:

 Henrik> ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
 >> Henrik Motakef <············@henrik-motakef.de> writes:
 >> 
 >> > I understand that sometimes size is an issue - you just cannot
 >> > currently use CMUCL to implement a small utility to carry around on a
 >> > floppy disk. But I don't think that this is what motivates most of the
 >> > questions on that topic here, and after all, you /can/ build such
 >> > things with other implementations.
 >> 
 >> Floppy disk!  You're killing me!  :-)
 >> "Hmm, this is a funny looking CD..."

 Henrik> No kidding. Two of the most frequenty mentioned advantages of
 Henrik> the Putty SSH client for Windows are that it is a "standalone
 Henrik> executable" (not requiring any installation step, only a
 Henrik> multi-gigabyte and -kilodollar operating system), and that it
 Henrik> is small enough to fit on a floppy disk.

The way that most people I know take advantage of those features of
PuTTY is that they download it from the web browser onto whatever
machine they wind up sitting at.

(So it's not really relevent that it fits on a floppy disk or that
it's a standalone executable.  The feature is that you can click 
on it, and it installs.  You can do the same thing with Lisp.)
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <NF%Tb.86544$U%5.465426@attbi_s03>
Henrik Motakef wrote:

> But this is kinda the point. Very few people really need "standalone"
> (perhaps "native" would be better, in the sense as "working as every
> other damn program on this OS) executables, they need their programs
> to be easy to install and use. This is trivial to do with any
> implementation I know, and the low-tech way of providing a starter
> script has no serious disadvantages, neither for users nor for the
> programmer.
> 

Yes, I think "native" is a better word. I agree that the issue is going away
at a certain level. It's far worse on Windows since the scripting
capability is so poor an typically results in a command interpreter window
being created if done naively. You can work around all this, but again,
it's work. With *nix, it's far easier since everything can worst-case be
launched from a simple sh script.

> (A short investigation on my local system reveals that starter scripts
> are good enough at least for Mozilla and Opera, both of which are
> end-user applications and definitely not implemented in Common Lisp or
> any other fancy runtime-dependend language.)

Yep, exactly. Given that, it bodes well for Lisp/Java/etc.

> I understand that sometimes size is an issue - you just cannot
> currently use CMUCL to implement a small utility to carry around on a
> floppy disk. But I don't think that this is what motivates most of the
> questions on that topic here, and after all, you /can/ build such
> things with other implementations.

Right. Again, even if you want that, you'll have to have a statically linked
C program or at least a dynamic binary that requires nothing but very
standard libraries.

> At least it is unlikely that users of Lisp apps run into problems due
> to an incompatible runtime version, since any Lisp programmer shipping
> binaries will probably expect that no Lisp runtime is already
> installed anyway and just include it. So the X3J13 committee will
> never have to sue Microsoft because the CL implementation shipped with
> Windows is not ANSI-compliant, like Sun had to because of the MS
> JRE. :-)

Right. ;-)
From: Paolo Amoroso
Subject: Re: State machine representation
Date: 
Message-ID: <87fzdq22z5.fsf@plato.moon.paoloamoroso.it>
Henrik Motakef <············@henrik-motakef.de> writes:

> (A short investigation on my local system reveals that starter scripts
> are good enough at least for Mozilla and Opera, both of which are
> end-user applications and definitely not implemented in Common Lisp or
> any other fancy runtime-dependend language.)

OpenOffice too.


Paolo
-- 
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Ingvar Mattsson
Subject: Re: State machine representation
Date: 
Message-ID: <87n08070i5.fsf@gruk.tech.ensign.ftech.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Joe Marshall wrote:
[ SNIP ]
> > No one writes stand-alone C or Java programs, so don't complain about
> > lisp.
> 
> I think I understand with respect to Java. I don't with respect to C. Please
> educate me.

For a randomly-written piece of C binary, with "all parts by me"
statically-linked:
head$ ldd wf-server
        libc.so.6 => /lib/libc.so.6 (0x40025000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

If those go, the program doesn't work. In addition it *also* depends
on the OS, so...

//Ingvar
-- 
"I'm in 386 enchanted mode." 
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <XhQTb.83932$U%5.449015@attbi_s03>
Ingvar Mattsson wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
> 
>> Joe Marshall wrote:
> [ SNIP ]
>> > No one writes stand-alone C or Java programs, so don't complain about
>> > lisp.
>> 
>> I think I understand with respect to Java. I don't with respect to C.
>> Please educate me.
> 
> For a randomly-written piece of C binary, with "all parts by me"
> statically-linked:
> head$ ldd wf-server
>         libc.so.6 => /lib/libc.so.6 (0x40025000)
>         /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
> 
> If those go, the program doesn't work. In addition it *also* depends
> on the OS, so...

Yea, well that's a thin line. I mean, if you can count on certain OS libs
always being there, there's little practical difference.

To me, the issue with "stand alone" is simply whether I can create a binary
that looks and launches like a real binary on the OS of interest. Java is
difficult, because you invoke things on Unix, for example, as "java -jar
theprog.jar" rather than "theprog". You can write a launcher that is native
and hides this (cf. the Eclipse launcher, for instance), but it's work. In
terms of whether a program comes delivered as a series of libraries and
other pieces in multiple files, that's really no concern as long as the
user doesn't have to get involved with knowing that. Almost all non-trivial
modern program is, as I think you are pointing out, delivered in multiple
pieces of dynamic libraries, etc.

-- Dave
From: Ingvar Mattsson
Subject: Re: State machine representation
Date: 
Message-ID: <8765eo6qac.fsf@gruk.tech.ensign.ftech.net>
Dave Roberts <·····@re-move.droberts.com> writes:

> Ingvar Mattsson wrote:
> 
> > Dave Roberts <·····@re-move.droberts.com> writes:
[SNIP]
> >> I think I understand with respect to Java. I don't with respect to C.
> >> Please educate me.
> > 
> > For a randomly-written piece of C binary, with "all parts by me"
> > statically-linked:
> > head$ ldd wf-server
> >         libc.so.6 => /lib/libc.so.6 (0x40025000)
> >         /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
> > 
> > If those go, the program doesn't work. In addition it *also* depends
> > on the OS, so...
> 
> Yea, well that's a thin line. I mean, if you can count on certain OS libs
> always being there, there's little practical difference.

In this specific case, I can. However, were I to require (say)
libreadline or libiberty or libgmp or... I'd be out of luck once I
left "linux". Saying that, as things stand at the moment, I am more
comfortabel delivering "applications" as source code and have them
compiled on the other end. Mostly because I (a) am not in the business
of delivering applications and (b) most things I do aren't interesting
enough to actually be downloaded. I can live with that.

Once one goes as far as delivering C++ binaries, the reliance on
"libraries installed on the host" is or, to be honest, at least were)
vastly more interesting. At least a couple of years back, where a
source-built C++ app usually worked, but a "grabbed binary for
royughly the same versions" woked only occasionally.

//Ingvar
-- 
When it doesn't work, it's because you did something wrong.
Try to do it the right way, instead.
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvy8rkdor7.fsf@famine.OCF.Berkeley.EDU>
Ingvar Mattsson <······@cathouse.bofh.se> writes:

> Once one goes as far as delivering C++ binaries, the reliance on
> "libraries installed on the host" is or, to be honest, at least were)
> vastly more interesting. At least a couple of years back, where a
> source-built C++ app usually worked, but a "grabbed binary for
> royughly the same versions" woked only occasionally.

You're talking about Linux here, right?  This wasn't a big problem on
Solaris.  The ABI changed a little, but they kept it to a minimum as
the language changed -- none of that, "It's a new month, we need a new
ABI" crap that afflicted the GNU tools.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Rob Warnock
Subject: Re: State machine representation
Date: 
Message-ID: <7NWdnRNhMr8SUb3dXTWc-g@speakeasy.net>
Thomas F. Burdick <···@famine.OCF.Berkeley.EDU> wrote:
+---------------
| Ingvar Mattsson <······@cathouse.bofh.se> writes:
| > ...vastly more interesting. At least a couple of years back, where a
| > source-built C++ app usually worked, but a "grabbed binary for
| > royughly the same versions" woked only occasionally.
| 
| You're talking about Linux here, right?  This wasn't a big problem on
| Solaris.  The ABI changed a little, but they kept it to a minimum as
| the language changed -- none of that, "It's a new month, we need a new
| ABI" crap that afflicted the GNU tools.
+---------------

FreeBSD tries to maintain backwards-compatibility, too. I just installed
4.9-RELEASE, and they have compatibility libraries you can install to run
binaries built for stuff as far back as FreeBSD 1.x.  This was especially
useful for me since I had some binaries built for FreeBSD 2.2.6 that I
needed to keep working. With the "compat22" libraries installed, they do.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Thomas F. Burdick
Subject: [OT] was: State machine representation
Date: 
Message-ID: <xcvk732d6mf.fsf_-_@famine.OCF.Berkeley.EDU>
····@rpw3.org (Rob Warnock) writes:

> Thomas F. Burdick <···@famine.OCF.Berkeley.EDU> wrote:
> +---------------
> | Ingvar Mattsson <······@cathouse.bofh.se> writes:
> | > ...vastly more interesting. At least a couple of years back, where a
> | > source-built C++ app usually worked, but a "grabbed binary for
> | > royughly the same versions" woked only occasionally.
> | 
> | You're talking about Linux here, right?  This wasn't a big problem on
> | Solaris.  The ABI changed a little, but they kept it to a minimum as
> | the language changed -- none of that, "It's a new month, we need a new
> | ABI" crap that afflicted the GNU tools.
> +---------------
> 
> FreeBSD tries to maintain backwards-compatibility, too. I just installed
> 4.9-RELEASE, and they have compatibility libraries you can install to run
> binaries built for stuff as far back as FreeBSD 1.x.  This was especially
> useful for me since I had some binaries built for FreeBSD 2.2.6 that I
> needed to keep working. With the "compat22" libraries installed, they do.

Nice, I had assumed they were victims of their toolchain, but this
sounds very much in line with FreeBSD in general.  Do the
compatibility libraries cover C++ compatibility?

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Rob Warnock
Subject: Re: [OT] was: State machine representation
Date: 
Message-ID: <8Aydnfj-Y72vyL_dXTWc-g@speakeasy.net>
Thomas F. Burdick <···@famine.OCF.Berkeley.EDU> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) writes:
| > FreeBSD tries to maintain backwards-compatibility, too. I just installed
| > 4.9-RELEASE, and they have compatibility libraries you can install to run
| > binaries built for stuff as far back as FreeBSD 1.x.  This was especially
| > useful for me since I had some binaries built for FreeBSD 2.2.6 that I
| > needed to keep working. With the "compat22" libraries installed, they do.
| 
| Nice, I had assumed they were victims of their toolchain, but this
| sounds very much in line with FreeBSD in general.  Do the
| compatibility libraries cover C++ compatibility?
+---------------

I don't know for sure [not being a big user of C++], but I assume so.
There were versions of "libg++.so.NN" and "libstdc++.so.NN" (for several
values of "NN") in the various "compatXX" libraries, for what that's worth.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: State machine representation
Date: 
Message-ID: <874qu8jq75.fsf@thalassa.informatimago.com>
Dave Roberts <·····@re-move.droberts.com> writes:
> > No one writes stand-alone C or Java programs, so don't complain about
> > lisp.
> 
> I think I understand with respect to Java. I don't with respect to C. Please
> educate me.

$ ldd /bin/ls
        librt.so.1 => /lib/librt.so.1 (0x40016000)
        libacl.so.1 => /lib/libacl.so.1 (0x40029000)
        libc.so.6 => /lib/libc.so.6 (0x4002f000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x40163000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
        libattr.so.1 => /lib/libattr.so.1 (0x401b3000)

Which gives, after resolving the symlinks:

 $ ls -lh /bin/ls /lib/librt.so.1 /lib/libacl.so.1.1.0 /lib/libc.so.6 /lib/libpthread.so.0 /lib/ld-2.3.2.so /lib/libattr.so.1.1.0
-rwxr-xr-x    1 root     root          73K 2003-04-16 16:44 /bin/ls*
-rwxr-xr-x    1 root     root          93K 2003-03-27 21:39 /lib/ld-2.3.2.so*
-rw-r--r--    1 root     root          30K 2003-04-16 16:21 /lib/libacl.so.1.1.0
-rw-r--r--    1 root     root          14K 2003-04-16 16:14 /lib/libattr.so.1.1.0
-rwxr-xr-x    1 root     root         1.5M 2003-03-27 21:39 /lib/libc.so.6*
-rwxr-xr-x    1 root     root          81K 2003-03-27 21:39 /lib/libpthread.so.0*
-rwxr-xr-x    1 root     root          37K 2003-03-27 21:39 /lib/librt.so.1*
----------------------------------------------------------------------------
TOTAL:                                1.7M

So you start  with a 73KB executable, but you  need 1.7MB of libraries
before being able to run a  simple program such as ls. For the smaller
2.9KB of hello-word, you still need 1.5MB of library:


$ ls -lh hw /lib/libc.so.6 /lib/ld-2.3.2.so 
-rwxr-xr-x    1 root     root          93K 2003-03-27 21:39 /lib/ld-2.3.2.so*
-rwxr-xr-x    1 root     root         1.5M 2003-03-27 21:39 /lib/libc.so.6*
-rwx------    1 pascal   regular      2.9K 2004-02-03 13:33 hw*
------------------------------------------------------------------------
TOTAL:                                1.5M


With Lisp, you start with a 1MB executable wich loads a 1MB image, and
a 70KB .fas (well, the clisp executable uses libc too...).


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Coby Beck
Subject: Re: State machine representation
Date: 
Message-ID: <bvmspu$t7g$1@otis.netspace.net.au>
"Joe Marshall" <···@ccs.neu.edu> wrote in message
·················@ccs.neu.edu...
> Dave Roberts <·····@re-move.droberts.com> writes:
> >
> > Anyway, I won't ask that question. Anything else I should steer clear
of?
>
> We like parenthesis.
>
> If you like tail recursion, turn it on.  Most implementations can do
> it.
>
> Some people actually like LOOP.
>
> No one writes stand-alone C or Java programs, so don't complain about
lisp.
>
> Lisp *is* case sensitive, the reader folds case by default, but you
> can change that.
>
> If you want to talk about Scheme, go to comp.lang.scheme
>
> Lisp has been compiled since before you were born.  If not, you are
> old enough to know better.
>
> Lisp is 44 years old.  Name an idea and it's been tried before.
>

Oh yeah, and Lisp is not Dead.
-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Thomas A. Russ
Subject: Re: State machine representation
Date: 
Message-ID: <ymi7jz265b0.fsf@sevak.isi.edu>
Joe Marshall <···@ccs.neu.edu> writes:

> Lisp has been compiled since before you were born.  If not, you are
> old enough to know better.
> 
> Lisp is 44 years old.  Name an idea and it's been tried before.

Omigod, I pre-date lisp.  I guess I could have derived this fact, but I
didn't really put it together before I saw this post.

- Tom

And yes, I do know better :)

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Christopher C. Stacy
Subject: Re: State machine representation
Date: 
Message-ID: <uvfmm1ot9.fsf@news.dtpq.com>
>>>>> On 04 Feb 2004 10:57:39 -0800, Thomas A Russ ("Thomas") writes:

 Thomas> Joe Marshall <···@ccs.neu.edu> writes:
 >> Lisp has been compiled since before you were born.  If not, you are
 >> old enough to know better.
 >> 
 >> Lisp is 44 years old.  Name an idea and it's been tried before.

 Thomas> Omigod, I pre-date lisp.  I guess I could have derived this
 Thomas> fact, but I didn't really put it together before I saw this post.

Well, if you want to get picky, depending on how you count,
you could claim that Lisp is older than that. The research
began in 1956, with the first Lisp implementation starting
in late 1958.  People say 1960 (44 years) due to Lisp 1.5.
From: Henrik Motakef
Subject: Re: State machine representation
Date: 
Message-ID: <x7u126h1no.fsf@crocket.internal.henrik-motakef.de>
···@sevak.isi.edu (Thomas A. Russ) writes:

> > Lisp is 44 years old.  Name an idea and it's been tried before.
> 
> Omigod, I pre-date lisp.

If it helps: You don't look any deader than usual, either.
From: Christopher C. Stacy
Subject: Re: State machine representation
Date: 
Message-ID: <usmhp50c2.fsf@news.dtpq.com>
>>>>> On 05 Feb 2004 00:20:59 +0100, Henrik Motakef ("Henrik") writes:

 Henrik> ···@sevak.isi.edu (Thomas A. Russ) writes:
 >> > Lisp is 44 years old.  Name an idea and it's been tried before.
 >> 
 >> Omigod, I pre-date lisp.

 Henrik> If it helps: You don't look any deader than usual, either.

And most men can generate small executables throughout their life.
From: Kenny Tilton
Subject: Re: State machine representation
Date: 
Message-ID: <xVjTb.170932$4F2.20369178@twister.nyc.rr.com>
Thomas F. Burdick wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Dave Roberts wrote:
>>
>>>Yes, people have sent me the reference, which I appreciate, BTW. My goal
>>>wasn't to inflame here, but it seems I have really stepped on some toes...
>>>;-)
>>
>>It is pretty funny how you have managed to set off just about every land 
>>mine in the joint in your first few questions. If you dig into Google 
>>and read every thread we have seen on namespaces and tail recursion and 
>>CL vs Scheme, when you finish in six months you will understand that... 
>>well, you are lucky to be alive at this point.
>>
>>:)
> 
> 
> To head off the next one: continuations are ...

F*ck! I knew I was missing one hugey (if not five). But continuations 
was definitely the biggest dead horse flogging I missed.

And if we can go OT, gee, how does the OP feel about the GPL?

:)

kt

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Joe Marshall
Subject: Re: State machine representation
Date: 
Message-ID: <r7xd8pni.fsf@ccs.neu.edu>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> To head off the next one: continuations are a bad idea in an
> industrial strength language like CL.  They're not missing, their lack
> is a feature. ;-)

I wouldn't say that they are a *bad idea* per se.  As far as I know,
no implementation of Common Lisp has tried them and discovered that
they cause problems with conforming programs.

On the other hand, a conforming implementation of Common Lisp does not
need (first-class) continuations.
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvfzdtfjj2.fsf@famine.OCF.Berkeley.EDU>
Joe Marshall <···@ccs.neu.edu> writes:

> ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
> 
> > To head off the next one: continuations are a bad idea in an
> > industrial strength language like CL.  They're not missing, their lack
> > is a feature. ;-)
> 
> I wouldn't say that they are a *bad idea* per se.  As far as I know,
> no implementation of Common Lisp has tried them and discovered that
> they cause problems with conforming programs.
> 
> On the other hand, a conforming implementation of Common Lisp does not
> need (first-class) continuations.

Yes, they are a bad idea, unless you don't think UNWIND-PROTECT is
important; see KMP's writings on the subject.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Joe Marshall
Subject: Re: State machine representation
Date: 
Message-ID: <smhtuz8f.fsf@ccs.neu.edu>
···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Joe Marshall <···@ccs.neu.edu> writes:
>
>> ···@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:
>> 
>> > To head off the next one: continuations are a bad idea in an
>> > industrial strength language like CL.  They're not missing, their lack
>> > is a feature. ;-)
>> 
>> I wouldn't say that they are a *bad idea* per se.  As far as I know,
>> no implementation of Common Lisp has tried them and discovered that
>> they cause problems with conforming programs.
>> 
>> On the other hand, a conforming implementation of Common Lisp does not
>> need (first-class) continuations.
>
> Yes, they are a bad idea, unless you don't think UNWIND-PROTECT is
> important; see KMP's writings on the subject.

I'm aware of KMP's writings, but I imagine that you may be unfamiliar
with these papers taken from the Proceedings of the Fourth Workshop on
Scheme and Functional Programming.

``How to Add Threads to a Sequential Language Without Getting Tangled
Up'', Martin Gasbichler, Eric Knauel, Michael Sperber, and Richard
Kelsey 

``Unwind-protect in portable Scheme'',  Dorai Sitaram

The first of these gives a formal denotational semantics of the
interaction between DYNAMIC-WIND and threads.  The second should be
obvious. 
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <pCfTb.204941$xy6.1054186@attbi_s02>
Kenny Tilton wrote:

> 
> 
> Dave Roberts wrote:
>> Yes, people have sent me the reference, which I appreciate, BTW. My goal
>> wasn't to inflame here, but it seems I have really stepped on some
>> toes... ;-)
> 
> It is pretty funny how you have managed to set off just about every land
> mine in the joint in your first few questions. If you dig into Google
> and read every thread we have seen on namespaces and tail recursion and
> CL vs Scheme, when you finish in six months you will understand that...
> well, you are lucky to be alive at this point.
> 
> :)
> 
> kenny
> 

Indeed. So it seems. ;-)

Well, I never was bashful...

Again, thanks to those who have been patient with me. I appreciate your
experience and wisdom.

-- Dave
From: Bulent Murtezaoglu
Subject: Re: State machine representation
Date: 
Message-ID: <87ptcy8q1a.fsf@cubx.internal>
>>>>> "DR" == Dave Roberts <·····@re-move.droberts.com> writes:
    DR> [...] Again, if this is the case, please educate me. It's
    DR> easier to tolerate certain irregularities if there is a good
    DR> reason for them. [...]

I don't know if anyone pointed this out but here's a good reference 
for you to read:

http://www.nhplace.com/kent/Papers/Technical-Issues.html

cheers,

BM
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <hCeTb.161076$nt4.733581@attbi_s51>
Bulent Murtezaoglu wrote:

> I don't know if anyone pointed this out but here's a good reference
> for you to read:
> 
> http://www.nhplace.com/kent/Papers/Technical-Issues.html

I think I found a reference that Pascal Costanza provided to the same paper
on Gabriel's site, rather than Pitman's
(http://www.dreamsongs.com/Separation.html).

Thanks,

-- Dave
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <7ObTb.160436$nt4.730027@attbi_s51>
Kenny Tilton wrote:

>> 1. Just represent state machines simply with an integer or symbol state
>> variable and a case or cond form which switches on the current state. The
>> forms associated with any case/cond clause then determine the next state.
> 
> That's what I have done with some simple machines. Symbols definitely,
> for readability, plus numbers would not work with CASE.

Right. Doesn't seem like it scales as well, however. Lots of top-level
namespace pollution. Probably the most simple way to get it done, however.
For simple programs, this seems like what I would use if I didn't have a
macro language built up to define state machines nicely (my eventual goal).

>> 2. Represent each state with a different function, bound at top-level.
>> The state machine can then be represented as a list or structure, with
>> those functions operating on it.
>> 
>> 3. Represent the state machine with a closure. Basically:
>> (defun make-state-machine ....
>>   (let ((statevar1)
>>         (statevar2)
>>         (current-state))
>>     (flet ((state1 (input) ...)
>>            (state2 (input) ...))
>>       (setq current-state state1)
>>       (lambda (input) (funcall current-state input)))))
> 
> Not bad.

Thanks, I'm learning. I sense that closures are powerful constructs, but I'm
sort of struggling for how/when to use them. Typically, it seems like you
can always get something done another way, and so I struggle with when to
use that tool.

-- Dave
From: Gareth McCaughan
Subject: Re: State machine representation
Date: 
Message-ID: <87hdybc8q0.fsf@g.mccaughan.ntlworld.com>
Dave Roberts <·····@re-move.droberts.com> writes:

> 1. Just represent state machines simply with an integer or symbol state
> variable and a case or cond form which switches on the current state. The
> forms associated with any case/cond clause then determine the next state.
> 
> 2. Represent each state with a different function, bound at top-level. The
> state machine can then be represented as a list or structure, with those
> functions operating on it.

I'm not sure I understand what you mean by this one.

> 3. Represent the state machine with a closure. Basically:
> (defun make-state-machine ....
>   (let ((statevar1)
>         (statevar2)
>         (current-state))
>     (flet ((state1 (input) ...)
>            (state2 (input) ...))
>       (setq current-state state1)
>       (lambda (input) (funcall current-state input)))))
> 
> This is sort of "object-oriented" in the sense that the enclosure
> encapsulates the total state and outsiders can't get into it without the
> state machine itself exposing the state.
> 
> 4. Finally, you could obviously do this with full CLOS objects, with the
> machine being an object and states being represented by either additiona
> CLOS objects or by a combination of variables and functions.
> 
> So, a question for all the Lisp Wizards: What is your favorite technique for
> state machines.

If your Lisp implementation does full tail-call optimization,
then you can modify #3 so that each state calls the next
directly (without the external driver you evidently have).

You could put everything into a tagbody, represent states
by tags, and use GO to change state. Very low-level, but then
a state machine is a pretty low-level construct. Again, this
assumes that each state is responsible for reading input or
whatever else it needs to do.

Another way of using CLOS is to represent the state by a
symbol and make what happens in each state be defined by
a method with an EQL specializer.

    (defmethod process ((state (eql 'waiting-for-packet)) input)
      ...)

    (defmethod process ((state (eql 'in-data-packet)) input)
      ...)

One advantage of this is that if there's some common stuff that
each state needs to do, you can say

    (defmethod process (state input)
      ...)

and then use CALL-NEXT-METHOD, or some sort of non-standard
method combination.

-- 
Gareth McCaughan
.sig under construc
From: Paul Tarvydas
Subject: Re: State machine representation
Date: 
Message-ID: <4YaTb.74925$ef.19287@twister01.bloor.is.net.cable.rogers.com>
In any language, if you want to use state machines as a *serious*
programming construct, you need to consider:

a) entry code - code that is executed when a state is entered

b) exit code - code that is executed when you leave a state

c) transition code - code that is executed when a particular state-to-state
transition is taken

d) hierarchical states - (a la Harel Statecharts) state machines nested
inside of parent states, where transitions into and out of the parent state
are "inherited" by the nested states - for example an "error" or "reset"
transition out of a parent state causes all nested machines to execute
their exit code, deepest first.

The protocol for performing a "step" of a state machine, triggered by an
incoming reactive event is:

1) exit current state

2) determine which particular transition is to be taken, then execute its
transition code

3) enter next state.

(Suitably augmented by considerations for hierarchical states).

None of the suggestions, thus far, have addressed these issues.  For example
"go" is insufficient for performing a transition (since it must perform the
above protocol).  Symbols / case #'s are insufficient because a sate
transition has a least 3 parts.

If I wanted debug-ability, I would implement state machines using defstructs
or clos objects along with a state-walking engine (which would have
state-single-stepping built into it).

If I wanted performance, I would implement a state compiler using lisp
macros (e.g. define defmachine and defstate macros) that unroll the control
flow within a machine into the hoary combination of case's, go's and
name-manglings necessary to efficiently encode the above logic.  

In a language other than lisp, the state compiler would generally be
"outside of" the language, i.e. a separate compiler program which emits
source code in the target language and then is compiled again by the
target-language compiler.  

This demonstrates one of the features of CL - due to a combination of its
regular syntax and its macros, CL has a compiler-compiler (think "Antlr" or
"YACC") built into the language.  [And, just to over-do the analogy, lisp
comes pre-LEX'ed - "symbols" are "tokens".  "LEX" is built into CL via the
reader.]

Great physicists solve a problem by inventing a notation to describe the
problem, first.  Good lispers do the same.

pt
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <VGbTb.160358$nt4.729455@attbi_s51>
Paul Tarvydas wrote:

> In any language, if you want to use state machines as a *serious*
> programming construct, you need to consider:
> 
> a) entry code - code that is executed when a state is entered
> 
> b) exit code - code that is executed when you leave a state
> 
> c) transition code - code that is executed when a particular
> state-to-state transition is taken
> 
> d) hierarchical states - (a la Harel Statecharts) state machines nested
> inside of parent states, where transitions into and out of the parent
> state are "inherited" by the nested states - for example an "error" or
> "reset" transition out of a parent state causes all nested machines to
> execute their exit code, deepest first.
> 
> The protocol for performing a "step" of a state machine, triggered by an
> incoming reactive event is:
> 
> 1) exit current state
> 
> 2) determine which particular transition is to be taken, then execute its
> transition code
> 
> 3) enter next state.
> 
> (Suitably augmented by considerations for hierarchical states).

Right. My plan was to play around with some simple protocol state machines
and then develop a more general macro "language" that implements more fully
general state machines. I figured this would be a good exercise to learn
both the basics of CL and then make my way into non-trivial macros.

> None of the suggestions, thus far, have addressed these issues.  For
> example "go" is insufficient for performing a transition (since it must
> perform the
> above protocol).  Symbols / case #'s are insufficient because a sate
> transition has a least 3 parts.

Depends on how complex your state machines are. If you have a hardware
background, you understand the difference between Mealy and Moore state
machines. Moore state machines associates actions to the entry of states
themselves, while Mealy assigns them to the transitions between states.
Moore state machines are more simply and work well for small problems, but
can lead to state explosion if the machine logic is really complex. The
things you describe above are all nice generalizations of Mealy machines
and further increase flexibility and reduce state explosion. They're nice,
but they aren't *required* to make state machines work.

> If I wanted debug-ability, I would implement state machines using
> defstructs or clos objects along with a state-walking engine (which would
> have state-single-stepping built into it).

Right. That was one of the things I was looking at.

> If I wanted performance, I would implement a state compiler using lisp
> macros (e.g. define defmachine and defstate macros) that unroll the
> control flow within a machine into the hoary combination of case's, go's
> and name-manglings necessary to efficiently encode the above logic.

That was step 2 of my plan. ;-)

> In a language other than lisp, the state compiler would generally be
> "outside of" the language, i.e. a separate compiler program which emits
> source code in the target language and then is compiled again by the
> target-language compiler.
> 
> This demonstrates one of the features of CL - due to a combination of its
> regular syntax and its macros, CL has a compiler-compiler (think "Antlr"
> or
> "YACC") built into the language.  [And, just to over-do the analogy, lisp
> comes pre-LEX'ed - "symbols" are "tokens".  "LEX" is built into CL via the
> reader.]

Yes, exactly. That's one of the reasons for the exercise from my side. I
want to understand this machinery and flexibility in greater detail. I have
done the reading, now I want to flex my mental muscles.

> Great physicists solve a problem by inventing a notation to describe the
> problem, first.  Good lispers do the same.

Yes, exactly. That's precisely what I want to do. I have written state
machines in lots of different languages over the years. In some, the amount
of baggage you need to write to get a maintainable system is large, and the
more maintainable the system is, the slower it typically operates. My goal
is to learn about how I could implement the system in low-level constructs,
then develop a macro language on top of those ideas that allows simple,
maintainable expression, but transformation down to the efficient
representations.

Anyway, this is just a self-imposed exercise for myself to get me to work
through the details. Thanks for the discussion. Your input is spot on.

-- Dave
From: Marco Antoniotti
Subject: Re: State machine representation
Date: 
Message-ID: <tutTb.11$xV.2465@typhoon.nyu.edu>
Paul Tarvydas wrote:
> In any language, if you want to use state machines as a *serious*
> programming construct, you need to consider:
> 
> a) entry code - code that is executed when a state is entered
> 
> b) exit code - code that is executed when you leave a state
> 
> c) transition code - code that is executed when a particular state-to-state
> transition is taken
> 
> d) hierarchical states - (a la Harel Statecharts) state machines nested
> inside of parent states, where transitions into and out of the parent state
> are "inherited" by the nested states - for example an "error" or "reset"
> transition out of a parent state causes all nested machines to execute
> their exit code, deepest first.

If you want this, then you are in for major complications.  Not that 
they are not worth it, but TRT is much farther away than an afternoon 
worth of hacking.

For those so inclined, I point out the Lambda-SHIFT system by Tunc 
Simsek, available at www.gigascale.org.

Cheers

--
Marco
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <YubTb.198532$I06.2191785@attbi_s01>
Gareth McCaughan wrote:

> Dave Roberts <·····@re-move.droberts.com> writes:
>> 2. Represent each state with a different function, bound at top-level.
>> The state machine can then be represented as a list or structure, with
>> those functions operating on it.
> 
> I'm not sure I understand what you mean by this one.

I basically mean what I wrote for number 3, below, but without the closure.
That is, you could just represent states by functions stored in a top-level
variable:

(defun state1 (params) ...)
(defun state2 (params) ...)

(setq current-state #'state1)

Right?

Then you state machine driver simply becomes:

(funcall current-state params)

In each state, they (setq current-state ...) however they need to in order
to move to the next state.

>> 3. Represent the state machine with a closure. Basically:
>> (defun make-state-machine ....
>>   (let ((statevar1)
>>         (statevar2)
>>         (current-state))
>>     (flet ((state1 (input) ...)
>>            (state2 (input) ...))
>>       (setq current-state state1)
>>       (lambda (input) (funcall current-state input)))))
>> 
>> This is sort of "object-oriented" in the sense that the enclosure
>> encapsulates the total state and outsiders can't get into it without the
>> state machine itself exposing the state.
>> 
>> 4. Finally, you could obviously do this with full CLOS objects, with the
>> machine being an object and states being represented by either additiona
>> CLOS objects or by a combination of variables and functions.
>> 
>> So, a question for all the Lisp Wizards: What is your favorite technique
>> for state machines.
> 
> If your Lisp implementation does full tail-call optimization,
> then you can modify #3 so that each state calls the next
> directly (without the external driver you evidently have).

Doesn't CL require this? I know that Scheme does.

> You could put everything into a tagbody, represent states
> by tags, and use GO to change state. Very low-level, but then
> a state machine is a pretty low-level construct. Again, this
> assumes that each state is responsible for reading input or
> whatever else it needs to do.

Interesting. That would work well and is a technique I hadn't thought of
(this is one of the things that I love about Lisp). The downside here is
that it basically consumes the thread during the complete running of the
state machine. I was thinking about something that was more reactive and
event-driven. Also, how efficient is tagbody for large numbers of tags? I
don't know how it's implemented. Worst case, it could be just a linear
search of an association list or something.

> Another way of using CLOS is to represent the state by a
> symbol and make what happens in each state be defined by
> a method with an EQL specializer.

Yea, this is pretty elegant. I assume that this is worse for performance
however, as the more complex you get with your dispatching, the more CLOS
has to work to figure out which method to use, right? I mean, nothing is
free. It's more elegant that simply putting a huge (cond ...) form
somewhere from a maintenance point of view, but basically CLOS has to
execute the functional equivalent of that (cond...) in order to dispatch.
One of the things I like about first-class functions is that you can store
them in variables and simply bypass all the dispatch logic. Very fast, no?

>     (defmethod process ((state (eql 'waiting-for-packet)) input)
>       ...)
> 
>     (defmethod process ((state (eql 'in-data-packet)) input)
>       ...)
> 
> One advantage of this is that if there's some common stuff that
> each state needs to do, you can say
> 
>     (defmethod process (state input)
>       ...)
> 
> and then use CALL-NEXT-METHOD, or some sort of non-standard
> method combination.

Yes. Definitely, of the approaches I looked at, CLOS was the most flexible.
(I have just dipped my toes into CLOS, but it seems like it's a whole other
world there, huge in size, scope, and power. My plan is to get a reasonable
grounding of the basics of "vanilla" CL and then dive into CLOS.)

Thanks for your reply.

-- Dave
From: Harald Hanche-Olsen
Subject: Re: State machine representation
Date: 
Message-ID: <pcowu76o5mf.fsf@thoth.math.ntnu.no>
+ Dave Roberts <·····@re-move.droberts.com>:

| Gareth McCaughan wrote:
| 
| > If your Lisp implementation does full tail-call optimization,
| > then you can modify #3 so that each state calls the next
| > directly (without the external driver you evidently have).
| 
| Doesn't CL require this?

No, among other reasons because it makes debugging harder.  Search for
old messages on this newsgroup for details.  Kent Pitman, in
particular, has written at length on this topic.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <fEeTb.155807$Rc4.1236279@attbi_s54>
Harald Hanche-Olsen wrote:

> + Dave Roberts <·····@re-move.droberts.com>:
> 
> | Gareth McCaughan wrote:
> | 
> | > If your Lisp implementation does full tail-call optimization,
> | > then you can modify #3 so that each state calls the next
> | > directly (without the external driver you evidently have).
> | 
> | Doesn't CL require this?
> 
> No, among other reasons because it makes debugging harder.  Search for
> old messages on this newsgroup for details.  Kent Pitman, in
> particular, has written at length on this topic.
> 

So what does the CL spec say on it, specifically? Is it implementation
dependent? Suggested? Encouraged?

What do most implementations do?

-- Dave
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvoesifmfw.fsf@famine.OCF.Berkeley.EDU>
Dave Roberts <·····@re-move.droberts.com> writes:

> Harald Hanche-Olsen wrote:
> 
> > + Dave Roberts <·····@re-move.droberts.com>:
> > 
> > | Gareth McCaughan wrote:
> > | 
> > | > If your Lisp implementation does full tail-call optimization,
> > | > then you can modify #3 so that each state calls the next
> > | > directly (without the external driver you evidently have).
> > | 
> > | Doesn't CL require this?
> > 
> > No, among other reasons because it makes debugging harder.  Search for
> > old messages on this newsgroup for details.  Kent Pitman, in
> > particular, has written at length on this topic.
> > 
> 
> So what does the CL spec say on it, specifically? Is it implementation
> dependent? Suggested? Encouraged?
> 
> What do most implementations do?

Most implementations support *some* sort of tail call elimination, but
it might be as simple as only self-calls.  You can find out about your
particular implementation, but unless you plan on completely tying
your program to an implementation, you shouldn't count on it.  A
better way is to abstract away the state-changing machinery with a
CHANGE-STATE macro, or something.  You can have it expand to a
funcall, or to something like (throw 'main-loop 'next-state).  If
you're talking about having big state machines, powering the whole app
(as opposed to little, one-off parsers or something), you definately
want to hide the mechanism behind nice high-level declarative macros.

For little one-off machines, I just use go-to.  Specifically PROG,
which sets up some lexical variables, and gives you an implicit
TAGBODY.  Using a loop with tests on a condition variable isn't any
clearer IMO, so I might as well lose the if-then-else ladder that
amounts to interpreting a TAGBODY.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <eBfTb.74976$U%5.410003@attbi_s03>
Thomas F. Burdick wrote:

> Most implementations support *some* sort of tail call elimination, but
> it might be as simple as only self-calls.  You can find out about your
> particular implementation, but unless you plan on completely tying
> your program to an implementation, you shouldn't count on it.  A
> better way is to abstract away the state-changing machinery with a
> CHANGE-STATE macro, or something.  You can have it expand to a
> funcall, or to something like (throw 'main-loop 'next-state).  If
> you're talking about having big state machines, powering the whole app
> (as opposed to little, one-off parsers or something), you definately
> want to hide the mechanism behind nice high-level declarative macros.

Yes, agreed. In fact, that's step 2 of my plan. First, I want to understand
the form those macros will expand to. Then I'm going to write the macros.
The whole thing is a large exercise to force me through the learning
process for a language this sophisticated.

> For little one-off machines, I just use go-to.  Specifically PROG,
> which sets up some lexical variables, and gives you an implicit
> TAGBODY.  Using a loop with tests on a condition variable isn't any
> clearer IMO, so I might as well lose the if-then-else ladder that
> amounts to interpreting a TAGBODY.

Right. For something that can consume a whole thread and whip through the
machine to completion, this style would seem to both be efficient and work
well. The trouble I'm going to have is that my machines are going to be
protocol-level entities, so I need something that won't block in the
machine to get more input. The machine really has to transition to the next
state, then exit so we can go back and do some non-blocking I/O to get the
next batch of input, then enter the machine again and drive it forward one
or more states. Part of the reason this is so is because you could have
multiple such state machines operating simultaneously, each handling a
differnet protocol conenction. The TAGBODY/GO approach seems very nice for
things like lexers, parsers, etc., that can run to completion and then
terminate.

-- Dave
From: Thomas F. Burdick
Subject: Re: State machine representation
Date: 
Message-ID: <xcvisipfjwd.fsf@famine.OCF.Berkeley.EDU>
Dave Roberts <·····@re-move.droberts.com> writes:

> Thomas F. Burdick wrote:
> 
> > Most implementations support *some* sort of tail call elimination, but
> > it might be as simple as only self-calls.  You can find out about your
> > particular implementation, but unless you plan on completely tying
> > your program to an implementation, you shouldn't count on it.  A
> > better way is to abstract away the state-changing machinery with a
> > CHANGE-STATE macro, or something.  You can have it expand to a
> > funcall, or to something like (throw 'main-loop 'next-state).  If
> > you're talking about having big state machines, powering the whole app
> > (as opposed to little, one-off parsers or something), you definately
> > want to hide the mechanism behind nice high-level declarative macros.
> 
> Yes, agreed. In fact, that's step 2 of my plan. First, I want to understand
> the form those macros will expand to. Then I'm going to write the macros.
> The whole thing is a large exercise to force me through the learning
> process for a language this sophisticated.
> 
> > For little one-off machines, I just use go-to.  Specifically PROG,
> > which sets up some lexical variables, and gives you an implicit
> > TAGBODY.  Using a loop with tests on a condition variable isn't any
> > clearer IMO, so I might as well lose the if-then-else ladder that
> > amounts to interpreting a TAGBODY.
> 
> Right. For something that can consume a whole thread and whip through the
> machine to completion, this style would seem to both be efficient and work
> well. The trouble I'm going to have is that my machines are going to be
> protocol-level entities, so I need something that won't block in the
> machine to get more input. The machine really has to transition to the next
> state, then exit so we can go back and do some non-blocking I/O to get the
> next batch of input, then enter the machine again and drive it forward one
> or more states. Part of the reason this is so is because you could have
> multiple such state machines operating simultaneously, each handling a
> differnet protocol conenction. The TAGBODY/GO approach seems very nice for
> things like lexers, parsers, etc., that can run to completion and then
> terminate.

You might want to look at CMUCL's event server architecture:
http://www.pmsf.de/pub/cmucl/doc/cmu-user/serve-event.html

It's pretty easy to build a set of cooperating state machines on top of it.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Harald Hanche-Olsen
Subject: Re: State machine representation
Date: 
Message-ID: <pcoisiqo1rl.fsf@thoth.math.ntnu.no>
+ Dave Roberts <·····@re-move.droberts.com>:

| So what does the CL spec say on it [tail call optimization],
| specifically? Is it implementation dependent? Suggested? Encouraged?

Nothing much, apparently.  You can get the spec for free, you know:
The Common Lisp HyperSpec, available from Xanalys' website or some
such place.  Google for it.  Then you don't have to ask what the spec
says, but can move on to the next level:  "Where in the HyperSpec does
it talk about it?"

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <vvfTb.74940$U%5.410074@attbi_s03>
Harald Hanche-Olsen wrote:

> + Dave Roberts <·····@re-move.droberts.com>:
> 
> | So what does the CL spec say on it [tail call optimization],
> | specifically? Is it implementation dependent? Suggested? Encouraged?
> 
> Nothing much, apparently.  You can get the spec for free, you know:
> The Common Lisp HyperSpec, available from Xanalys' website or some
> such place.  Google for it.  Then you don't have to ask what the spec
> says, but can move on to the next level:  "Where in the HyperSpec does
> it talk about it?"
> 

Right, exactly. I already have the spec. The hard part is now finding things
in it. For a function, that's easy. The index is good. I wasn't sure where
I'd dig this up, however, which is why I asked. Thanks for your help.

-- Dave
From: Joe Marshall
Subject: Re: State machine representation
Date: 
Message-ID: <u12actit.fsf@comcast.net>
Dave Roberts <·····@re-move.droberts.com> writes:

>
> Doesn't CL require [full tail recursion optimization]?
>

No, but most implementations have a means by which you can enable it.


-- 
~jrm
        
From: Gareth McCaughan
Subject: Re: State machine representation
Date: 
Message-ID: <87ekteb7vc.fsf@g.mccaughan.ntlworld.com>
Dave Roberts wrote:

> Gareth McCaughan wrote:
> 
> > Dave Roberts <·····@re-move.droberts.com> writes:
> >> 2. Represent each state with a different function, bound at top-level.
> >> The state machine can then be represented as a list or structure, with
> >> those functions operating on it.
> > 
> > I'm not sure I understand what you mean by this one.
> 
> I basically mean what I wrote for number 3, below, but without the closure.
> That is, you could just represent states by functions stored in a top-level
> variable:
> 
> (defun state1 (params) ...)
> (defun state2 (params) ...)
> 
> (setq current-state #'state1)
> 
> Right?

Right.

> > If your Lisp implementation does full tail-call optimization,
> > then you can modify #3 so that each state calls the next
> > directly (without the external driver you evidently have).
> 
> Doesn't CL require this? I know that Scheme does.

No, CL doesn't. Some implementations may do it, but I'm
not sure that any implementation *guarantees* to do it.
I don't actually know of any language with such a requirement
(either as standard or for all implementations) other than
Scheme, though it wouldn't surprise me to learn that there
are others.

> > You could put everything into a tagbody, represent states
> > by tags, and use GO to change state. Very low-level, but then
> > a state machine is a pretty low-level construct. Again, this
> > assumes that each state is responsible for reading input or
> > whatever else it needs to do.
> 
> Interesting. That would work well and is a technique I hadn't thought of
> (this is one of the things that I love about Lisp). The downside here is
> that it basically consumes the thread during the complete running of the
> state machine. I was thinking about something that was more reactive and
> event-driven. Also, how efficient is tagbody for large numbers of tags? I
> don't know how it's implemented. Worst case, it could be just a linear
> search of an association list or something.

The *compiler* may have to do a linear search, but I'd be
astonished if the compiled code had anything of the kind
left in it. Each GO will probably end up as a single jump
instruction.

> > Another way of using CLOS is to represent the state by a
> > symbol and make what happens in each state be defined by
> > a method with an EQL specializer.
> 
> Yea, this is pretty elegant. I assume that this is worse for performance
> however, as the more complex you get with your dispatching, the more CLOS
> has to work to figure out which method to use, right? I mean, nothing is
> free. It's more elegant that simply putting a huge (cond ...) form
> somewhere from a maintenance point of view, but basically CLOS has to
> execute the functional equivalent of that (cond...) in order to dispatch.
> One of the things I like about first-class functions is that you can store
> them in variables and simply bypass all the dispatch logic. Very fast, no?

Yes, it is likely to be faster than using EQL specializers
in CLOS.

> Yes. Definitely, of the approaches I looked at, CLOS was the most flexible.
> (I have just dipped my toes into CLOS, but it seems like it's a whole other
> world there, huge in size, scope, and power. My plan is to get a reasonable
> grounding of the basics of "vanilla" CL and then dive into CLOS.)

CLOS is amazing. Your plan is a reasonable one.

-- 
Gareth McCaughan
.sig under construc
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: State machine representation
Date: 
Message-ID: <pan.2004.02.06.13.27.53.86269@knm.org.pl>
On Sun, 01 Feb 2004 11:58:15 +0000, Gareth McCaughan wrote:

> You could put everything into a tagbody, represent states
> by tags, and use GO to change state.

Doesn't the target of GO need to be known at compile time?

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Jens Axel Søgaard
Subject: Re: State machine representation
Date: 
Message-ID: <401cddcd$0$201$edfadb0f@dread12.news.tele.dk>
Dave Roberts wrote:

> So, a question for all the Lisp Wizards: What is your favorite technique for
> state machines.

I hope you will find Shriram Krishnamurthi's "The Swine before the Perl"
interesting.

     <http://ll1.ai.mit.edu/>

-- 
Jens Axel S�gaard
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <wJbTb.156878$sv6.865126@attbi_s52>
Jens Axel Søgaard wrote:

> Dave Roberts wrote:
> 
>> So, a question for all the Lisp Wizards: What is your favorite technique
>> for state machines.
> 
> I hope you will find Shriram Krishnamurthi's "The Swine before the Perl"
> interesting.
> 
>      <http://ll1.ai.mit.edu/>
> 

Excellent, I'll have a look. Actually, just about all the various
presentations at that conference look interesting. Thanks for the link.

-- Dave
From: Tayssir John Gabbour
Subject: Re: State machine representation
Date: 
Message-ID: <866764be.0402030453.3a5b667@posting.google.com>
Jens Axel S�gaard <······@jasoegaard.dk> wrote in message news:<·······················@dread12.news.tele.dk>...
> Dave Roberts wrote:
> 
> > So, a question for all the Lisp Wizards: What is your favorite technique for
> > state machines.
> 
> I hope you will find Shriram Krishnamurthi's "The Swine before the Perl"
> interesting.
> 
>      <http://ll1.ai.mit.edu/>

The audio's at:
http://technetcast.ddj.com/tnc_play_stream.html?stream_id=644

The site's really slow right now; I've got a copy if anyone wants me
to ftp or scp it.  He's a very good lecturer.
From: Jens Axel Søgaard
Subject: Re: State machine representation
Date: 
Message-ID: <401fc54e$0$256$edfadb0f@dread12.news.tele.dk>
Tayssir John Gabbour wrote:
> Jens Axel S�gaard <······@jasoegaard.dk> wrote in message news:<·······················@dread12.news.tele.dk>...
>>Dave Roberts wrote:

>>>So, a question for all the Lisp Wizards: What is your favorite technique for
>>>state machines.

>>I hope you will find Shriram Krishnamurthi's "The Swine before the Perl"
>>interesting.
>>
>>     <http://ll1.ai.mit.edu/>

> The audio's at:
> http://technetcast.ddj.com/tnc_play_stream.html?stream_id=644
> 
> The site's really slow right now; I've got a copy if anyone wants me
> to ftp or scp it.  He's a very good lecturer.

I would like a copy. I can't even start the download from technetcast at the moment.

-- 
Jens Axel S�gaard
From: Tayssir John Gabbour
Subject: Re: State machine representation
Date: 
Message-ID: <866764be.0402031027.339a52e7@posting.google.com>
Jens Axel S�gaard <······@jasoegaard.dk> wrote in message news:<·······················@dread12.news.tele.dk>...
> > The audio's at:
> > http://technetcast.ddj.com/tnc_play_stream.html?stream_id=644
> > 
> > The site's really slow right now; I've got a copy if anyone wants me
> > to ftp or scp it.  He's a very good lecturer.
> 
> I would like a copy. I can't even start the download from technetcast at the moment.

DDJ's screwed up -- it should point here:
ftp://ftp.ddj.com/technetcast/mp3/tnc-0644-24.mp3

That site really likes you to go thru contortions; it took me a while
to figure out The True Way to play the Philip Wadler one was to use
the streaming version.
From: rmagere
Subject: Re: State machine representation
Date: 
Message-ID: <bvomah$14i$1@news.ox.ac.uk>
Jens Axel S�gaard wrote:
> I would like a copy. I can't even start the download from technetcast
> at the moment.

Same here.

--
rmagere
From: Paolo Amoroso
Subject: Re: State machine representation
Date: 
Message-ID: <8765erotym.fsf@plato.moon.paoloamoroso.it>
Dave Roberts <·····@re-move.droberts.com> writes:

> So I'm learning CL and trying to write various programs. One thing that I'm
> interested in is communications protocols, so I figured that I'd try some

You may check Etiquette:

  Project page
  http://sourceforge.net/projects/etiquette

  Quickstart guide
  http://sourceforge.net/docman/display_doc.php?docid=17729&group_id=8411


Paolo
-- 
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Edi Weitz
Subject: Re: State machine representation
Date: 
Message-ID: <m33c9uopr7.fsf@bird.agharta.de>
On Sun, 01 Feb 2004 13:38:41 +0100, Paolo Amoroso <·······@mclink.it> wrote:

>   Quickstart guide
>   http://sourceforge.net/docman/display_doc.php?docid=17729&group_id=8411

    <http://sourceforge.net/docman/display_doc.php?docid=17729&group_id=84118>

Edi.
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <KgbTb.154849$Rc4.1223224@attbi_s54>
Paolo Amoroso wrote:

> You may check Etiquette:
> 
>   Project page
>   http://sourceforge.net/projects/etiquette

Yes, I actually found etiquette prior to your message and was checking it
out. I was interested that they used CLOS for most of it. That was actually
one of the things that prompted my question.

-- Dave
        
From: Eugene Zaikonnikov
Subject: Re: State machine representation
Date: 
Message-ID: <680a835d.0402020701.6c6e450f@posting.google.com>
Dave Roberts <·····@re-move.droberts.com> wrote in message news:<························@attbi_s54>...
> Paolo Amoroso wrote:
> 
> > You may check Etiquette:
> > 
> >   Project page
> >   http://sourceforge.net/projects/etiquette
> 
> Yes, I actually found etiquette prior to your message and was checking it
> out. I was interested that they used CLOS for most of it. That was actually
> one of the things that prompted my question.
> 
Notice that Etiquette protocols are procedural and define control flow
for both sides, essentially describing two distinct state machines
(one per role). Hence, the underlying machinery is hardly a typical
approach to state machine implementation. If you want to read more on
implementation of Etiquette, I'd like to refer you to the design
notes: http://cvs.sourceforge.net/viewcvs.py/*checkout*/etiquette/etiquette/design-notes.txt?content-type=text%2Fplain&rev=1.1

One of the reasons why I used CLOS in Etiquette is multiple dispatch.
It appeared to be very convenient to specialize protocol phases and
agent actions on agent's instance and role (for which EQL specializers
came handy) in communication. Another nice thing is that CLOS provides
a framework flexible enough for tweaking and with a number of power
tools and approaches for experimentation: when I started the project I
had a loose vision of which entities should be there, but it was
unclear how the relationships between them could be implemented. In
this particular domain CLOS has made it cheap to experiment.


--
  Eugene
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <JJuTb.166819$nt4.749006@attbi_s51>
Eugene Zaikonnikov wrote:

> Notice that Etiquette protocols are procedural and define control flow
> for both sides, essentially describing two distinct state machines
> (one per role). Hence, the underlying machinery is hardly a typical
> approach to state machine implementation. If you want to read more on
> implementation of Etiquette, I'd like to refer you to the design
> notes:
>
http://cvs.sourceforge.net/viewcvs.py/*checkout*/etiquette/etiquette/design-notes.txt?content-type=text%2Fplain&rev=1.1

I have read the ones that came in the latest distribution. Do these differ
from those? They helped explain a lot.

> One of the reasons why I used CLOS in Etiquette is multiple dispatch.
> It appeared to be very convenient to specialize protocol phases and
> agent actions on agent's instance and role (for which EQL specializers
> came handy) in communication. Another nice thing is that CLOS provides
> a framework flexible enough for tweaking and with a number of power
> tools and approaches for experimentation: when I started the project I
> had a loose vision of which entities should be there, but it was
> unclear how the relationships between them could be implemented. In
> this particular domain CLOS has made it cheap to experiment.

No doubt. As I said in a response elsewhere, CLOS seems very powerful. I'm
still just trying to figure out the basics, though, so my current thought
is to learn how to do it without CLOS and then dive into CLOS as I gain
more understanding. I have this feeling that CLOS will just blow my mind in
terms of what OOP is all about, having spent too long with C++ and Java.
;-)

-- Dave
From: Edi Weitz
Subject: Re: State machine representation
Date: 
Message-ID: <m3znc1qwid.fsf@bird.agharta.de>
On Mon, 02 Feb 2004 16:16:41 GMT, Dave Roberts <·····@re-move.droberts.com> wrote:

> I have this feeling that CLOS will just blow my mind in terms of
> what OOP is all about, having spent too long with C++ and Java.  ;-)

That feeling is right.

Edi.
From: Eugene Zaikonnikov
Subject: Re: State machine representation
Date: 
Message-ID: <680a835d.0402040737.654ac3b0@posting.google.com>
Dave Roberts <·····@re-move.droberts.com> wrote in message news:<·······················@attbi_s51>...
>
> I have read the ones that came in the latest distribution. Do these differ
> from those? They helped explain a lot.
>
Yep, they're the same. The code in CVS has several improvements
though, but they're not reflected yet in the documentation.


--
  Eugene
From: Petter Gustad
Subject: Re: State machine representation
Date: 
Message-ID: <m37jz5vnj8.fsf@scimul.dolphinics.no>
Dave Roberts <·····@re-move.droberts.com> writes:

> So, a question for all the Lisp Wizards: What is your favorite
> technique for state machines.

I'm no wizard, but I'm also a hardware engineer working mostly in
Verilog (and some VHDL). I've find it quite useful to use Common Lisp
to test state machines, generate test patterns, doing simple
synthesis, etc. Here's one example, a JTAG TAP controller:

(defun next-tap-state (current-state tms)
  "return the nest tap controller state"
  (ecase current-state
    (:test-logic-reset
     (if (zerop tms) :run-test-idle  :test-logic-reset))
    (:run-test-idle
     (if (zerop tms) :run-test-idle  :select-dr-scan))
    (:select-dr-scan
     (if (zerop tms) :capture-dr     :select-ir-scan))
    (:capture-dr
     (if (zerop tms) :shift-dr       :exit1-dr))
    (:shift-dr
     (if (zerop tms) :shift-dr       :exit1-dr))
    (:exit1-dr
     (if (zerop tms) :pause-dr       :update-dr))
    (:pause-dr
     (if (zerop tms) :pause-dr       :exit2-dr))
    (:exit2-dr
     (if (zerop tms) :exit2-dr       :update-dr))
    (:update-dr
     (if (zerop tms) :run-test-idle  :select-dr-scan))
    (:select-ir-scan
     (if (zerop tms) :capture-ir     :test-logic-reset))
    (:capture-ir
     (if (zerop tms) :shift-ir       :exit1-ir))
    (:shift-ir
     (if (zerop tms) :shift-ir       :exit1-ir))
    (:exit1-ir
     (if (zerop tms) :pause-ir       :update-ir))
    (:pause-ir
     (if (zerop tms) :pause-ir       :exit2-ir))
    (:exit2-ir
     (if (zerop tms) :exit2-ir       :update-ir))
    (:update-ir
     (if (zerop tms) :run-test-idle  :select-dr-scan))))

You might want to intern the state symbols in a given package rather
than in the keyword package as I've done above.

Quite frequently I find myself using classes to hold the state
information like in:

(defclass jtag-device ()
  ((tap-state :initform :test-logic-reset
              :accessor tap-state)
   (ir        :initform (make-array 4 :element-type 'bit :initial-element 0)
              :initarg :ir
              :accessor ir)
   (dr        :initform 0
              :accessor dr)
   (idcode    :initform (make-array 32 :element-type 'bit :initial-element 0)
              :accessor idcode))
  (:documentation "jtag device state"))


What I enjoy about CL is that it's fairly simple to write functions to
test your code like this which will traverse the state machine to make
sure that there are no dangling next-states which have not been taken
care of:


(defun next-states (fsm state alphabet)
  "return a set of next states when applying the entire alphabet"
  (mapcar 
   #'(lambda (letter) (funcall fsm state letter))
   alphabet))
    

(defun traverse-fsm (fsm to-check traversed alphabet) 
  "returns all terminal states, or nil if unhandled terminal states"
  (if (null to-check) traversed
      (traverse-fsm fsm
                    (union (rest to-check)
                           (set-difference 
                            (next-states fsm (first to-check) alphabet)
                            (cons (first to-check) traversed)))
                    (union (list (first to-check)) traversed)
                    alphabet)))


Then I can verify that I have no dangling next states by starting at
the initial state with the binary alphabet:

(traverse-fsm #'next-tap-state '(:run-test-idle) nil '(0 1))
(:TEST-LOGIC-RESET :UPDATE-IR :UPDATE-DR :EXIT2-IR :EXIT2-DR :PAUSE-IR
 :PAUSE-DR :EXIT1-IR :EXIT1-DR :SHIFT-IR :SHIFT-DR :CAPTURE-IR :CAPTURE-DR
 :SELECT-IR-SCAN :SELECT-DR-SCAN :RUN-TEST-IDLE)


Petter

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
From: Dave Roberts
Subject: Re: State machine representation
Date: 
Message-ID: <kGuTb.161139$Rc4.1262661@attbi_s54>
Petter Gustad wrote:

> (defun next-states (fsm state alphabet)
>   "return a set of next states when applying the entire alphabet"
>   (mapcar
>    #'(lambda (letter) (funcall fsm state letter))
>    alphabet))

That's nice and elegant!

> (traverse-fsm #'next-tap-state '(:run-test-idle) nil '(0 1))
> (:TEST-LOGIC-RESET :UPDATE-IR :UPDATE-DR :EXIT2-IR :EXIT2-DR :PAUSE-IR
>  :PAUSE-DR :EXIT1-IR :EXIT1-DR :SHIFT-IR :SHIFT-DR :CAPTURE-IR :CAPTURE-DR
>  :SELECT-IR-SCAN :SELECT-DR-SCAN :RUN-TEST-IDLE)

Very cool. I never thought about things like this.

-- Dave
From: Alan Crowe
Subject: Re: State machine representation
Date: 
Message-ID: <86wu72plfo.fsf@cawtech.freeserve.co.uk>
(defconstant heat 0)
(defconstant insulate 1)
(defconstant cool 2)

(defconstant hot #(hot hot cold))
(defconstant cold #(hot cold cold))

(defun next (state input)
  (svref (symbol-value state) input))

(reduce (function next)
	  (list cool insulate heat insulate cool)
          :initial-value 'hot)
=> COLD

(let ((raise 0)(hold 1)(lower 2)
	(top #(top top middle))
	(middle #(top middle bottom))
	(bottom #(middle bottom bottom)))
    (declare (special top middle bottom))
    (reduce (function next)
	    (list raise raise lower hold) :initial-value
            'bottom))

=> MIDDLE

Alan Crowe
Edinburgh
Scotland
From: Christian Lynbech
Subject: Re: State machine representation
Date: 
Message-ID: <ofsmhpeo5h.fsf@situla.ted.dk.eu.ericsson.se>
>>>>> "Dave" == Dave Roberts <·····@re-move.droberts.com> writes:

Dave> So I'm learning CL and trying to write various programs. One
Dave> thing that I'm interested in is communications protocols, so I
Dave> figured that I'd try some practice projects in that area. Being
Dave> that I have a hardware engineering background and protocols are
Dave> often designed in terms of state machines, I tend to write
Dave> reactive, event-driven state machine systems frequently.

You may also want to check out the `etiquette' project:

        http://etiquette.sourceforge.net/

This attempts to build a framework in which to specify and try out
protocols. I have not studied it in enough detail to say how well it
works but it sure looks nifty.


------------------------+-----------------------------------------------------
Christian Lynbech       | christian ··@ defun #\. dk
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - ·······@hal.com (Michael A. Petonic)