|
From: Pascal B. <pj...@in...> - 2003-05-07 10:47:41
|
Christophe Rhodes writes:
> Pascal Bourguignon <pj...@in...> writes:
>=20
> > For example compiling the following source gives all these notices=
.
> > Why could not I decide how to build my own data structures? How woul=
d
> > you do it?
> >
> > In particular, what type uncertainty is there in being a
> > (VECTOR (ARRAY BASE-CHAR)) ?
>=20
> There are two kinds of type uncertainty in that type, both of them
> fairly fundamental (i.e. common to all CL implementations).
>=20
> The first is that it is uncertain whether an object of type=20
> (VECTOR (ARRAY BASE-CHAR)) is a SIMPLE-ARRAY or not. Knowing that an
> object is definitely a simple-array can lead to significant
> performance improvements; unfortunately, there is no way of
> expressing, currently, "I am aware that I may pay a price for the
> genericity of having this code work on all vectors, not just simple
> arrays of rank 1". So some implementations shut up about it, others
> don't. (Maybe we should at default compilation settings, I don't
> know).
To see why this behavior is obnoxious, try to compile this:
(defun test-a (stuff)
(declare (type t stuff))
(cond
((simple-vector-p stuff) (aref (the simple-vector stuff) 0))
((vectorp stuff) (aref (the vector stuff) 0))
(t nil)))
It looks like sbcl is incapable of (or at least, can't bear) working
with anything else than simple arrays. =20
Well, why stop here? Since it's much more efficient to do additions
with fixnums, why not issue notices when we use floating point
numbers?
And why not when you use a string (even a simple-string) issue a
notice remembering that it would be much more efficient to avoid those
long arrays and just use fixnums. After all, strings can't be stored
in registers while fixnum can.
It seems to me that the solution is simple: just believe what the
programmer writes!
I could have written: =20
(declare (type (simple-array (simple-array standard-char *) *)) pict)
but since I've written:
(declare (type (array (array character *) *)) pict)
it should mean that it has to accept any kind of array of any kind of
characters.
=20
> The second is significantly worse: since the
> UPGRADED-ARRAY-ELEMENT-TYPE of (ARRAY BASE-CHAR) is T, the declaration
> (VECTOR (ARRAY BASE-CHAR)) means _precisely_ the same as the
> declaration (VECTOR T). In other words, as mandated by ANSI, you can
> store absolutely anything in that vector, not just arrays of type
> BASE-CHAR. Given this, the compiler is unable to infer how to do the
> second dereference [in (AREF (AREF ...) ...)], because the result of
> the first AREF could be anything.
I understand that UPGRADED-ARRAY-ELEMENT-TYPE is implementation
dependant, but why does sbcl upgrade a (ARRAY BASE-CHAR) to T and not
to (ARRAY BASE-CHAR) ?
Is there a declaration I could add to specify that all the elements of
my array are of type (ARRAY BASE-CHAR) ?
Why can't sbcl infer from:
(DECLARE (TYPE (ARRAY (ARRAY CHARACTER *) *) PICT))
that:
(TYPE (ARRAY CHARACTER *) (AREF PICT Y))
(ok, you just said it above, but it seems that the meekest C compiler
is able to do that...).
Would adding THE (ARRAY CHARACTER *) in the right places do?
(SETF (AREF (THE (ARRAY CHARACTER *) (AREF PICT Y)) X) FOREGROUND)
;; etc
From the above test-a, I don't feel that this would improve the
situation. Besides, that seems to be a lot of low-level details to me.
> As an aside: this leads me to suspect that a better implementation
> of a PICTURE might be as a two dimensional array?
Probably. Two reasons that let me to use an array of array are:
- since it's an ascii-art framework, it's quite text line oriented
and it could be nice to be able to consider it as an array of lines=
.
- one of the targets does not support multidimensional arrays.
In anycase, thank you for your explaining.
--=20
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.
|