Re: API conflicts (Was: Re: Reasons for withdrawal) Taylor Campbell 29 Oct 2003 21:39 UTC

On Wednesday, Oct 29, 2003, at 00:48 US/Eastern, Shiro Kawai wrote:

> I'd still like to see a section or a note that refers to names
> which conflicts or confusing with existing srfis and popular
> implementations.  It may be a job of users to look them out,
> but having mentioned it in this srfi would be a great help
> for users and implementators.  Something like the following.
>
>   Compatibilities:
>
>      Some of the names defined in this srfi uses the same or
>      similar name in existing srfis or implementations.  Some of
>      them are defined so that they are extension of the existing
>      practice, and some of them have incompatibilities.
>
>    Extensions to R5RS
>
>      R5RS doesn't specify the return value of string-set! and
>      vector-set!.  This srfi specifies them to return the passed
>      collection.
>
>      string-ref, vector-ref and list-ref are extended to take
>      an optional argument, absence-thunk.

I just want to stress the fact that these are _extensions_ and not
incompatibilities.

>    Relation to other SRFIs
>
>      string= has different interface from string= in srfi-13,
>      which has the following API:
>
>         (string= string1 string2 [start1 end1 start2 end2])
>
>      If the implementation wish to support both srfis, it can
>      dispatch by its argument types.

I think SRFI 13's STRING= is the problem here.  It breaks the
convention defined by SRFI 1, and SRFIs 43 and 44 use that same
convention; SRFI 13's STRING= is really R5RS's STRING=?, but with the
question mark removed for no reason I can find.

(oops: having read your email over again, I realize that it was just
a list of related work/extensions/incompatibilities; this comment is
therefore irrelevant to this message, but it's still a comment I'd
like to make somewhere)

>      string-copy and string-count are subset of srfi-13's.

*-COPY for sequences _used_ to be like SRFI 13's STRING-COPY and SRFI
43's VECTOR-COPY.  I'm not sure where this changed, and I'll see if
Scott will put that back in.  The same applies to *-COUNT for
sequences, except without it having been extended for sequences in
prior versions of the document.

In fact, it seems like it would make sense for a lot of the bag and
general collection operations to be able to accept start and end
arguments for the sequence versions, e.g. *->LIST, *-REMOVE-whatever,
et cetera.

>      [...]
>
>      list= in this srfi takes two lists.  list= in srfi-1 takes
>      arbitrary number of lists.

LIST= should be n-ary.  I'm not sure why it isn't.  (probably a typo;
there are lots of those in the document, due to the tedium in writing
it)

>      [...]
>
>      alist-copy is an extension of srfi-1's.  SRFI-1's alist-copy
>      doesn't specify the behavior when the given argument contains
>      non-pair in the list.  This srfi's alist-copy treats the first
>      element specially.  [This actually suggests the choice of
>      'alist-' prefix may not be adequate, since the alist dictionary
>      given in srfi-44 is not really a plain alist.  For example,
>      when people see alist?, they might think something like
>        (define (alist? obj) (and (proper-list? pbj) (every pair? obj)))
>      but it's not the case here.  It's even obscure whether ordinary
>      alist operations such as assq, assv, assoc can be applicable to
>      this alist dictionary.  Maybe 'alist-dict-' prefix would be
> better].

A couple of problems with alists have been mentioned.  Three solutions
came up on IRC:

   - Create an abstract type for alists.
       Advantages: removes the type conflicts that Tom mentioned
       Disadvantages: _no_ list-processing routines work on abstract
         and opaque alists, that definition of ALIST? still doesn't
         work, and ASS{Q,V,OC} still don't work.
   - Add a unique token to the head of the alist.
       Advantages: removes the type conflicts
       Disadvantages: that definition of ALIST? still doesn't work, and
         ASS{Q,V,OC} still don't work.
   - Add a metadata _association_ to the list, with a unique token
     visible only to the implementation.  This metadata could contain
     the equivalence functions and even more, perhaps.
       Advantages: removes the type conflicts, your ALIST? works, and
         ASS{Q,V,OC} work.
       Disadvantages: there probably are some that I just can't
         remember now...Matthias brought this one up months ago, and I
         didn't implement it; I probably had _some_ reason for not
         implementing it.

>      srfi-1 uses "remove" and "delete" in a consistent way;
>      the functions with "remove" takes a predicate, while the ones
>      with "delete" takes a value to be compared to the element.
>      In this srfi, "remove" and "delete" also have a consistent
> meaning,
>      but different from srfi-1's.
>
>      Consequently, there are a few procedures that have confusingly
>      similar names with different signatures.
> [...]

I don't think these matter much.  They aren't _incompatible_, anyways,
though I suppose it might be worth mentioning.

>    Relation to existing implementations
>
>      Some implementations (e.g. PLT) use absence-thunk to give a
>      default value in ?-ref or ?-get API.  Other implementations
>      (e.g. Chicken, STk, Gauche) instead allow an optional value
>      to specify a default value.   This srfi takes the thunk approach
>      because .....
>
>      [Gauche has extended string-ref, vector-ref and list-ref.
>       Chicken and STk don't have them, but for example they have
>       hash-table-{ref|get} that takes an optional default value, which
>       would conflict if somebody wants to implement a hash table
>       as a dictionary.]

It's pretty easy to avoid this conflict by either not explicitly using
SRFI 44 or explicitly using those implementations' libraries, or
having a simple SRFI 44 wrapper around hash tables of those
implementations when you do explicitly use SRFI 44.

>      [This has persional bias:  Gauche has string-size that
>       returns number of bytes the multibyte string occupies]
>
>
> --shiro