guile-devel
[Top][All Lists]

## 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>
> 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

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;
}

```