| Date: Thu, 20 Nov 2003 21:15:43 -0800 (PST)
| From: bear <xxxxxx@sonic.net>
|
| On Thu, 20 Nov 2003, Aubrey Jaffer wrote:
|
| > | Date: Thu, 20 Nov 2003 11:58:30 -0800 (PST)
| > | From: bear <xxxxxx@sonic.net>
| >
| >Uniform arrays are just that -- uniform! If you want to mix exact and
| >inexact numbers in an array, just make its type be vector.
|
| Okay. That's a decision. Good. So let's make it explicit. I have
| three specific suggestions for making that clear in your SRFI.
|
| First, I'd suggest that if you have an inexact number, you can store
| it in a uniform array of inexact numbers, and retrieve an inexact
| number from the location where you stored it. But since there is a
| chance that the number you retrieve won't be equal? to the number you
| stored, this document needs to say so. This doesn't have to be an
| error -- in fact I'm pretty sure it shouldn't be -- but you need to
| say so explicitly.
|
| Second, I'd suggest that if you have an exact number, and an
| exact-number typed array, then any operation involving the array that
| would result in a roundoff, wraparound, or truncation of that number
| or the array contents ought to be an error. You shouldn't be able to
| store an exact number and then retrieve from that location a number
| that's not equal? to the one you stored, nor add two exact numbers
| from an array and get an answer that's not the answer you'd get if you
| added two exact numbers from a vector. In specifying representation
| you are not giving implementors any "wiggle room" to switch to
| different representation in order to give exact results where they are
| otherwise required, so you need to be explicit that operations which
| don't *allow* exact results within the specified representation type
| (overflow, wraparounds, roundoffs, etc) are errors.
|
| Finally, I'd suggest that if you have an inexact number, and you try
| to store it in an array of an exact numeric type, or vice versa, that
| should be an error. If people want automatic type conversions on
| store, they're easy to implement on top of the arrays you've
| specified, any problems they introduce needn't be your fault and
| needn't be behavior users can't get around.
Thanks for the suggestions. Does this specify them:
* All the elements of arrays of type au8, au16, au32, au64, as8,
as16, as32, or as64 are exact.
* All the elements of arrays of type ar32, ar64, ac32, or ac64 are
inexact.
* The value retrieved from an exact array element will equal (=) the
value stored in that element.
* Assigning a non-integer to array-type au8, au16, au32, au64, as8,
as16, as32, or as64 is an error.
* Assigning number larger than can be represented in array-type au8,
au16, au32, au64, as8, as16, as32, or as64 is an error.
* Assigning a negative number to array-type au8, au16, au32, or au64
is an error.
* Assigning an inexact number to array-type au8, au16, au32, au64,
as8, as16, as32, or as64 is an error.
* When assigning an exact number to array-type ar32, ar64, ac32, or
ac64, the procedure may report a violation of an implementation
restriction.
* Assigning a non-real number (eg. real? returns #f) to an ar64 or
ar32 array is an error.
* An implementation may reduce the precision of a number assigned to
an inexact array.
|
| >Two's-complement integers are in widespread use and well understood.
| >The type-checking enforced by uniform-arrays has proven to be a
| >benefit to debugging large-data-set numerical algorithms.
|
| Hmm, that brings up another question -- at the point where it becomes
| useful for the programmer to *know* individual bits of representation
| such as whether the number is represented as twos-complement, you're
| dealing with a hardware interface -- frequently, that means type
| punning based on bit patterns being interpretable as varying numbers
| of different types.
There is no hardware exposed. Inexacts are stored in whatever form
the implementation uses. Exacts are stored twos-complement. The
semantics of twos-complement representation are not
hardware-dependent.
| One thing I haven't seen addressed with make-shared-array is whether
| you're going to allow type punning. IOW, can two arrays of different
| types share storage? Can I have, say, an array of au64's that shares
| space with an array of 8 times as many au8's and with an array of 64
| times as many at1, and manipulate the contents of the au64 array by
| frobbing with its individual bits-n-bytes through the at1 and at8
| interfaces?
Make-shared-array returns an array with the same type as its first
argument.
| That could be very useful for implementing hardware interfaces and
| FFI's, but I don't think the operation is sufficiently described and I
| can't tell for sure here whether it's a functionality you intended to
| provide.
That would expose endianness and data formats. SRFI-47 does not do
that.
| > Assigning a non-integer to array-type u8, u16, u32, u64, s8, s16,
| > s32, or s64 is an error.
|
| > Assigning a negative number to array-type u8, u16, u32, or u64 is an
| > error.
|
| > Assigning a non-real number to a r64 or r32 array is an error.
|
| By non-real, you mean to say, complex or imaginary? Or do you mean to
| say, integral or rational?
No. (real? <number>) ==> #f
| According to R5RS, some real numbers are integers, and some are not
| integers. Some real numbers are exact and some are inexact. So
| for compatibility with the rest of the language, could you please
| describe these specifically as exact and inexact, rather than just
| giving a hardware type? The problem is that in some
| implementations you have such things as exact floats or inexact
| rationals or integers, and people will want to store 'em in your
| typed arrays.
I believe the new restrictions language above does this:
* All the elements of arrays of type au8, au16, au32, au64, as8,
as16, as32, or as64 are exact.
* All the elements of arrays of type ar32, ar64, ac32, or ac64 are
inexact.
| > Uniform arrays don't favor interpreters over compilers, they can just
| > make the performance difference negligible.
|
| I think the same may be said of optional declarations. At least I'm
| not sure why it wouldn't be so.
Declarations enforced by an interpreter add additional overhead; they
go slower.
Thanks for the suggestions.