[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: propose deprecation of generalized-vector-*
From: |
Daniel Llorens |
Subject: |
Re: propose deprecation of generalized-vector-* |
Date: |
Wed, 19 Sep 2012 19:20:49 +0200 |
On Sep 19, 2012, at 18:00, address@hidden wrote:
> Date: Wed, 19 Sep 2012 13:02:25 +0100
> From: Peter TB Brett <address@hidden>
> To: address@hidden
> Subject: Re: propose deprecation of generalized-vector-*
...
> It seems to me that array-length should return the first non-unity
> dimension. This is the approach taken by e.g. MATLAB's length()
> function. It would give it a distinct utility compared to
> array-dimensions (which is analogous to MATLAB's size() function).
>
> WDYT?
>
> Peter
That is not exactly what length() does in Matlab:
> >> help length
> LENGTH Length of vector.
> LENGTH(X) returns the length of vector X. It is equivalent
> to MAX(SIZE(X)) for non-empty arrays and 0 for empty ones.
The notion of rank in Matlab is rather sui generis. There are no rank 1 objects
as such, only row or column vectors. Even size(0) gives [1 1]. So there's
constant confusion when you want a simple vector X, because Matlab gives you a
column or a row and you need to know which one you've got, even though the
things you want to do with X don't depend on that at all. That leads to
superfluous use of (:) and .' .
The above definition of length() is meant to paper over the row/column
distinction. Octave says:
> octave:1> help length
> `length' is a built-in function
>
> -- Built-in Function: length (A)
> Return the `length' of the object A. For matrix objects, the
> length is the number of rows or columns, whichever is greater (this
> odd definition is used for compatibility with MATLAB).
Guile is strict about rank, so this problem doesn't exist. Wouldn't you agree?
----
Going back to the two definitions I proposed, and after giving it some thought,
I favor the first
(array-length a) = (car (array-dimensions a))
more strongly than before, for these reasons:
1. Utility. I do the equivalent of (car (array-dimensions a)) much more often
than either (fold * 1 (array-dimensions a)) or what Matlab length() does. An
array is often also a list of objects, e.g. a list of n points in R^m is an [n
m] shape array, or a list of n transformation matrices is an [n m m] shape
array [*].
Of course this is because of the way I use arrays in my own code. I'd be
interested in reading about what other people do.
2. Efficiency. (car (array-dimensions a)) deserves a shortcut, since it's a
waste to construct a list only to take its car. You can say that of the other
axes, but the first axis is used more often.
[*] This is very common in J and K, the descendants of APL. In fact K's
'arrays' don't even need to be rectangular. But I think J can be a good model
for Guile arrays. J has an operator '#' (tally) which is basically what I
propose for array-length. The only difference is that in J (# scalar) gives 1,
and this seems irregular. It maybe better to make (array-length #0(0)) an error.
Here's an implementation with this behavior.
SCM array_length(SCM a)
{
scm_t_array_handle h;
scm_array_get_handle(a, &h);
if (scm_array_handle_rank(&h)==0) {
scm_array_handle_release(&h);
scm_error_scm(scm_from_locale_symbol("out-of-range"), SCM_BOOL_F,
scm_from_locale_string("no items for rank 0 array"),
SCM_EOL, a);
}
scm_t_array_dim const * dims = scm_array_handle_dims(&h);
SCM l = scm_from_size_t(dims->ubnd-dims->lbnd+1);
scm_array_handle_release(&h);
return l;
}