On Sep 19, 2012, at 18:00, guile-devel-requ...@gnu.org wrote: > Date: Wed, 19 Sep 2012 13:02:25 +0100 > From: Peter TB Brett <pe...@peter-b.co.uk> > To: guile-devel@gnu.org > 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; }