[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fundamental design flaws

This page is part of the web mail archives of SRFI 44 from before July 7th, 2015. The new archives for SRFI 44 contain all messages, not just those from before July 7th, 2015.





For me, currently, there are at least six big issues with the srfi.  I
will list these and then say more about each below.

1) lack of extensibility

2) requirement for and definition of procedures for which valid
   arguments can not be provided using only the facilities of the srfi
   (and standard scheme)

3) unfortunate class hierarchy 

4) absense of reasonable support for iterators

5) unfortunate handling of "equivalence functions"

6) buggy and incomplete implementation with unreasonable dependencies.


----------------------------------------------------------------

1) lack of extensibility

   I simply do not believe your claims that adding definitions for 
   type constructors would in any serious way damage implementations.

   Nothing about type constructors would _require_ that all 
   collection types are created by them;  nothing would prevent
   native collection types from having whatever representations
   they like.

   Collection type constructors could be reasonably implemented in a
   reference implementation by using the facilities of srfi-9.

   Collection type constructors are a prerequisite for allowing people
   to write portable implementations of collection types.   While a 
   portable implementation may or may not be less efficient than 
   a native one, many useful collection types would perform quite
   reasonably using just about any reasonable implementation of
   srfi-9, a srfi which I would hope that any non-trivial Scheme
   implementation seeks to implement well.


2) unusable procedures

   44 defines procedures which client programs have no use for.
   For example, all of the SET functions could be correctly
   implemented as:

	(define (set-fn . ignored) 
          (error "there is no such thing as a set"))

   Specifications of such procedures should come after, not before
   the specification of values that would make them meaningful.


3) unfortunate class hierarchy

  I recognize that there are, for example, operations which apply
  generically to sequences and dictionaries.

  It is a fine idea to provide an abstract interface to such
  operations, much as Common Lisp does for sequences.

  However, this srfi goes much further than that.  In particular, it
  requires that, in these abstract interfaces, a list or a vector is
  always a sequence and never a dictionary.

  The reason it must do so is because it seeks to unify everything
  that might vaguely be called a "collection" in a class hierarchy,
  and to provide abstract interfaces to collections in general.
  No motivation is provided, however, for the existence of a
  COLLECTION? type.   And if it is the case that a COLLECTION? type
  is truly desirable, no rationale is provided to explain why SEQUENCE?
  gets the privilege of subsuming the LIST? type rather than, say SET?
  or DICTIONARY?.

  Related to this is the fact that some procedures that accept a
  collection are, in fact, partial functions of the set of
  collections.   

  Let me put this a little differently: supposing I really like the
  abstract parts of the collections interface of 44 but I'm writing a
  program that wants to use ordinary lists (plus some other
  implementation-specific types) as _dictionaries_ not sequences.
  It'd be swell to have the genericty of 44 to help me operate
  transparently on either of these two representations, but I can't --
  because in 44 a list is always a sequence, not a dictionary.

  I wonder if it wouldn't be an improvement to _not_ attempt to
  provide a "collections" interface, but rather to provide separate 
  interfaces for sets, dictionaries, and sequences?

  I'll happily live without COLLECTION-COPY if you can give me both
  DICTIONARY-COPY (accepting normal association lists) and
  SEQUENCE-COPY (accepting normal lists).


4) absense of reasonable support for iterators

  Let us suppose that I would like to iterate over the elements of two
  or more collections, randomly choosing which collection to pick an
  element from next.

  The -FOLD- procedures permit me to do this but only by one of a few 
  means all of which seem to be horribly inefficient compared to what
  is achievable:  I can convert the collections to lists or some other
  type;   I can use call/cc.

  Compared to, say, incrementing an index integer or taking the CDR of
  a pair, those techniques for iteration over multiple collections are
  horrible.  It is a serious weakness of 44 that it does not define
  generic interfaces to iterators which would not require those
  techniques.


5) unfortunate handling of "equivalence functions"

  Similarly to the way that 44 forces all lists to be sequences but
  not dictionaries, it also forces all lists to EQV?-based bags.

  Parametric equality is pervasive in Scheme (and, really, all lisp
  dialects).   You've got MEMQ, MEMV, and MEMBER, for example.

  I am not at all clear why I would really want just BAG-CONTAINS? for 
  example rather than BAG-CONTQ?, BAG-CONTV?, BAG-CONTAINS? (and,
  perhaps BAG-CONTAINS=? to permit an arbitrary predicate).

  For something like a hash table, sure -- at creation time I really
  need to establish what notion of equality (and hence, hashing) is in
  play -- but for bags?


6) buggy and incomplete implementation with unreasonable dependencies.

  Bugs and missing things can be fixed, of course, but in its current
  state, the srfi truly ought to be rejected by the editors on this
  basis.

  Tiny-Clos is, in my opinion, a quite unreasonable dependency.   At
  the _very_ least it should be included in the reference
  implementation so that the proposal is self contained.   Personally, 
  I would much prefer to see a reference implementation based on
  srfi-9 rather than one that defines lots of complicated new
  functionality well outside the scope of the srfi.

  A few srfis are clearly special:  they either can't be portably
  implemented or a portable implementation is, at best, a toy.
  srfi-9 is a good example of the latter.

  Informally, though, the _point_ of such foundational srfis is quite
  sophisticated:   to provide a spec that interfaces can implement in
  a non-toy fashion without compromising their quality, and to spare
  future srfis from having reference implementations that share those
  unfortunate properties.

  Since srfi-9 is ample mechanism to implement 44, it would be vastly
  preferable to dragging in Tiny-Clos.


Perhaps it would be helpful to take a more bottom-up approach.
Rather than trying to make a "collections" srfi that is a 100%
solution for that domain, start by making a "sequences" srfi and a
"dictionary" srfi and a "set" srfi -- and then see whether there are
higher-order generalizations to make after that.

-t