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

State machine representation

1,147 views
Skip to first unread message

Dave Roberts

unread,
Feb 1, 2004, 1:53:38 AM2/1/04
to
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

Kenny Tilton

unread,
Feb 1, 2004, 4:07:01 AM2/1/04
to

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

Jens Axel Søgaard

unread,
Feb 1, 2004, 6:04:52 AM2/1/04
to
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

Matthew Danish

unread,
Feb 1, 2004, 6:52:11 AM2/1/04
to
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 <mda...@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."

Gareth McCaughan

unread,
Feb 1, 2004, 6:58:15 AM2/1/04
to
Dave Roberts <ld...@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

Paolo Amoroso

unread,
Feb 1, 2004, 7:38:41 AM2/1/04
to
Dave Roberts <ld...@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

Edi Weitz

unread,
Feb 1, 2004, 9:09:32 AM2/1/04
to

Kenny Tilton

unread,
Feb 1, 2004, 12:18:38 PM2/1/04
to

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

Paul Tarvydas

unread,
Feb 1, 2004, 12:46:40 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 1:08:42 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 1:23:52 PM2/1/04
to
Gareth McCaughan wrote:

> Dave Roberts <ld...@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


Dave Roberts

unread,
Feb 1, 2004, 1:36:37 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 1:39:25 PM2/1/04
to
Jens Axel Søgaard wrote:

Excellent, I'll have a look. Actually, just about all the various
presentations at that conference look interesting. Thanks for the link.

-- Dave

Dave Roberts

unread,
Feb 1, 2004, 1:44:19 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 1:48:43 PM2/1/04
to
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

Matthew Danish

unread,
Feb 1, 2004, 2:14:57 PM2/1/04
to

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.

Dave Roberts

unread,
Feb 1, 2004, 2:37:17 PM2/1/04
to
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

Erik Naggum

unread,
Feb 1, 2004, 2:42:28 PM2/1/04
to
* 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.

Erann Gat

unread,
Feb 1, 2004, 3:18:53 PM2/1/04
to
In article <fSbTb.156975$sv6.865734@attbi_s52>, Dave Roberts
<ld...@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.

Dave Roberts

unread,
Feb 1, 2004, 3:58:44 PM2/1/04
to
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

Bulent Murtezaoglu

unread,
Feb 1, 2004, 4:10:09 PM2/1/04
to
>>>>> "DR" == Dave Roberts <ld...@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

Matthew Danish

unread,
Feb 1, 2004, 4:16:15 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 4:26:09 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 4:38:35 PM2/1/04
to
Erann Gat wrote:

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

Harald Hanche-Olsen

unread,
Feb 1, 2004, 4:24:24 PM2/1/04
to
+ Dave Roberts <ld...@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

Harald Hanche-Olsen

unread,
Feb 1, 2004, 4:46:39 PM2/1/04
to
+ Dave Roberts <ld...@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.

Erik Naggum

unread,
Feb 1, 2004, 4:53:15 PM2/1/04
to
* 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
<2004-032-8...@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.

Dave Roberts

unread,
Feb 1, 2004, 4:54:46 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 4:56:30 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 4:58:35 PM2/1/04
to
Harald Hanche-Olsen wrote:

> + Dave Roberts <ld...@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

Erik Naggum

unread,
Feb 1, 2004, 5:00:16 PM2/1/04
to
* 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?

Matthew Danish

unread,
Feb 1, 2004, 5:13:28 PM2/1/04
to
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.

Dave Roberts

unread,
Feb 1, 2004, 5:22:57 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 5:25:38 PM2/1/04
to
Harald Hanche-Olsen wrote:

> + Dave Roberts <ld...@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

Erik Naggum

unread,
Feb 1, 2004, 5:37:32 PM2/1/04
to
* 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.

Dave Roberts

unread,
Feb 1, 2004, 5:39:16 PM2/1/04
to
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


Joe Marshall

unread,
Feb 1, 2004, 5:39:55 PM2/1/04
to
Dave Roberts <ld...@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

Joe Marshall

unread,
Feb 1, 2004, 5:41:14 PM2/1/04
to
Dave Roberts <ld...@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

Kenny Tilton

unread,
Feb 1, 2004, 5:38:48 PM2/1/04
to

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

Harald Hanche-Olsen

unread,
Feb 1, 2004, 5:33:24 PM2/1/04
to
+ Dave Roberts <ld...@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.

Dave Roberts

unread,
Feb 1, 2004, 5:44:34 PM2/1/04
to
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

Thomas F. Burdick

unread,
Feb 1, 2004, 5:45:55 PM2/1/04
to
Dave Roberts <ld...@re-move.droberts.com> writes:

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! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Thomas F. Burdick

