(The following note was written while softly humming, "
    ...
    I get by with a little help from my friends,
    Gonna try with a little help from my friends.
    ...
")

I'm really interested in the idea of a common/shared library of
functions/objects such as found on www.rebol.com, contained in
Ladislav's

    http://www.rebol.org/advanced/highfun.r

(as one example of the MANY sites that REBOLlistfolk have),
or some of my scribbles earlier in this thread.  I'll address
the library issue in a follow-up post.  As for the function at
hand, let me raise a couple of questions:

[EMAIL PROTECTED] wrote:
> 
> Joel wrote:
> > Finally, I'd considered handling the structure-traversing
> > issues separately from the data-manipulation issues, by
> > defining (this version is VERY quick and dirty):
> >
> >...
> 
> I've cleaned it up a bit:
>
> ...
> 

j>     transpose: function [b [block!]] [w i s r] [

A> Transpose: function [
A>     [catch]
A>     "Transposes Matrices"
A>     Matrix [block!]
A>     ][
A>     Results Width Height Column
A>     ][

Nice choice of names (but I MUST remember to ask you about the caps)
Since we're discussing, I'll take the liberty to explain my abbrevs
as (w)idth (i)ndex (s)ubresult (r)esult :-/

j>     r: make block! w: accum length? b/1 map b :length? :min

A>     Results: make block! Width: length? Matrix/1
A>     Height: length? Matrix

That bit of obscurity in the initialization of  w  is explained
in a footnote (1) in case I mangled it so badly that no-one can
read it.  My real question here is this, if we collectively are
going to build up a small pile of useful extensions, would it be
good to have some conventions re defensive programming, or would
that be the sort of thing that should simply be documented (for
each) as "possible failure modes"?  Alternately, should we have
a rating (I do NOT mean "value judgement", but simply accurate
labeling of content!) with values such as:

    "fragile"  - "arguments not vetted, you can crash this if
                  you don't play well with others"
    "robust"   - "good faith argument checking done, but there
                  may be some gotchas left"
    "ironclad" - "we've collectively banged on this one REALLY
                  hard, and are confident that errors will be
                  pre-empted"

j>         s: make block! length? b

A>         Column: make block! Width

(Boneheaded mistake on my part -- thanks for the correction!)

J>         foreach c b [append/only s c/:i]
j>         append/only r s

A>         foreach Row Matrix [
A>             insert/only tail Column Row/:Index
A>             ]
A>         insert/only tail Results Column

(Sigh... You'd think I'd have learned by now.  Thanks for cleaning
"append/only" up into "insert/only tail" -- repeatedly!)

> 
> > Critiques/comments/debugging welcome!
> 
> I totally agree. :-)
> 

-jn-


FOOTNOTE:

1)  Regarding the peculiar initialization code
    
        r: make block! w: accum length? b/1 map b :length? :min
                                            ------1-------
                                -----2-----
                       --------------------3-------------------

Step 1 gets the lengths of all sub-blocks in the argument,
step 2 assumes the length of the first as a default, and
step 3 sets  w  to the length of the shortest sub-block.

This was done so that a collection of (sub-)blocks of different
lengths wouldn't cause an error, but would be transposed as far
as possible:

    >> transpose [[1 2 3 4 5] [1 2 3] [1 2 3 4]]
    == [[1 1 1] [2 2 2] [3 3 3]]

Of course, this is still not totally robust, as an empty arg
block will still not be swallowable (mea culpa!):

    >> transpose []
    ** Script Error: length? expected series argument of type:
       series port tuple struct.
    ** Where: r: make block! w: accum

This is easy to handle by adding

    if 0 = length? b [return copy []]

to the very beginning of the function, or wrapping the body with

    either 0 = length? b [
        r: copy []
    ][
        r: ...etc...
        ...etc...
    ]
    r

which would then ensure that the basis for  accum  given by
length? b/1  was well-defined.

I assume your  [catch]  was a faster way of addressing this
same issue, by simply passing the error resulting from an
empty argument list back to the caller.

So...  should we prefer a style for common/standard library
functions, or at least document which position the author (and
maintainers) took?

Reply via email to