From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mij45$j99@web.nmti.com>
In article <············@masala.cc.uh.edu>,
········@bayou.uh.edu <········@Bayou.UH.EDU> wrote:
> It's nice to know that you've kept enough of a handle on this thread
> to supply a specific reference, yet it's depressing to know that you
> haven't kept enough of a handle on this thread to know what I've
> been talking about all along.

That's just it. The message you were responding to wasn't talking about a
generalized "C" pointer, but a more restricted construct that's very much
closer to half a lisp "cons" cell than anything in "C".

If you're not talking about with this more limited and safer pointer, then
there's nothing much to talk about. Do let me know.

> Arbitrary structures of these _LISTS_ are nothing more than _LISTS_ of
> _LISTS_.

No, they're not. They're general directed graphs, of which a list is a
specific case. You can use RPLACA and RPLACD to build circular structures
that can't be expressed in list notation:

(set 'a '(a b))
(rplacd a a)

(well, you can't express that in list notation in finite time)

> Again there is no resemblence to the traditional pointer --
> we don't allocate to it,

(set 'a '(a b))

Yes, the memory allocation is implicit, not explicit. And you don't need to
explicitly deallocate it.

> we don't use any stupid dereferencing
> symbols, etc...

(car a)

This is an issue of syntax, not semantics. You could write a macro that
converted "*a" into "(car a)" or "(cdr a)".

> When you can show me an example of Lisp code that dereferences
> pointers ala C or Pascal then I'll believe you, until then,
> you have proven nothing.

See above.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.

From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3073895616785722@naggum.no>
* Peter da Silva
| That's just it. The message you were responding to wasn't talking about a
| generalized "C" pointer, but a more restricted construct that's very much
| closer to half a lisp "cons" cell than anything in "C".

I fail to understand what "half a lisp `cons' cell" even means.  most (but
not all) Lisp objects would be represented by a pointer if you wrote it in
C.  a cons cell _contains_ two such Lisp objects.  there's nothing magic
about the cons cell at all.  the magic, if any, is in any variable or slot
that holds a Lisp object that requires a "pointer" to it in C terminology.

| If you're not talking about with this more limited and safer pointer,
| then there's nothing much to talk about. Do let me know.
| 
| > Arbitrary structures of these _LISTS_ are nothing more than _LISTS_ of
| > _LISTS_.
| 
| No, they're not. They're general directed graphs, of which a list is a
| specific case. You can use RPLACA and RPLACD to build circular structures
| that can't be expressed in list notation:
| 
| (set 'a '(a b))
| (rplacd a a)
| 
| (well, you can't express that in list notation in finite time)

sigh.  Peter, get yourself out of the 60's Lisp and play with a 90's Lisp
system.  you have nothing to lose but your chains.

user(1): (setq *print-circle* t)
t
user(2): (setq a (cons 'a 'b))
(a . b)
user(3): (setf (cdr a) a)
#1=(a . #1#)

| > Again there is no resemblence to the traditional pointer --
| > we don't allocate to it,
| 
| (set 'a '(a b))
| 
| Yes, the memory allocation is implicit, not explicit. And you don't need
| to explicitly deallocate it.

the allocation here occurs at read-time, not run-time.  a compiler is free
to pre-allocate (quoted) constants in read-only memory and share them with
all its users.  your `rplacd' above is a violation of this freedom.

if you want a non-constant list, you allocate and initialize memory for it
(in C terms) with `cons' or `list'.  since you cannot de-couple 

BTW, `set' is deprecated.  (set x y) == (setf (symbol-value x) y), which is
only meaningful for special (dynamic) variables, not lexical variables,
since the latter are not stored in the value slot of symbols.  (yes, Lisp
has lexical variables.  what a concept!)  use `setq' or `setf', instead.

| (car a)
| 
| This is an issue of syntax, not semantics. You could write a macro that
| converted "*a" into "(car a)" or "(cdr a)".

I really hope you understand the difference between * and . in (*bar).car
even though they come rolled up in a single -> as in bar->car, which is
what (car bar) would be doing.

| > When you can show me an example of Lisp code that dereferences pointers
| > ala C or Pascal then I'll believe you, until then, you have proven
| > nothing.
| 
| See above.

you have proven nothing, Peter.  (if I were less generous, I could point
out that you _have_ proven something, but I'll let it pass for now. :)

#\Erik
-- 
if we work harder, will obsolescence be farther ahead or closer?
From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mk1nt$ha9@web.nmti.com>
Eric, I'm not calling you names or demeaning your intelligence just because
I'm getting frustrated with your insistence on complicating the issue. I'd
really appreciate it if you could be similarly polite. Thanks.

Anyway, I'd just like to point out, again, that I'm not talking about any
implementation of lisp or the details of what a compiler can or can not do...
I'm looking at the semantics of the underlying language. For example:

In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
> the allocation here occurs at read-time, not run-time.

The distinction between "read time" and "run time" is an implementation detail,
it's just an optimization. Compilation is just an optimization.

It doesn't effect language semantics at all, and I could certainly construct
an expression that didn't allow you to perform that optimization.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3073917026458422@naggum.no>
* Peter da Silva
| Eric, I'm not calling you names or demeaning your intelligence just
| because I'm getting frustrated with your insistence on complicating the
| issue. I'd really appreciate it if you could be similarly polite. Thanks.

Peter, you're being grossly unfair.  I'm not calling you names, and I'm not
demeaning your intelligence.  I'm showing you that you lack the knowledge
prerequisite to making the claims you try to make.

you're trying to say, as far as I understand, and please correct me if I'm
wrong, that the Lisp family has a pointer concept just like C has, except
that Lisp pointers cannot be manipulated in the same ways in C and Lisp.
still, I gather that you contend, the "pointer" concept is equally valid
for both C and Lisp.

however, I offer a rebuttal to this claim that the pointer is an
implementation issue because is not specified in the language what it
should be like.  in Lisp, it is not even available to the programmer,
although an implementation would necessarily need to use some machine
representation that pointers in C would also use.  I contend that you
cannot make a pointer to an existing object in Lisp except by copying an
existing pointer, but that you can in C.  I contend that you cannot avoid
dereferencing a pointer i Lisp, but that you can in C.  these differences
are very, very important to understand.

| Anyway, I'd just like to point out, again, that I'm not talking about any
| implementation of lisp or the details of what a compiler can or can not
| do...

but you _are_!  the only way your argument could be valid was if we peek
under the proverbial hood of both C and Lisp and look at machine
representation of their respective programmer-level concepts and find that,
lo and behold, there are machine words that contain what must be machine
addresses under _both_ hoods.  I maintain that this is entirely irrelevant
to the _language_ discussions.

| I'm looking at the semantics of the underlying language. For example:
| 
| In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
| > the allocation here occurs at read-time, not run-time.
| 
| The distinction between "read time" and "run time" is an implementation
| detail, it's just an optimization. Compilation is just an optimization.

the semantics of the Common Lisp language is in fact that modifying a
quoted constant is undefined precisely _because_ a number of what you call
"optimizations" _shall_ be possible.  the problem I'm trying to communicate
to you is that _you_ are abusing an implementation detail when you modify a
quoted constant -- namely that such action actually has a meaning, when in
the language specification it has not.

to be specific, since you seem to know C and not Lisp at all, a C compiler
is allowed to store constant strings in read-only memory and coalesce all
string constants.  _therefore_, a portable C program cannot modify a string
constant.  via the wonders of the `const' keyword and the un-const-ing
casting operator, it is impossible for the compiler to complain, and
through the tradition of C run-time systems, it is customary for a running
program to do what you asked, and _not_ trap this violation of the language
semantics.  if it works, _that_ is an implementation detail.

| It doesn't effect language semantics at all, and I could certainly
| construct an expression that didn't allow you to perform that
| optimization.

I wish you would be less disrespectful, Peter.  I'm trying to tell you
something that you don't know.  I'm really trying to be factual all the
time, but instead of trying to listen, you react by thinking I'm calling
you names and demeaning your intelligence.  now, if you don't want to
accept new information to update the clearly very obsolete version you
carry around with you, feel free, but say so, and don't blame _me_ for it!

#\Erik
-- 
a software manager is a person who, upon reports of the existence of
icebergs, launches a major operation to remove the tip, yet refuses to
listen to experts who say that when the tip is removed, the rest of the
iceberg will float up.  such a manager was in charge on the Titanic.
From: Johann Hibschman
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mkr0a$gc8@agate.berkeley.edu>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:

>you're trying to say, as far as I understand, and please correct me if I'm
>wrong, that the Lisp family has a pointer concept just like C has, except
>that Lisp pointers cannot be manipulated in the same ways in C and Lisp.
>still, I gather that you contend, the "pointer" concept is equally valid
>for both C and Lisp.
>
>however, I offer a rebuttal to this claim that the pointer is an
>implementation issue because is not specified in the language what it
>should be like.  in Lisp, it is not even available to the programmer,
>although an implementation would necessarily need to use some machine
>representation that pointers in C would also use.  I contend that you
>cannot make a pointer to an existing object in Lisp except by copying an
>existing pointer, but that you can in C.  I contend that you cannot avoid
>dereferencing a pointer i Lisp, but that you can in C.  these differences
>are very, very important to understand.

Sorry to interrupt this little debate, but I'm getting a little confused.
I just want to inject a few examples to make sure I know what you guys
are driving at.

I don't know Common Lisp, but a pointer-like action in Scheme would be:

(define a (vector 1 2 3 4 5))
(define b a)
(vector-set! b 2 10)
a
=> #(1 2 10 4 5)

I suppose this is "copying an existing pointer", right?  Object identity
is preserved across function calls, so this would take care of the C
use of pointers to do pass-by-reference.

As someone else pointed out, in C you could make a pointer to the third
item in an array, but you can't in Scheme, AFAIK.  Can you do this in
Common Lisp?

i.e.:
(define c (vector-ref a 2))
(set! c 3)
a
=> #(1 2 10 4 5)

This is because I "cannot avoid dereferencing a pointer," so the
item returned by vector-ref lost its pointer nature automatically.
(Same for lists and car, cadr, etc.)  However, I can do:

(define d (list 1 2 3 4 5))
(define e (cddr d))
(set-car! e 10)
d
=> (1 2 10 4 5)

This returns the cons-cell, which still has the "pointer nature."

So in Scheme at least, it seems like the only big problem is vectors,
since most other data structures are built up out of cons-cells which
can be used like pointers. (AFAIK, I just bought SICP two weeks
ago, and I'm only 3/4 of the way through it)

i.e. I can make endless loops with
(define (make-loop lst)
  (define (last-cell lst)
    (if (null? (cdr lst)) lst (last-cell (cdr lst))))
  (set-cdr! (last-cell lst) lst))

So are vectors the only things for which Scheme cons cells can't be used
as "C pointers minus the arithmetic" or am I still missing something?

Thanks,

- Johann

-- 
Johann A. Hibschman         | Grad student in Physics, working in Astronomy.
······@physics.berkeley.edu | Probing pulsar pair production processes.
From: Erik Naggum
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <3073934556898504@naggum.no>
* Johann Hibschman
| I just want to inject a few examples to make sure I know what you guys
| are driving at.

your examples are good.

| I don't know Common Lisp, but a pointer-like action in Scheme would be:
| 
| (define a (vector 1 2 3 4 5))
| (define b a)
| (vector-set! b 2 10)
| a
| => #(1 2 10 4 5)
| 
| I suppose this is "copying an existing pointer", right?

right.  you can't take the address of an existing object to create a new
pointer.  an object and the pointer to it are inseperable.  in C, you can
view them as distinct.

| As someone else pointed out, in C you could make a pointer to the third
| item in an array, but you can't in Scheme, AFAIK.  Can you do this in
| Common Lisp?

in Lisp, you can't make a pointer into an array just like that.  in C you
can, since you can have an object and a pointer to it as distinct types.
Lisp vectors are frequently optimized for certain types, such that you can
store 32-bit integers in vector slots even though the rest of the type
system allows only 30-bit fixnums, or you can store floating-point values
directly without boxing.  also, a Lisp array knows its dimensions and their
sizes.  various other features are available, too.  it would be necessary
to keep track of such things in a "pointer" into an array.

Common Lisp does offer a way to "point" into an array, through arrays
displaced to other arrays.

(setq foo (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9)))
=> #(0 1 2 3 4 5 6 7 8 9)
(setq bar (make-array 1 :displaced-to foo :displaced-index-offset 5))
=> #(5)
(setf (aref bar 0) nil)
=> nil
bar
=> #(nil)
foo
=> #(0 1 2 3 4 nil 6 7 8 9)

clearly, this is not the trivial thing it is in C, where vectors are just
blocks of contiguous memory and a pointer to a particular object can just
be incremented to point to the next few bytes of the memory.  I don't think
it would be recommended practice to use displaced arrays like a "pointer",
but one could use `adjust-array' to modify an existing "pointer" object.

| So in Scheme at least, it seems like the only big problem is vectors,
| since most other data structures are built up out of cons-cells which
| can be used like pointers.

actually, very few of the other data structures in a Lisp system are
list-like.  most are indeed vector-like, since it is much more efficient
for structures of fixed size to be represented as contiguous blocks of
memory with named slots with direct accessors than the pointer-chasing in
lists.  in fact, the cons cell itself is just such a vector-like structure.

#\Erik
-- 
a software manager is a person who, upon reports of the existence of
icebergs, launches a major operation to remove the tip, yet refuses to
listen to experts who say that when the tip is removed, some more of the
iceberg will float up.  such a manager was in charge on the Titanic.
From: Joe English
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5mnrm5$861@crl2.crl.com>
Johann Hibschman <······@physics20.berkeley.edu> wrote:
> [...]
>
>So are vectors the only things for which Scheme cons cells can't be used
>as "C pointers minus the arithmetic" or am I still missing something?

You can use Scheme pairs (cons cells) as Pascal/Ada/SML-style pointers,
but C-style pointers (even minus arithmetic) have an additional operation
"address-of" which produces a "pointer to T" from _any_ lvalue of type T.
This can't be implemented or emulated in Scheme.


--Joe English

  ········@crl.com
From: Brian Rogoff
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <Pine.SGI.3.95.970602120601.3210A-100000@shellx.best.com>
On 30 May 1997, Joe English wrote:
> Johann Hibschman <······@physics20.berkeley.edu> wrote:
> > [...]
> >
> >So are vectors the only things for which Scheme cons cells can't be used
> >as "C pointers minus the arithmetic" or am I still missing something?
> 
> You can use Scheme pairs (cons cells) as Pascal/Ada/SML-style pointers,
> but C-style pointers (even minus arithmetic) have an additional operation
> "address-of" which produces a "pointer to T" from _any_ lvalue of type T.
> This can't be implemented or emulated in Scheme.

	Actually, Ada 95 style "pointers" (called "access types" ) have the 
same capabilities you describe C pointers as having, the difference is 
that you have to declare the type T as being "aliased", and the access 
type as being a general one, so

	int i = 5;
	int *p_i = &i;

could be written as 

	type Integer_Access is access all Integer;
	I : aliased Integer := 5;
	P_I :  Integer_Access := I'Access;

-- Brian
From: Peter da Silva
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <5ml86u$58p@web.nmti.com>
In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
> you're trying to say, as far as I understand, and please correct me if I'm
> wrong, that the Lisp family has a pointer concept just like C has, except
> that Lisp pointers cannot be manipulated in the same ways in C and Lisp.
> still, I gather that you contend, the "pointer" concept is equally valid
> for both C and Lisp.

No. I'm saying that there exists a language object that I'm calling a
pointer. It can be described as an opaque reference to another language
object.

In "classic lisp", the role of this object is served by the components of
a CONS cell. It is also served by other objects in modern Lisp, but to
illustrate my point I've been trying to stick to one specific example of
a pointer... and the one I chose is convenient because it's common to
every variant of lisp I know of except Tcl and LOGO.

In C as described by the ANSI standard, this object has the property
that if you use it to refer to an object in an ordered collection, you
can perform operations on it to create references to other objects in
this collection, and you can determine the relationships between objects
in that collection.

This is the property of pointers in "de jure" C that is not shared by
the analogous constructs in lisp.

Of course in "de facto" C a "pointer" is no longer opaque. It's a memory
address (except in a few cases like Burroughs C).

What you're referring to as a pointer, near as I can tell, is this latter
construct. To me that's two steps removed from what I'm talking about.

> I contend that you
> cannot make a pointer to an existing object in Lisp except by copying an
> existing pointer, but that you can in C.

That's true. That's because of the property of C pointers that I referred to
above.

> I contend that you cannot avoid
> dereferencing a pointer i Lisp, but that you can in C.

You're looking at a different part of the language than I am when discussing
pointers, obviously. If you assign a cell to a symbol or pass it to a function
you are not dereferencing it.

> the semantics of the Common Lisp language is in fact that modifying a
> quoted constant is undefined precisely _because_ a number of what you call
> "optimizations" _shall_ be possible.  the problem I'm trying to communicate
> to you is that _you_ are abusing an implementation detail when you modify a
> quoted constant -- namely that such action actually has a meaning, when in
> the language specification it has not.

Then construct the cons cell that I used in my example some other way than
by quoting it as a constant. Instead of "'(a b)" use "(cons 'a 'b)".

> | It doesn't effect language semantics at all, and I could certainly
> | construct an expression that didn't allow you to perform that
> | optimization.

> I wish you would be less disrespectful, Peter.

What is disrespectful about that? I used a simple example to illustrate a
point.  You pointed out that my example was too simple. My response... then
construct an example where these optimization considerations don't get in
the way.

I listened to your point, accepted it, but that doesn't mean I have to
then discard mine... because it doesn't change what I'm trying to express.
It doesn't *matter* that lisp in 1997 is more complex than lisp in 1987
or 1977, the structure that I'm discussing has remained the same for
longer than that.

A list is still built out of dotted pairs (S Expressions, CONS cells).

And a dotted pair still serves the role of a pair of opaque references
to language objects. It is not a container, it is a reference. A container
can not contain itself.

And an opaque reference to a language object is still a pointer.

You're reading way too much into this. It's not a declaration of war. It's
not an attack on lisp. Honest.
-- 
The Reverend Peter da Silva, ULC, COQO, BOFH, 3D0G, KIBO, POPE Ziggy Wotzit II.
Har du kramat din varg, idag? `-_-'                                Kulanu Kibo.
Hail Eris! All Hail Discordia!                                 Vi er alle Kibo.
HEIL KIBO! HEIL KIBO! HEIL KIBO!                            Wir sind alle Kibo.
From: Chris Bitmead uid(x22068)
Subject: Re: C++ briar patch (Was: Object IDs are bad)
Date: 
Message-ID: <s6yk9kdmoiu.fsf@aalh02.alcatel.com.au>
·····@nmti.com (Peter da Silva) writes:

> In article <················@naggum.no>, Erik Naggum  <····@naggum.no> wrote:
> > you're trying to say, as far as I understand, and please correct me if I'm
> > wrong, that the Lisp family has a pointer concept just like C has, except
> > that Lisp pointers cannot be manipulated in the same ways in C and Lisp.
> > still, I gather that you contend, the "pointer" concept is equally valid
> > for both C and Lisp.
> 
> No. I'm saying that there exists a language object that I'm calling a
> pointer. It can be described as an opaque reference to another language
> object.

This discussion is a bit silly, but anyway...

I think the point is that Lisp "pointers" are not "language objects"
at all. Unlike C pointers, you can't have a pointer to a pointer. They
have no methods attached to them. For all intents and purposes they
don't exist.

It's a bit of a semantic issue really. In my mind Lisp has pointers
because you can have more than one place pointing at the same
object. But because these so-called pointers are not "objects" in the
same way as they are in C, I can see the argument that Lisp doesn't
have pointers.