unread,
Feb 1, 2004, 5:50:45 PM2/1/04
to
Kenny Tilton <kti...@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. ;-)

Harald Hanche-Olsen

unread,
Feb 1, 2004, 5:47:42 PM2/1/04
to
+ Dave Roberts <ld...@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?"

Dave Roberts

unread,
Feb 1, 2004, 5:57:31 PM2/1/04
to
Harald Hanche-Olsen wrote:

> + Dave Roberts <ld...@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

Harald Hanche-Olsen

unread,
Feb 1, 2004, 6:03:05 PM2/1/04
to
+ Dave Roberts <ld...@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.)

Dave Roberts

unread,
Feb 1, 2004, 6:03:38 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 6:04:53 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 6:07:28 PM2/1/04
to
Thomas F. Burdick wrote:

> Kenny Tilton <kti...@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

Dave Roberts

unread,
Feb 1, 2004, 6:24:33 PM2/1/04
to
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

Pascal Costanza

unread,
Feb 1, 2004, 6:28:04 PM2/1/04
to

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."

Pascal Costanza

unread,
Feb 1, 2004, 6:32:19 PM2/1/04
to

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.

David Golden

unread,
Feb 1, 2004, 7:03:56 PM2/1/04
to
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.

Dave Roberts

unread,
Feb 1, 2004, 7:11:28 PM2/1/04
to
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

Gareth McCaughan

unread,
Feb 1, 2004, 8:14:15 PM2/1/04
to
Dave Roberts wrote:

> Gareth McCaughan wrote:
>
> > Dave Roberts <ld...@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

Dave Roberts

unread,
Feb 1, 2004, 8:26:14 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 8:28:30 PM2/1/04
to
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

Dave Roberts

unread,
Feb 1, 2004, 8:33:42 PM2/1/04
to
Harald Hanche-Olsen wrote:

> + Dave Roberts <ld...@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

Dave Roberts

unread,
Feb 1, 2004, 8:39:54 PM2/1/04
to
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


Bulent Murtezaoglu

unread,
Feb 1, 2004, 8:50:50 PM2/1/04
to
>>>>> "DR" == Dave Roberts <ld...@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

Gareth McCaughan

unread,
Feb 1, 2004, 8:38:11 PM2/1/04
to
Dave Roberts <ld...@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.)

Kenny Tilton

unread,
Feb 1, 2004, 10:58:21 PM2/1/04
to

Thomas F. Burdick wrote:
> Kenny Tilton <kti...@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

Kenny Tilton

unread,
Feb 1, 2004, 11:01:54 PM2/1/04
to

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

Dave Roberts

unread,
Feb 2, 2004, 12:50:47 AM2/2/04
to
Gareth McCaughan wrote:

> Dave Roberts <ld...@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

Dave Roberts

unread,
Feb 2, 2004, 12:51:20 AM2/2/04
to
Gareth McCaughan wrote:

> Dave Roberts <ld...@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

Dave Roberts

unread,
Feb 2, 2004, 12:52:40 AM2/2/04
to
Bulent Murtezaoglu wrote:

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

Erann Gat

unread,
Feb 2, 2004, 1:13:10 AM2/2/04
to
In article <mjfTb.157861$5V2.827283@attbi_s53>, Dave Roberts
<ld...@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.

Erann Gat

unread,
Feb 2, 2004, 1:25:29 AM2/2/04
to
In article <XylTb.160314$sv6.881667@attbi_s52>, Dave Roberts
<ld...@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.

Alain Picard

unread,
Feb 2, 2004, 2:19:53 AM2/2/04
to
Dave Roberts <ld...@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".


Jens Axel Søgaard

unread,
Feb 2, 2004, 2:37:38 AM2/2/04
to
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

Frode Vatvedt Fjeld

unread,
Feb 2, 2004, 3:48:48 AM2/2/04
to
Dave Roberts <ld...@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

Petter Gustad

unread,
Feb 2, 2004, 4:27:55 AM2/2/04
to
Dave Roberts <ld...@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?

Pascal Costanza

unread,
Feb 2, 2004, 6:03:34 AM2/2/04
to

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.

Marco Antoniotti

unread,
Feb 2, 2004, 9:52:10 AM2/2/04
to

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

Marco Antoniotti

unread,
Feb 2, 2004, 9:58:53 AM2/2/04
to

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


Eugene Zaikonnikov

unread,
Feb 2, 2004, 10:01:17 AM2/2/04
to
Dave Roberts <ld...@re-move.droberts.com> wrote in message news:<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.
>
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

Joe Marshall

unread,
Feb 2, 2004, 10:16:12 AM2/2/04
to
Dave Roberts <ld...@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.

Joe Marshall

unread,
Feb 2, 2004, 10:25:32 AM2/2/04
to
Dave Roberts <ld...@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.

