[comp.lang.misc] Re^4: Some things that pointer-less languages can't do efficiently

kend@data.UUCP (Ken Dickey) (10/23/90)

peter@ficc.ferranti.com (Peter da Silva) writes:

>In article <415@data.UUCP> kend@data.UUCP (Ken Dickey) writes:
>> There are a number of programming languages, Scheme and ML among them,
>> which do not have a pointer abstraction.

>The *only* abstractions in scheme are a pair of pointers or a value.

Gee, I thought there was this constructor CONS which takes two values.
It has 2 accessors, CAR and CDR, which return the 1st and 2nd value
respectively.  It can be implemented in a number of ways including:

 (define (CONS the-car the-cdr)
   (define (self message)
     (case message
      ((CAR) the-car)
      ((CDR) the-cdr)
      (else (error "CONS: unknown operation" message))
  ))
  self ; a new cons object
)

(define (CAR a-cons) (a-cons 'CAR))
(define (CDR a-cons) (a-cons 'CDR))

(define x (cons 1 2))
(car x) --> 1
(cdr x) --> 2

Will you please show me the pointer "abstraction" here?  How do I
dereference the pointer to get a value?

>And you accidentally return (cdr list) instead of list,

If I accidently do (car (+ 2 "a" (cons a b))) I am in bad shape too!
But it has been a long time since I did a (car '()).  I don't have to
dereference store addresses to sort a list.  I don't care if the
implementation does "cdr-coding" (lists implemented as arrays) or not.
I use the abstract accessor and let the implementation do a
dereference if it needs to.

> you have all the
>problems as you do in C when you return a pointer to the middle of the
>array. Oh, sure, the *symptoms* are different, but when you have an
>object (a C pointer, or a dotted pair) that can point to any arbitrary
>place in any non-atomic language object (a string, or a list) you have the
>exact same problem.

How, exactly, does this add something called a POINTER, which I
DEREFERENCE to get a value, into the language?  I can easily add a BOX
abstraction which I can have multiple references to, and do the "call
by reference" types of things.  This is not part of the language
standard.

It is true that there are pointers all through typical implementatons
of Scheme, but there is no "pointer" in the definition of the language!


-Ken Dickey			kend@data.uucp

[We can get into C bashing off-line as a seperate topic if you like,
it is really too embarrasingly easy to do in public]

kend@data.UUCP (Ken Dickey) (10/23/90)

peter@ficc.ferranti.com (Peter da Silva) writes:

>In article <415@data.UUCP> kend@data.UUCP (Ken Dickey) writes:
>> There are a number of programming languages, Scheme and ML among them,
>> which do not have a pointer abstraction.

>The *only* abstractions in scheme are a pair of pointers or a value.

No closures, strings, arrays, numbers??  Gosh Batman, they were there
the last time I looked.

Gee, I thought there was this constructor CONS which takes two values.
It has 2 accessors, CAR and CDR, which return the 1st and 2nd value
respectively.  It can be implemented in a number of ways including:

 (define (CONS the-car the-cdr)
   (define (self message)
     (case message
      ((CAR) the-car)
      ((CDR) the-cdr)
      (else (error "CONS: unknown operation" message))
  ))
  self ; a new cons object
)

(define (CAR a-cons) (a-cons 'CAR))
(define (CDR a-cons) (a-cons 'CDR))

(define x (cons 1 2))
(car x) --> 1
(cdr x) --> 2

Will you please show me the pointer "abstraction" here?  How do I
dereference the pointer to get a value?

>And you accidentally return (cdr list) instead of list,

If I accidently do (car (+ 2 "a" (cons a b))) I am in bad shape too!
But it has been a long time since I did a (car '()).  I don't have to
dereference store addresses to sort a list.  I don't care if the
implementation does "cdr-coding" (lists implemented as arrays) or not.
I use the abstract accessor and let the implementation do a
dereference if it needs to.

> you have all the
>problems as you do in C when you return a pointer to the middle of the
>array. Oh, sure, the *symptoms* are different, but when you have an
>object (a C pointer, or a dotted pair) that can point to any arbitrary
>place in any non-atomic language object (a string, or a list) you have the
>exact same problem.

How, exactly, does this add something called a POINTER--which I can
dereference get a bit pattern in the store (memory)--into the
language?  I can easily add a BOX abstraction which I can have
multiple references to, and do the "call by reference" types of
things.  This is not part of the language standard.

It is true that there are pointers all through typical implementatons
of Scheme, but there is no "pointer" in the definition of the language!


-Ken Dickey			kend@data.uucp

[We can get into C bashing off-line as a seperate topic if you like,
it is really too embarrasingly easy to do in public]

peter@ficc.ferranti.com (Peter da Silva) (10/24/90)

First of all... what's a pointer? It's not a machine address. A pointer is
a token that refers to a value, such that it can refer to any value in
the domain of the language, and that more than one such token can refer
to a given value. The operation of getting to the value referred to is
called dereferencing.

In article <418@data.UUCP> kend@data.UUCP (Ken Dickey) writes:
> Gee, I thought there was this constructor CONS which takes two values.

And returns a pair of pointers. It can be implemented by writing down on
a piece of paper the safe-deposit-box-numbers of a safe-deposit-box in
New York City, but it is still functionally a pair of pointers.

> Will you please show me the pointer "abstraction" here?  How do I
> dereference the pointer to get a value?

	(car list)
	(cdr list)

> But it has been a long time since I did a (car '()).

And it's been a long time since I did a *NULL in C, so?

> It is true that there are pointers all through typical implementatons
> of Scheme, but there is no "pointer" in the definition of the language!

This is only a true statement if you think "machine address" when I say
"pointer". There are C implementations that have all the checking that
Lisp or Scheme does, and implement pointers as a pair of "array, offset".
These are *very* handy in debugging, but don't change the language definition
one iota.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

kend@data.UUCP (Ken Dickey) (10/26/90)

Paraphrase of Peter da Silva: "On what statistical evidence are you
bashing pointers as source language constructs?"

"Pointers are the gotos of the 90's" {I forget who said that.  Alan Kay?}

There was a study done at Xerox PARC on large project development that
showed something over half the development time was spent with storage
management issues.  I believe that the development was done in Mesa,
which is why Cedar has automatic storage management (a.k.a. garbage
collection).  I have found similar results in my development work (C,
Pascal, vs. Scheme, Actor).  "Pointers" contribute in no small way to
this problem.  In the Portable Common Runtime System work (also at
PARC), it was found that C presented hardest runtime problems because
of its low level memory model.

[Most projects I am involved in are >500K LOC]


peter@ficc.ferranti.com (Peter da Silva) writes:

>In article <3407.2720318d@cc.helsinki.fi> jpiitulainen@cc.helsinki.fi writes:

ken>> It is a pair of values.  Pointers to values, as separate from values, do
ken>> not exist.

>So, (a) is the same as a?

No, '(a) is the same as (cons 'a '()).

ken>> In Scheme, any
ken>> pair or vector can hold arbitrarily big values---even itself---pointers
ken>> are not needed and there is no such thing as a pointer to an integer.

>Really? As far as aliasing and debugging are concerned (3) is a pointer
>to 3. (well, to 3 and nil)

'(3) is the result of (cons 3 '()) or (cons '3 '()), this is not the
same as three [as defined in C as "int *three = 3;"].


ken>> Pointers (addresses) are usually used in the implementation,

>No, addresses are not what I mean by pointers. The definition of a pointer
>that I am using is "a token that can refer to any language object". The
>operative word is "any".

Ah, the heart of the issue! It would be interesting to do address
arithmetic on a token!  You are definitely going against the
literature here.  I think that you should look up th definition of
"pointer" in a few texts.

By "token" (a syntax concept), I presume you mean "identifier" (a
language concept).  It seems strange to refer to "identifier
references" as "pointers", as they have no immediate runtime
correspondence [e.g. a "variable" may be assigned to only once to a
known value and the compiler may choose to put that value in the code
rather than create a location to hold it].  If you use the term
"object reference" or "descriptor" or "handle" or just "object",
there would be much less confusion here.

It is much more interesting to think of *values*, which may (or may
not) be *named* in various places in a program than to follow all the
values which a name may denote.


?>> The same problems are there, when applicable.  Lists are just chains of
?>> pairs, or pairs who's cdr fields are pairs, and the cdr pair can be a
?>> part of some other list, too.  Thus mutation is dangerous.

>*Exactly*, just as arbitrary pointer operations are dangerous. And for
>exactly the same reasons.

N.b.: this is basically an argument against assignment, not pointers.


-Ken			kend@data.uucp

peter@ficc.ferranti.com (Peter da Silva) (10/27/90)

In article <420@data.UUCP>, kend@data.UUCP (Ken Dickey) writes:
> Paraphrase of Peter da Silva: "On what statistical evidence are you
> bashing pointers as source language constructs?"

> "Pointers are the gotos of the 90's" {I forget who said that.  Alan Kay?}

That's an evocative statement, considering that folks on both sides of
the fence can... with some justice... claim it as their own. But let's
not add a goto war to the current pointer war...

> There was a study done at Xerox PARC on large project development that
> showed something over half the development time was spent with storage
> management issues.

It should also be considered that the big projects done at Xerox during
the '70s are things like Interlisp, Smalltalk, the Star office system,
and other things that would tend to push the limits of storage
management. Not exactly typical problems, and right at the bleeding edge
of technology at the time.

> '(3) is the result of (cons 3 '()) or (cons '3 '()), this is not the
> same as three [as defined in C as "int *three = 3;"].

[ um, that's a type mismatch. Do you mean "int *three = { 3 };"? ]

You're mixing symbols and values. three is a variable of type "pointer
to integer" containing a pointer to an integer cell containing the
value 3. In lisp:

(setq three '(3)).

> Ah, the heart of the issue! It would be interesting to do address
> arithmetic on a token!  You are definitely going against the
> literature here.  I think that you should look up th definition of
> "pointer" in a few texts.

Not all languages with pointers allow arithmetic on them. And you never
need to do arithmetic on a pointer in C... it is merely convenient. This
has nothing to do with the definition of a pointer.

> By "token" (a syntax concept), I presume you mean "identifier" (a
> language concept).

No, I mean a token. An opaque object. The term is used in other contexts
than compiler design... consider its use in networking. The rest of your
paragraph is complete gibberish, I'm afraid, because it's based on a
misconception.

> >*Exactly*, just as arbitrary pointer operations are dangerous. And for
> >exactly the same reasons.

> N.b.: this is basically an argument against assignment, not pointers.

Nonsense. If a value can't be aliased assignment isn't a problem. And all
aliasing problems come down to pointers at the bottom.

What you're arguing about here isn't whether one should have pointers
at all, merely how restricted the operations on pointers should be. And
that's a horse of a different color.

I use C for pragmatic reasons. It's the only language that's powerful
enough for most of the stuff I do that's also widely available and has
a good enough standard library. You just can't *get* good Pascal, Modula,
Smalltalk, what-have-you implementations on most of the machines I have
to work with. I'm not going to claim it's even a very good langauge. But
it's there, and works, everywhere I need it to be. You want to help improve
things... write some compilers and sell them cheaply.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

jeff@aiai.ed.ac.uk (Jeff Dalton) (11/08/90)

In article <83N6E05@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
>First of all... what's a pointer? It's not a machine address. A pointer is
>a token that refers to a value, such that it can refer to any value in
>the domain of the language, and that more than one such token can refer
>to a given value. The operation of getting to the value referred to is
>called dereferencing.

When a language has pointers, this usually means that "pointer" or
"pointer to TYPE" is a kind of value.  Pointers can be assigned to
variables, passed as parameters, etc.

Lisp and Scheme do not have pointers in that sense, unless you regard
*all* values as pointers (modulo certain cases where compiler code may
hold certain values directly).  If you do that, it is often better
(when thinking about Lisp) to factor out the phrase "pointer to" and
regard all objects as being held directly (rather than indirectly, at
the other ends of pointers).  

Aliasing is still possible, because two variables may hold the same
object or hold objects that overlap.  However (modulo displaced arrays
in CL?) different arrays never overlap, and there is no value that can
turn out to be, say, a pointer to the 3rd element of an array.
Whether aliasing is a problem for programmers depends on how, and
how often, they use side effects to modify objects.

Now let's talk about dereferencing.  (CAR X) and (CDR X) dereference
X, in a sense.  They do a deref plus a structure access.  But there
isn't any X in Lisp such that X is a pointer to Y, and no operation
that given a "pointer to Y" will return Y.  So the closest we can come
here is to say "a cons is a pair of pointers".

Some Lisps (eg, ZetaLisp) do have such things.  They are an additional
data type (not present in standard Common Lisp or Scheme, for example)
called (in ZetaLisp) "locatives".  And additional property of locatives,
something otherwise impossible, is that they can point into objects,
such as to the 3rd element of a vector.

In any case, it is important to note that a cons need not be
implemented as a pair of pointers.  In particular, it is possible
to use cdr-coding or an even more compressed form where the cars
are not pointers either.  So the equation between a cons and a
pair of pointers is not a completely straightforward one.

Note that I have not tried to argue that Lisp does or does not have
pointers, only to describe what the actual situation is.  Whether it
counts as having pointers I leave to you.

-- Jeff