From: Sam Steingold
Subject: (upgraded-array-element-type nil)
Date: 
Message-ID: <m3y950wx7i.fsf@loiso.podval.org>
15.1.2.1 Array Upgrading

        if a type Tx is a subtype of another type Ty, then the upgraded
        array element type of Tx must be a subtype of the upgraded array
        element type of Ty

upgraded-array-element-type doc:

        If typespec is bit, the result is type equivalent to bit. If
        typespec is base-char, the result is type equivalent to
        base-char. If typespec is character, the result is type
        equivalent to character.

since type NIL is a subtype of both BASE-CHAR and BIT, then
(UPGRADED-ARRAY-ELEMENT-TYPE NIL) must be a subtype of both
(UPGRADED-ARRAY-ELEMENT-TYPE 'BASE-CHAR) == BASE-CHAR and
(UPGRADED-ARRAY-ELEMENT-TYPE 'BIT) == BIT.
Since BIT and BASE-CHAR are disjoint,
        (UPGRADED-ARRAY-ELEMENT-TYPE NIL) == NIL

Now, what should (MAKE-ARRAY 10 :ELEMENT-TYPE NIL) return?
The element-type of the resulting array must be
(UPGRADED-ARRAY-ELEMENT-TYPE NIL) == NIL, so nothing should
be storable in (and retrievable from) it.

This object would appear to be quite useless, and, little surprise, no
implementation returns NIL for (UPGRADED-ARRAY-ELEMENT-TYPE NIL).

So, is this a genuine bug (as in "unintended consequence of an
unfortunate wording") in the spec?

Or is this reasoning (or Paul Dietz) wrong?

What should (UPGRADED-ARRAY-ELEMENT-TYPE NIL) return?
What about (MAKE-ARRAY 10 :ELEMENT-TYPE NIL)?

thanks!

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
Trespassers will be shot.  Survivors will be prosecuted.

From: Paul F. Dietz
Subject: Lattice entertain you  (was Re: (upgraded-array-element-type nil))
Date: 
Message-ID: <9cydnXjQIc4tqqajXTWcpQ@dls.net>
Sam Steingold wrote:

> So, is this a genuine bug (as in "unintended consequence of an
> unfortunate wording") in the spec?

If you think *that's* odd...

The subtype relationship as defined in the glossary of the ANSI spec
is set theoretic, not the partial relation specified by SUBTYPEP.
So consider this type (which we can define for any natural number y):

    (defun pred-y (x)
        (cond
         ((not (typep x '(integer 0 *))) nil)
	((member x '(0 1)) t)
	(t (turing-machine-number-y-terminates-after-x-steps x))))

Them, the type (satisfies pred-y) is either BIT or contains all
but a finite number of the natural numbers.

So what us (upgraded-array-element-type '(satisfies pred-y))?
We can't expect the Lisp to actually determine if this element
type is a subtype of BIT, since that's undecidable in general.
So (upgraded-array-element-type '(satisfies pred-y)) is going to
have to be some new kind of type that is either type equivalent
to BIT, or to (upgraded-array-element-type '(or bit (integer n *)))
for some n, but we can't simplify it to find out.

I think the spec needed to be written in terms of 'recognizable
subtypes', like those computable by SUBTYPEP.

	Paul
From: Paul F. Dietz
Subject: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <wuWdnVRHz5wZXqajXTWcoA@dls.net>
I've been writing tests involving subtypep on classes.
Is it expected behavior that the results returned by SUBTYPEP
are allowed to change as classes are added?  The particular situation
is when we have classes

(defclass c1 () (a))
(defclass c2 () (b))

and we are looking at the results of (subtypep '(and c1 c2) nil)
before and after performing

(defclass c3 (c1 c2) ())

(That call to subtypep is allowed to return nil nil, of course.)

I also assume that subtypep reflects the current state of the
class hierarchy, not possible future changes.  The fact that
one could define a class inheriting from both c1 and c2 wouldn't
mean that c1 and c2 intersect if that class had not been defined.
Or is that wrong?

	Paul
From: Nils Goesche
Subject: Re: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <87r8asgnch.fsf@darkstar.cartan>
"Paul F. Dietz" <·····@dls.net> writes:

> I've been writing tests involving subtypep on classes.  Is it
> expected behavior that the results returned by SUBTYPEP are
> allowed to change as classes are added?  The particular
> situation is when we have classes
> 
> (defclass c1 () (a))
> (defclass c2 () (b))
> 
> and we are looking at the results of (subtypep '(and c1 c2) nil)
> before and after performing
> 
> (defclass c3 (c1 c2) ())
> 
> (That call to subtypep is allowed to return nil nil, of
> course.)

Actually, it isn't.  The dictionary entry to SUBTYPEP says

# subtypep never returns a second value of nil when both type-1
# and type-2 involve only the names in Figure 4-2, or names of
# types defined by defstruct, define-condition, or defclass, or
# derived types that expand into only those names.

> I also assume that subtypep reflects the current state of the
> class hierarchy, not possible future changes.  The fact that
> one could define a class inheriting from both c1 and c2
> wouldn't mean that c1 and c2 intersect if that class had not
> been defined.  Or is that wrong?

How could it possibly be otherwise?

Regards,
-- 
Nils G�sche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xD26EF2A0
From: Paul F. Dietz
Subject: Re: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <c9idnZ94iZxZWqajXTWc3Q@dls.net>
Nils Goesche wrote:

[...]
>>and we are looking at the results of (subtypep '(and c1 c2) nil)
>>before and after performing
[...]
>>(That call to subtypep is allowed to return nil nil, of
>>course.)

> Actually, it isn't.  The dictionary entry to SUBTYPEP says
> 
> # subtypep never returns a second value of nil when both type-1
> # and type-2 involve only the names in Figure 4-2, or names of
> # types defined by defstruct, define-condition, or defclass, or
> # derived types that expand into only those names.

But the call also involves AND, so it's allowed to fail.

	Paul
From: Paul F. Dietz
Subject: Re: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <c9idnZ54iZyuVaajXTWc3Q@dls.net>
Nils Goesche wrote:

>>I also assume that subtypep reflects the current state of the
>>class hierarchy, not possible future changes.  The fact that
>>one could define a class inheriting from both c1 and c2
>>wouldn't mean that c1 and c2 intersect if that class had not
>>been defined.  Or is that wrong?
> 
> How could it possibly be otherwise?

One could argue that the classes that inherit from both c1
and c2 already 'exist' in some sense, but just haven't been
named yet.  But for other changes (like renaming classes) you're
right.

	Paul
From: Nils Goesche
Subject: Re: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <87isw4gmol.fsf@darkstar.cartan>
"Paul F. Dietz" <·····@dls.net> writes:

> Nils Goesche wrote:

> > Paul Dietz wrote:

> > > I also assume that subtypep reflects the current state of
> > > the class hierarchy, not possible future changes.  The fact
> > > that one could define a class inheriting from both c1 and
> > > c2 wouldn't mean that c1 and c2 intersect if that class had
> > > not been defined.  Or is that wrong?

> > How could it possibly be otherwise?
> 
> One could argue that the classes that inherit from both c1 and
> c2 already 'exist' in some sense, but just haven't been named
> yet.  But for other changes (like renaming classes) you're
> right.

Ok, found something else:

# 4.2.2 Type Relationships

# * Any two distinct classes created by defclass or
# define-condition are disjoint unless they have a common
# subclass or one class is a subclass of the other.

That seems to be a strong argument for the ``changing behavior��.

Regards,
-- 
Nils G�sche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xD26EF2A0
From: Nils Goesche
Subject: Re: SUBTYPEP and changes to the class hierarchy
Date: 
Message-ID: <87n0lggmy0.fsf@darkstar.cartan>
I <···@cartan.de> wrote:

> "Paul F. Dietz" <·····@dls.net> writes:
> 
> > (That call to subtypep is allowed to return nil nil, of
> > course.)
> 
> Actually, it isn't.  The dictionary entry to SUBTYPEP says
> 
> # subtypep never returns a second value of nil when both type-1
> # and type-2 involve only the names in Figure 4-2, or names of
> # types defined by defstruct, define-condition, or defclass, or
> # derived types that expand into only those names.

Waah, forget that.  AND.  Sorry.

Regards,
-- 
Nils G�sche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xD26EF2A0
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwu1fooaa4.fsf@shell01.TheWorld.com>
Sam Steingold <···@gnu.org> writes:

> Now, what should (MAKE-ARRAY 10 :ELEMENT-TYPE NIL) return?

An array that you can neither store into nor read from.

e.g.,

 (array-dimensions (make-array 10 :element-type nil)) => (10)

> The element-type of the resulting array must be
> (UPGRADED-ARRAY-ELEMENT-TYPE NIL) == NIL, so nothing should
> be storable in (and retrievable from) it.

Yes.  Though that doesn't make it useless.  It is still an object.
It can be the value of a variable.  It can have its dimensions asked
about, it can have its fill-pointer asked about, etc.  It can even be
ADJUST-ARRAY'd.  

> This object would appear to be quite useless,

I don't agree.  It may have only rare uses.  But that's not the 
same thing at all.

> and, little surprise, no
> implementation returns NIL for (UPGRADED-ARRAY-ELEMENT-TYPE NIL).

That speaks more to the rareness than the usefulness, except in the sense
of rareness being 'statistical usefulness' (which is not the same at all
as 'usefulness ever').

> So, is this a genuine bug (as in "unintended consequence of an
> unfortunate wording") in the spec?

I personally don't think so.

(I would even be happy, btw, if an array of type NIL allocated 
no backing store, so such arrays could be quite compact. :)

> Or is this reasoning (or Paul Dietz) wrong?
> 
> What should (UPGRADED-ARRAY-ELEMENT-TYPE NIL) return?

NIL   ;IMO

> What about (MAKE-ARRAY 10 :ELEMENT-TYPE NIL)?

#<ARRAY type NIL, 10 elements>    ;IMO
From: Duane Rettig
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <4fzr8ny6s.fsf@beta.franz.com>
[Background: A couple of weeks ago this subject came up at Franz,
due to Paul Dietz's tests, and we discussed it.  We came to the
conclusion that many others did; that arrays of element-type nil
were not very useful at all.  But, since Paul was correct in the
letter of the spec, and for grins, I did implement these beasts
in our next-version lisp.  So of course, don't look for this
behavior in the currently released version of Allegro CL]

Kent M Pitman <······@world.std.com> writes:

> Sam Steingold <···@gnu.org> writes:
> 
> > Now, what should (MAKE-ARRAY 10 :ELEMENT-TYPE NIL) return?
> 
> An array that you can neither store into nor read from.

The only such array which can be printed with *print-array* t
is one of size 0.  I hadn't thought about an array whose elements
are not accessible, but which is otherwise useful.  As it was
before I read your message, my "new implementation" still didn't
conform because it tried to initialize the array-contents (which
is an error for arrays of any size other than zero).  I take your
point below about other uses, though, so I tweaked it once more:

CL-USER(2): (make-array 0 :element-type nil)
#()
CL-USER(3): (type-of *)
(SIMPLE-ARRAY NIL (0))
CL-USER(4): (setq *print-array* nil)
NIL
CL-USER(5): ***
#<Vector @ #x7000010012616e2>
CL-USER(6): (make-array 10 :element-type nil)
#<Vector @ #x700001001262052>
CL-USER(7): (setq *print-array* t)
T
CL-USER(8): **
#(#<Printer Error, obj=#x700001000000db9: Index(s) to array function is/are out of the range of the array.>)
CL-USER(9): (type-of *)
(SIMPLE-ARRAY NIL (10))
CL-USER(10): 

> e.g.,
> 
>  (array-dimensions (make-array 10 :element-type nil)) => (10)
> 
> > The element-type of the resulting array must be
> > (UPGRADED-ARRAY-ELEMENT-TYPE NIL) == NIL, so nothing should
> > be storable in (and retrievable from) it.
> 
> Yes.  Though that doesn't make it useless.  It is still an object.
> It can be the value of a variable.  It can have its dimensions asked
> about, it can have its fill-pointer asked about, etc.  It can even be
> ADJUST-ARRAY'd.  

Good points.

> > This object would appear to be quite useless,
> 
> I don't agree.  It may have only rare uses.  But that's not the 
> same thing at all.
> 
> > and, little surprise, no
> > implementation returns NIL for (UPGRADED-ARRAY-ELEMENT-TYPE NIL).
> 
> That speaks more to the rareness than the usefulness, except in the sense
> of rareness being 'statistical usefulness' (which is not the same at all
> as 'usefulness ever').
> 
> > So, is this a genuine bug (as in "unintended consequence of an
> > unfortunate wording") in the spec?
> 
> I personally don't think so.
> 
> (I would even be happy, btw, if an array of type NIL allocated 
> no backing store, so such arrays could be quite compact. :)
> 
> > Or is this reasoning (or Paul Dietz) wrong?
> > 
> > What should (UPGRADED-ARRAY-ELEMENT-TYPE NIL) return?
> 
> NIL   ;IMO

Yes:

CL-USER(10): (upgraded-array-element-type nil)
NIL
CL-USER(11): 

> > What about (MAKE-ARRAY 10 :ELEMENT-TYPE NIL)?
> 
> #<ARRAY type NIL, 10 elements>    ;IMO

I agree.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Eric Smith
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ceb68bd9.0302010911.6e9c65fc@posting.google.com>
Kent M Pitman <······@world.std.com> wrote in message news:<···············@shell01.TheWorld.com>...

> #<ARRAY type NIL, 10 elements>    ;IMO

Referring to the following sections of the hyperspec:

   15.1.1 Array Elements
   An array contains a set of objects called elements

   4.4 The Types and Classes Dictionary
   Type NIL
   The type nil contains no objects ...
   No object is of type nil. 

It looks like a contradiction that an array could have
10 elements of type nil, if those elements are required
to be objects, and no object can be of type nil.

Thus it might be more correct to require the array to be
empty than to just prevent access to the elements.
From: Duane Rettig
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <4d6mbsvf7.fsf@beta.franz.com>
········@yahoo.com (Eric Smith) writes:

> Kent M Pitman <······@world.std.com> wrote in message news:<···············@shell01.TheWorld.com>...
> 
> > #<ARRAY type NIL, 10 elements>    ;IMO
> 
> Referring to the following sections of the hyperspec:
> 
>    15.1.1 Array Elements
>    An array contains a set of objects called elements
> 
>    4.4 The Types and Classes Dictionary
>    Type NIL
>    The type nil contains no objects ...
>    No object is of type nil. 
> 
> It looks like a contradiction that an array could have
> 10 elements of type nil, if those elements are required
> to be objects, and no object can be of type nil.

To assume anything about the contents of an array, one must
think in terms of access to that array.  However, if aref and
(setf aref) of an array of element-type nil must error (because
the object must satisfy the element-type specification, and
since no objects satisfy type nil, the accessors will always
error), then how can you know if anything is in the array?
(if a tree falls in the desert ...)

> Thus it might be more correct to require the array to be
> empty than to just prevent access to the elements.

That's a possible conclusion, based on your decision on whether
trees falling in the desert without hearers make noise...  But
Kent did make a good point about usefulness, that an array is
not only about its _contents_, but also about its attributes,
including shape and size, regardless of its contents.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Kenny Tilton
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <3E3C3408.7090006@nyc.rr.com>
Duane Rettig wrote:
> Kent did make a good point about usefulness, that an array is
> not only about its _contents_, but also about its attributes,
> including shape and size, regardless of its contents.

I had my doubts about that argument. Is it being suggested that an array 
might have been created purely to encode certain information in the 
meta-information of an array?

Couldn't we just take that programmer out back and shoot them? :)

This reminds me of a reductio ad absurdum argument. At some point 
reasonable logic can lead us outside the bounds of reasonableness. 
Caching info in array meta-info seems too absurd to get us back inside 
those bounds.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Duane Rettig
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <48ywzsnva.fsf@beta.franz.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Duane Rettig wrote:
> > Kent did make a good point about usefulness, that an array is
> > not only about its _contents_, but also about its attributes,
> > including shape and size, regardless of its contents.
> 
> I had my doubts about that argument. Is it being suggested that an
> array might have been created purely to encode certain information in
> the meta-information of an array?

Yes.

> Couldn't we just take that programmer out back and shoot them? :)

Careful; that's what C++ and Java programmers say about us :-)

> This reminds me of a reductio ad absurdum argument. At some point
> reasonable logic can lead us outside the bounds of
> reasonableness. Caching info in array meta-info seems too absurd to
> get us back inside those bounds.

But great discoveries are also made by such absurdities.  Don't
you remember when you were in grammar school, when you were taught
numbers and how to count, and _then_ they asked you to grasp the
concept of _negative_ numbers?  Remember how absurd that obviously
was?  And if that weren't enough, they go on: (I will skip fractions;
being a lover of food, I had _no_ problem with fractions, especially
since I had three siblings, so fractions of a pie were already known):
They next ask you to understand _irrational_ numbers; ones which can't
be respresented with fractions...  but guess what; they're not done,
because they now require you to _imagine_ numbers (because real numbers
aren't enough)...

Every new level is absurd at first, but could open up new doors.

Perhaps an implementation (but not Allegro CL) might take advantage
of the fact that for adjust-array, the consequences are unspecified
if the element-type given is not the same as array being adjusted,
and allows such a mismatch.  So, by extension, you might have a
place-holder array that serves as a forward-reference for the real
one, adjusted-to later...

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Christopher C. Stacy
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <u7kcjadp1.fsf@dtpq.com>
>>>>> On Sat, 01 Feb 2003 20:50:03 GMT, Kenny Tilton ("Kenny") writes:

 Kenny> Duane Rettig wrote:
 >> Kent did make a good point about usefulness, that an array is
 >> not only about its _contents_, but also about its attributes,
 >> including shape and size, regardless of its contents.

 Kenny> I had my doubts about that argument. Is it being suggested that an
 Kenny> array might have been created purely to encode certain information in
 Kenny> the meta-information of an array?

Maybe a program wants to reason about arrays, but not store
data into them.  Maybe that same code sometimes manipulates
arrays that actually do have data contents.   You don't want
the various parts of the code to have to know how to fiddle
around with some pretend object, and you also want the code
to be robust so that if one of these NIL-type arrays should
escape into the part that accesses data, you get an error.
From: Kenny Tilton
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <3E3C8D76.7000002@nyc.rr.com>
Christopher C. Stacy wrote:
>>>>>>On Sat, 01 Feb 2003 20:50:03 GMT, Kenny Tilton ("Kenny") writes:
>>>>>
> 
>  Kenny> Duane Rettig wrote:
>  >> Kent did make a good point about usefulness, that an array is
>  >> not only about its _contents_, but also about its attributes,
>  >> including shape and size, regardless of its contents.
> 
>  Kenny> I had my doubts about that argument. Is it being suggested that an
>  Kenny> array might have been created purely to encode certain information in
>  Kenny> the meta-information of an array?
> 
> Maybe a program wants to reason about arrays, but not store
> data into them.

And for that we need precisely a nil-type array? if we don't give a 
rat's ass about using the array, t-type would be dandy.

>  Maybe that same code sometimes manipulates
> arrays that actually do have data contents.

This code needs refactoring. :)

 >   You don't want
> the various parts of the code to have to know how to fiddle
> around with some pretend object, and you also want the code
> to be robust so that if one of these NIL-type arrays should
> escape into the part that accesses data, you get an error.

Sounds like nil (full-stop) would suffice (as always).

Do you all remember the photo of Rosemary Wood demonstrating how she 
might have accidentally created the 18.5 minute gap in the Oval Office 
tape? Using the phone back there while keeping her foot on the foot 
pedal over there? The extent to which we are stretching the imagination 
to justify nil-type arrays is precisely my point, and the stretch is not 
far sort of Wood's Olympian feat.

:)

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfw7kcjf7ov.fsf@shell01.TheWorld.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Sounds like nil (full-stop) would suffice (as always).
> 
> Do you all remember the photo of Rosemary Wood demonstrating how she
> might have accidentally created the 18.5 minute gap in the Oval Office
> tape? Using the phone back there while keeping her foot on the foot
> pedal over there? The extent to which we are stretching the
> imagination to justify nil-type arrays is precisely my point, and the
> stretch is not far sort of Wood's Olympian feat.

I don't agree.  For me, the issue isn't really type NIL arrays per se,
it's a commitment to supporting degenerate cases in general.  The
whole type NIL is a degenerate case which has limited usefulness but
is important for completeness.  There are program-writing programs
that could quite easily come up with a type NIL, and making this have
to be special-cased would be wrong.  Similar discussions could be had
about whether (AND) and (OR) need support (since T and NIL,
respectively, might work as well).  Or you might ask if (+) and (*)
really need to return 0 and 1, respectively.  We could get read of 0d
arrays, similarly; many people find (aref foo) and (setf (aref foo) 1)
to be very bizarre to look at.  But the language generally tends to
support degenerate cases, which makes the 'algebra' of program
composition work seamlessly.  When you start losing support for that,
bad things happen...

Type NIL does not make sense for value-manipulating situations.  It's
going to be read and write, so we have to exempt that.  And that's the
reason that (MAP NIL ...) has to be a special case; NIL as a result
type is problematic.  But type NIL does make sense in the other cases
mentioned, and the issue isn't "stretching to meet those", it's simply
"making sure we do what is obviously meant in a case that's rare".
From: Rob Warnock
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <A1GdnYhwW-2ClaCjXTWc-w@speakeasy.net>
Kent M Pitman  <······@world.std.com> wrote:
+---------------
| We could get read of 0d arrays, similarly; many people find
| (aref foo) and (setf (aref foo) 1) to be very bizarre to look at.
+---------------

Actually, I pointed to those once when somebody said, "But MzScheme
has boxes!"

	...records with a single mutable field:

	(box v) returns a new box that contains v.
	(unbox box) returns the content of box.
	  For any v, (unbox (box v)) returns v.
	(set-box! box v) sets the content of box to v.
	(box? v) returns #t if v is a box, #f otherwise. 

My retort, "Well, so does CL, so there!"  ;-}

	(defun box (v)
	  (make-array nil :initial-element v))
	(defun unbox (box)
	  (aref box))
	(defun set-box! (box v)
	  (setf (aref box) v))
	(defun box? (v)
	  (and (arrayp v) (zerop (array-rank v))))

[Of course, I really should have used just the car of a cons, but he
was under the odd impression that boxes simply *had* to be smaller
than pairs, so I used something else.  ;-}  ]

But it *is* amusing the first time you see how the above-defined
"boxes" print. [Try (box 123.45) or (box :hello), etc.] Perfectly
reasonable, in retrospect, once one gets over the startlement.


-Rob

-----
Rob Warnock, PP-ASEL-IA		<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rahul Jain
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <87el6qoap6.fsf@localhost.localdomain>
····@rpw3.org (Rob Warnock) writes:

> [Of course, I really should have used just the car of a cons, but he
> was under the odd impression that boxes simply *had* to be smaller
> than pairs, so I used something else.  ;-}  ]

Hmm, cons cells are typically 2 machine words in size. Array headers
would have to be at least one machine word in size and then the array
data must be the same size, so there's no space savings and maybe the
0-dimension arrays are larger in some implementations. There is,
however, a benefit in that there is no other 'place' being allocated and
the class of the object is a bit more representative of how it is used.

--
Rahul Jain
From: Kenny Tilton
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <3E3E2EC2.8030005@nyc.rr.com>
Kent M Pitman wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Sounds like nil (full-stop) would suffice (as always).
>>
>>Do you all remember the photo of Rosemary Wood demonstrating how she
>>might have accidentally created the 18.5 minute gap in the Oval Office
>>tape? Using the phone back there while keeping her foot on the foot
>>pedal over there? The extent to which we are stretching the
>>imagination to justify nil-type arrays is precisely my point, and the
>>stretch is not far sort of Wood's Olympian feat.
> 
> 
> I don't agree.  For me, the issue isn't really type NIL arrays per se,
> it's a commitment to supporting degenerate cases in general.  The
> whole type NIL is a degenerate case which has limited usefulness but
> is important for completeness.

I am definitely down with degenerate cases and completeness. But the 
context was a chain of deduction which proceeded unreasonably from nil 
being a subtype of everything thru upgraded-array-element-type into a 
protest over no implementation returning nil for (u-a-e-t nil), 
commenting along the way on the uselessness of nil-type arrays, and I 
just wanted to scream whoaa!!!

btw, why /is/ nil a subtype of everything else? is that so nils can be 
stored in typed arrays? in which case ACL's answer, t, makes all the 
sense in the world. The OP thought something could be made of base-char 
and bit being disjoint while nil is a subtype of each. Nope.

One /could/ protest nil being the universal subtype, but then I think we 
veer into another Lisp vs Scheme nil-as-false thread.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Paul F. Dietz
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sCydndu0I9yw7qOjXTWc2Q@dls.net>
Kenny Tilton wrote:

> I am definitely down with degenerate cases and completeness. But the 
> context was a chain of deduction which proceeded unreasonably from nil 
> being a subtype of everything thru upgraded-array-element-type into a 
> protest over no implementation returning nil for (u-a-e-t nil), 
> commenting along the way on the uselessness of nil-type arrays, and I 
> just wanted to scream whoaa!!!

Well, if you want an implementation that is compliant with the standard,
it has to comply with the standard.


> btw, why /is/ nil a subtype of everything else?

This follows directly from the definitions of 'subtype' and the fact
that the NIL type is empty.  See the ANSI CL spec.

	Paul
From: Tim Bradshaw
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ey31y2poa8z.fsf@cley.com>
* Kenny Tilton wrote:

> btw, why /is/ nil a subtype of everything else? is that so nils can be
> stored in typed arrays? in which case ACL's answer, t, makes all the
> sense in the world. The OP thought something could be made of
> base-char and bit being disjoint while nil is a subtype of
> each. Nope.

Because you want to have the bottom of the type lattice, as well as
the top.  An equally valid question is `why is T a supertype of
everything else?'.

--tim
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwvg01sbcf.fsf@shell01.TheWorld.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> btw, why /is/ nil a subtype of everything else? is that so nils can be
> stored in typed arrays?

Your question suggests a misunderstanding, which perhaps leads to your
upsetness.

The type NIL does not include the object NIL.

Type NIL is the empty type, having NO elements.  NILs cannot be stored into
typed arrays.  Having type NIL be a subtype of everything else means that
not only can type X be stored in an array typed X, but also nothing else.
That is, it's a no-op.
From: Kenny Tilton
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <3E3EA12F.1090003@nyc.rr.com>
Kent M Pitman wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>btw, why /is/ nil a subtype of everything else? is that so nils can be
>>stored in typed arrays?
> 
> 
> Your question suggests a misunderstanding, which perhaps leads to your
> upsetness.
> 
> The type NIL does not include the object NIL.

I had some trouble here, including starting to think that there was no 
object NIL. (typep nil 'nil) -> nil is a indeed a shocker. Thx for the 
clear-up.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwsmv5clz4.fsf@shell01.TheWorld.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Kent M Pitman wrote:
> > Kenny Tilton <·······@nyc.rr.com> writes:
> >
> >>btw, why /is/ nil a subtype of everything else? is that so nils can be
> >>stored in typed arrays?
> > Your question suggests a misunderstanding, which perhaps leads to
> > your
> > upsetness.
> > The type NIL does not include the object NIL.
> 
> I had some trouble here, including starting to think that there was no
> object NIL. (typep nil 'nil) -> nil is a indeed a shocker. Thx for the
> clear-up.

No problem.

Just for reference:

 * What you may have been confusing this with is:
   (typep nil 'null) => t

 * The type NULL is _not_ a subtype of all types.

Sounds like your problem is cleared up, but for the sake of others who
might have needed more explanation on this last point, about the potential
confusions of the NIL and NULL types:

There can be no object such that (typep x 'nil) returns T, which is
why it creates no problem that type NIL is a subtype of all types.

If you think of types as a set, represented as a list, then the type
NULL is (NIL) and the type BOOLEAN is the type (T NIL) and the type
UNSIGNED-BYTE is the type (0 1 2 3 4 ... 255), and so on, then the
type NIL is ().  Saying that () is a subtype of all integers is the
same as saying that every list of integers is a null-terminated list,
which makes it properly degenerate.  And this makes it clear why some
of us think it should be supported.
From: Tim Bradshaw
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ey3el6pmdrp.fsf@cley.com>
* Kent M Pitman wrote:
> If you think of types as a set, represented as a list, then the type
> NULL is (NIL) and the type BOOLEAN is the type (T NIL) and the type
> UNSIGNED-BYTE is the type (0 1 2 3 4 ... 255), and so on, then the
> type NIL is ().  Saying that () is a subtype of all integers is the
> same as saying that every list of integers is a null-terminated list,
> which makes it properly degenerate.  And this makes it clear why some
> of us think it should be supported.

I think that the type NIL has to exist, because you can construct it
if it doesn't:

   (deftype nil () '(not t))

I'm sure that in terms of set theory you have to have such a type in
the same sense as you need the empty set - you can't reason without it
because all sorts of things lose their base-cases.

--tim
From: Ivan Boldyrev
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <o054hx4ak.ln2@elaleph.borges.uiggm.nsc.ru>
Kent M Pitman <······@world.std.com> writes:

> UNSIGNED-BYTE is the type (0 1 2 3 4 ... 255),

* (typep (expt 2 256) 'unsigned-byte)

T
*

Seems, I bougth 256-bit Celeron by mistake :)


-- 
Ivan Boldyrev                 remove .microsoft.com from my address

                        Today is the first day of the rest of your life.
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwlm0vx2pc.fsf@shell01.TheWorld.com>
Ivan Boldyrev <········@uiggm.nsc.ru.microsoft.com> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > UNSIGNED-BYTE is the type (0 1 2 3 4 ... 255),
> 
> * (typep (expt 2 256) 'unsigned-byte)
> 
> T
> *
> 
> Seems, I bougth 256-bit Celeron by mistake :)

Oops. As Frode corrected me, yeah, you have to use (UNSIGNED-BYTE 8).

Sad, in a way, since I bet serious application would ever use
UNSIGNED-BYTE to mean what it means.  They would surely write
(INTEGER 0 *).  But by contrast the ordinary meaning of byte as
an 8-bit quantity has no denotation.  Oh well.  

Probably I was an advocate of this, long ago, because we used to
work with 7-bit bytes and 9-bit bytes on the 36-bit PDP10, and
other machines are not byte-oriented at all.  Might be my personal 
desire to eschew any notion of 'standard' coming back to haunt me.
I probably wanted to force people to put the byte size.  I guess I
should have suggested that the byte size be required...

Then again, I take solace in having been a champion of base 10 while
many prominent Lispers were insisting that base 8 was better.  I was
pretty sure most programmers would think base 10 canonical...
From: Frode Vatvedt Fjeld
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <2hu1fjkgpe.fsf@vserver.cs.uit.no>
Kent M Pitman <······@world.std.com> writes:

> UNSIGNED-BYTE is the type (0 1 2 3 4 ... 255), and so on, 

As you probably know, that's (unsigned-byte 8). unsigned-byte is the
set (0 1 2 3 ...), i.e (unsigned-byte 0 *).

-- 
Frode Vatvedt Fjeld
From: Gareth McCaughan
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <slrnb5ijpi.1b05.Gareth.McCaughan@g.local>
Kent M Pitman wrote (ages ago -- I've just got round to reading the thread):
>  There can be no object such that (typep x 'nil) returns T, which is
>  why it creates no problem that type NIL is a subtype of all types.
[etc]

Which is as good a place as any to hang a question that's
been puzzling me. In (extended) LOOP, you can specify the
types of variables; some (particularly important?) types
are particularly easy to specify, as e.g.

    (loop for i fixnum upfrom 10 below 100 do ...)

The types that you can specify that easily are:
FIXNUM, FLOAT, T, NIL. I can see why FIXNUM and
I can sort-of see why FLOAT (though, since there's
more than one kind of float, I'd expect more specific
types to be needed to get good optimization); but
why T and NIL, since

  - specifying type T is the same as not specifying
    the type at all (isn't it?)

  - specifying type NIL is always going to be wrong
    (isn't it?)

I suspect I'm missing something obvious here ...

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Paul F. Dietz
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <2v2cnY2IkJ8Q7sSjXTWc3g@dls.net>
Gareth McCaughan wrote:

>   - specifying type NIL is always going to be wrong
>     (isn't it?)
> 
> I suspect I'm missing something obvious here ...


Not if the loop executes zero times?

	Paul
From: Gareth McCaughan
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <slrnb5nil7.1b05.Gareth.McCaughan@g.local>
Paul F. Dietz wrote:
>  Gareth McCaughan wrote:
>  
> >   - specifying type NIL is always going to be wrong
> >     (isn't it?)
> > 
> > I suspect I'm missing something obvious here ...
>  
>  
>  Not if the loop executes zero times?

If you know in advance that the loop is going to execute 0 times
then there's no point in writing it. If you don't, then the
type is going to be wrong. No?

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Paul F. Dietz
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <JaCcnTR4sOVroMGjXTWcqg@dls.net>
Gareth McCaughan wrote:

> If you know in advance that the loop is going to execute 0 times
> then there's no point in writing it. If you don't, then the
> type is going to be wrong. No?

Maybe the loop is macro-generated?

	Paul
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfw3cmbrver.fsf@shell01.TheWorld.com>
"Paul F. Dietz" <·····@dls.net> writes:

> Gareth McCaughan wrote:
> 
> > If you know in advance that the loop is going to execute 0 times
> > then there's no point in writing it. If you don't, then the
> > type is going to be wrong. No?
> 
> Maybe the loop is macro-generated?

And also it may be unreachable.

I'm pretty sure there could be forms that are legal to write but that
are not legal to execute.

  (when nil
    (let ((foo (bar))) 
      (declare (type nil foo))
      foo))

seems like fine code to me, even though 

  (let ((foo (bar))) 
    (declare (type nil foo))
    foo)

does not seem like it would be good to execute.  It might be that whatever
macro generated this would be doing:

  (when ,(if result-type 't 'nil)
    (let ((foo (bar)))
      (declare (type ,result-type foo))
      foo))

That code seems reasonable to me.  Does someone disagree and want to cite
a reason why?
From: Gareth McCaughan
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <slrnb5qbol.1b05.Gareth.McCaughan@g.local>
Kent M Pitman wrote:

[I said, about the way that you can declare a loop variable
to be of type NIL specially concisely]
> > > If you know in advance that the loop is going to execute 0 times
> > > then there's no point in writing it. If you don't, then the
> > > type is going to be wrong. No?

[Paul Dietz:]
> > Maybe the loop is macro-generated?

Sure. Can you explain how that would make it useful to be able
to say (loop for x nil ...) instead of (loop for x of-type nil ...)?
It seems to me that, if there *is* any situation where you'd
want a NIL type in a macro-generated loop, then it would be one
where the type itself was variable, in which case you'd want
to use the full-length OF-TYPE version. The concise forms of
the LOOP variable type annotations are surely there for the
convenience of *humans*.

>  And also it may be unreachable.
>  
>  I'm pretty sure there could be forms that are legal to write but that
>  are not legal to execute.

Certainly.

> does not seem like it would be good to execute.  It might be that whatever
> macro generated this would be doing:
> 
>   (when ,(if result-type 't 'nil)
>     (let ((foo (bar)))
>       (declare (type ,result-type foo))
>       foo))
> 
> That code seems reasonable to me.  Does someone disagree and want to cite
> a reason why?

Not me. But I don't think it explains why two of the four types
you can declare a loop variable to have specially concisely
are T and NIL.

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwd6lenn69.fsf@shell01.TheWorld.com>
Gareth McCaughan <················@pobox.com> writes:

> > does not seem like it would be good to execute.  It might be that whatever
> > macro generated this would be doing:
> > 
> >   (when ,(if result-type 't 'nil)
> >     (let ((foo (bar)))
> >       (declare (type ,result-type foo))
> >       foo))
> > 
> > That code seems reasonable to me.  Does someone disagree and want to cite
> > a reason why?
> 
> Not me. But I don't think it explains why two of the four types
> you can declare a loop variable to have specially concisely
> are T and NIL.

I find myself wondering if the intent had been that supplying NIL here 
meant you had [at the last minute] opted not to supply a type and/or if
it was misclassified and should have been a destructuring pattern.
But I can't find any evidence to support either; my historical 
records are in storage at the moment, so that's as far as I can dig, but
I sent some email to JonL White, who might know.  I'll let you know if
he replies.
From: Gareth McCaughan
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <slrnb5rut2.1b05.Gareth.McCaughan@g.local>
Kent Pitman wrote:

[I said:]
> > Not me. But I don't think it explains why two of the four types
> > you can declare a loop variable to have specially concisely
> > are T and NIL.
>
> I find myself wondering if the intent had been that supplying NIL here 
> meant you had [at the last minute] opted not to supply a type and/or if
> it was misclassified and should have been a destructuring pattern.
> But I can't find any evidence to support either; my historical 
> records are in storage at the moment, so that's as far as I can dig, but
> I sent some email to JonL White, who might know.  I'll let you know if
> he replies.

Thanks! Surely if you decide at the last moment that you don't
want to supply a type, that would mean using T rather than NIL;
I find the presence of T in the list less puzzling than that of
NIL (though still odd). Anyway, thanks in advance if JonL turns
something up...

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Tim Bradshaw
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ey3smubffgm.fsf@cley.com>
* Paul F Dietz wrote:

> Maybe the loop is macro-generated?

Well, whatever generated the type specifier of NIL *knew* that the
loop would not ever be executed.

--tim
From: Frode Vatvedt Fjeld
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <2h4r7kkzu6.fsf@vserver.cs.uit.no>
Kent M Pitman <······@world.std.com> writes:

> The type NIL does not include the object NIL.

But CL does seem to think in general that "no value", that is,
(values), yields NIL. So maybe in the same vein aref of an array
specialized to NIL should return NIL? Or better yet, no values, the
same as (values)?

-- 
Frode Vatvedt Fjeld
From: Kent M Pitman
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <sfwwukggjos.fsf@shell01.TheWorld.com>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> > The type NIL does not include the object NIL.
> 
> But CL does seem to think in general that "no value", that is,
> (values), yields NIL. So maybe in the same vein aref of an array
> specialized to NIL should return NIL? Or better yet, no values, the
> same as (values)?

But (values) does not return an object of type NIL.
It returns no object.

Additional values are conjured, on demand, as if 
 (multiple-value-bind (x y z) (f) ...)
meant
 (multiple-value-call #'(lambda (&optional x y z) ...) (f))

That is, the NIL you see is not a property of what is returned, but of
what is done about the fact that a value was expected when none returned.

AREF does not return multiple values.  It returns precisely one value.

It is a different claim entirely to say that a single value is returned
that is of type NIL (i.e., a single value is returned whose nature is
intrinsically a logical contradiction) than to say a value might or might
not be returned.  The type NIL is not the absence of a value returned, it
is the absence of a suitable value in the set of possible values.  That's
different.

There is no sense in which multiple values ever get involved in type NIL
unless someone has specifically (and orthogonally to the multiple values
mechanism) declared a type NIL return type (i.e., has declared that it's
an error for the function to return).
From: Tim Bradshaw
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ey3n0lentpn.fsf@cley.com>
* Christopher C Stacy wrote:
>>>>>> On Sat, 01 Feb 2003 20:50:03 GMT, Kenny Tilton ("Kenny") writes:

> Maybe a program wants to reason about arrays, but not store
> data into them.  Maybe that same code sometimes manipulates
> arrays that actually do have data contents.   You don't want
> the various parts of the code to have to know how to fiddle
> around with some pretend object, and you also want the code
> to be robust so that if one of these NIL-type arrays should
> escape into the part that accesses data, you get an error.

Yes.  For instance, maybe you have some algorithm which manipulates a
number of arrays, and which checks dimensions &c are compatible, but
for some cases it doesn't actually access one some of these arrays.
You can use one of these magic arrays both to *check* it doesn't, and
to (possibly, if the implementation conveniently does not allocate
storage for the elements of these things) avoid allocation of a large
but unused amount of storage in this case.

--tim
From: Kenny Tilton
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <3E3DC185.5030502@nyc.rr.com>
Tim Bradshaw wrote:
> * Christopher C Stacy wrote:
> 
>>>>>>>On Sat, 01 Feb 2003 20:50:03 GMT, Kenny Tilton ("Kenny") writes:
>>>>>>
> 
>>Maybe a program wants to reason about arrays, but not store
>>data into them.  Maybe that same code sometimes manipulates
>>arrays that actually do have data contents.   You don't want
>>the various parts of the code to have to know how to fiddle
>>around with some pretend object, and you also want the code
>>to be robust so that if one of these NIL-type arrays should
>>escape into the part that accesses data, you get an error.
> 
> 
> Yes.  For instance, maybe you have some algorithm which manipulates a
> number of arrays, and which checks dimensions &c are compatible, but
> for some cases it doesn't actually access one some of these arrays.
> You can use one of these magic arrays both to *check* it doesn't, 

we're writing internal validation which for some reason must never look 
at an array element, and this is so vital we are going to seed a set of 
arrays with nil-type land mines to catch the validation code? So all the 
other code has to skip these land mines?

    http://www.dorsai.org/~walts/rwoods.html


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Tim Bradshaw
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <ey365s1oacm.fsf@cley.com>
* Kenny Tilton wrote:


> we're writing internal validation which for some reason must never
> look at an array element, and this is so vital we are going to seed a
> set of arrays with nil-type land mines to catch the validation code?
> So all the other code has to skip these land mines?

Erm?  I don't think you understand what I was saying.  Imagine a
symbolic array bashing package.  It will need to check things like
dimensions and rank for sanity, but it's not going to look at elements
since they probably can be any type.  Then imagine some algorithm
which, in some particular case, should not touch one of its arguments
other than the routine dimension/rank checking which it does anyway.
By passing it an array of element type NIL, you can know that, if it
*does* touch this array, it will blow up rather than silently
succeeding.

Yes, of course `you could read the source code to know it doesn't
touch the array elements'.  Or in fact `you can read the source code
and fix any bugs before running the program'.

Never mind.

--tim
From: Rahul Jain
Subject: Re: (upgraded-array-element-type nil)
Date: 
Message-ID: <87n0lfohbe.fsf@localhost.localdomain>
Duane Rettig <·····@franz.com> writes:

> To assume anything about the contents of an array, one must
> think in terms of access to that array.  However, if aref and
> (setf aref) of an array of element-type nil must error (because
> the object must satisfy the element-type specification, and
> since no objects satisfy type nil, the accessors will always
> error), then how can you know if anything is in the array?
> (if a tree falls in the desert ...)

Maybe it's useful if you want to create an array which will cause an
error any time it is accessed. It seems to at least have some potential
usefulness if nothing else. (Yeah, I know I said the opposite on IRC
yesterday, but reading this made me notice an obvious and maybe not so
silly use for such objects.)

--
Rahul Jain