Joe Marshall

unread,
Feb 2, 2004, 10:30:41 AM2/2/04
to
t...@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.

Joe Marshall

unread,
Feb 2, 2004, 11:01:06 AM2/2/04
to
Dave Roberts <ld...@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.

Dave Roberts

unread,
Feb 2, 2004, 11:13:04 AM2/2/04
to
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

Dave Roberts

unread,
Feb 2, 2004, 11:16:41 AM2/2/04
to
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

Edi Weitz

unread,
Feb 2, 2004, 11:25:14 AM2/2/04
to
On Mon, 02 Feb 2004 16:16:41 GMT, Dave Roberts <ld...@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.

Erann Gat

unread,
Feb 2, 2004, 11:45:25 AM2/2/04
to
In article <znc18q...@ccs.neu.edu>, Joe Marshall <j...@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.

Thomas F. Burdick

unread,
Feb 2, 2004, 12:53:06 PM2/2/04
to
Dave Roberts <ld...@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! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Thomas F. Burdick

unread,
Feb 2, 2004, 1:01:05 PM2/2/04
to
Joe Marshall <j...@ccs.neu.edu> writes:

Yes, they are a bad idea, unless you don't think UNWIND-PROTECT is
important; see KMP's writings on the subject.

Joe Marshall

unread,
Feb 2, 2004, 1:03:54 PM2/2/04
to
gNOS...@jpl.nasa.gov (Erann Gat) writes:

> In article <znc18q...@ccs.neu.edu>, Joe Marshall <j...@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.

Joe Marshall

unread,
Feb 2, 2004, 1:12:48 PM2/2/04
to
t...@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

> Joe Marshall <j...@ccs.neu.edu> writes:
>
>> t...@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.

The only true Barbara Schwarz - other postings with my name are forgeries

unread,
Feb 2, 2004, 1:32:09 PM2/2/04
to
Dave Roberts <ld...@re-move.droberts.com> wrote in message news:<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


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
~dst@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

Pascal Bourguignon

unread,
Feb 2, 2004, 1:36:04 PM2/2/04
to
Dave Roberts <ld...@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/

Pascal Bourguignon

unread,
Feb 2, 2004, 1:44:05 PM2/2/04
to
Frode Vatvedt Fjeld <fro...@cs.uit.no> writes:

> Dave Roberts <ld...@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

unread,
Feb 2, 2004, 1:48:11 PM2/2/04
to

Marco Antoniotti <mar...@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...)

Erann Gat

unread,
Feb 2, 2004, 1:32:03 PM2/2/04
to
In article <wu75uz...@ccs.neu.edu>, Joe Marshall <j...@ccs.neu.edu> wrote:

> gNOS...@jpl.nasa.gov (Erann Gat) writes:
>
> > In article <znc18q...@ccs.neu.edu>, Joe Marshall <j...@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.

Erann Gat

unread,
Feb 2, 2004, 1:50:27 PM2/2/04
to
In article <87ptcxmi...@thalassa.informatimago.com>, Pascal
Bourguignon <sp...@thalassa.informatimago.com> wrote:

> Dave Roberts <ld...@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.

Erann Gat

unread,
Feb 2, 2004, 1:53:37 PM2/2/04
to
In article <87llnlm...@thalassa.informatimago.com>, Pascal Bourguignon
<sp...@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.

Joe Marshall

unread,
Feb 2, 2004, 2:33:49 PM2/2/04
to
ARS-is...@myway.com (The only true Barbara Schwarz - other postings with my name are forgeries) writes:

> Dave Roberts <ld...@re-move.droberts.com> wrote in message news:<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
>
>
> 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.

Erik Naggum

unread,
Feb 2, 2004, 2:38:09 PM2/2/04
to
* ARS-is...@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.

Frode Vatvedt Fjeld

unread,
Feb 2, 2004, 2:44:08 PM2/2/04
to
Frode Vatvedt Fjeld <fro...@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 <sp...@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

Joe Marshall

unread,
Feb 2, 2004, 2:47:51 PM2/2/04
to
gNOS...@jpl.nasa.gov (Erann Gat) writes:

> In article <wu75uz...@ccs.neu.edu>, Joe Marshall <j...@ccs.neu.edu> wrote:
>
>> gNOS...@jpl.nasa.gov (Erann Gat) writes:
>>
>> > In article <znc18q...@ccs.neu.edu>, Joe Marshall <j...@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.

Tayssir John Gabbour

unread,
Feb 2, 2004, 2:56:34 PM2/2/04
to
Dave Roberts <ld...@re-move.droberts.com> wrote in message news:<GAeTb.161070$nt4.733919@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.

It is loading more messages.
0 new messages