As I am writing up the documentation for the revised SRFI-1 library, I have
cast my eye over the library as a whole, and am somewhat concerned with the
size of the namespace. While there's no particular reason why a large
namespace is bad, procedures exported by the library should "pull their
weight."
The primary source of namespace bloat is the multiple versions of procedures
defined over various equality procedurs -- instead of simply having a MEMBER
procedure, we have MEM, MEMQ, MEMV, and MEMBER. This gives a quadrupling
effect across certain classes of procedures.
If we throw the EQ?, EQUAL?, and EQV? specific operators out, we can
eliminate 56 procedures from the library. At what cost?
- Well, some code will be slightly more awkward to write; interactive use might
be a little more irritating.
- Compilers may not generate code quite as good as they could when, for
instance, the EQ? call is embedded in-line into a client procedure.
- Putting the comparison procedure last (where it can be optional)
breaks with the standard convention of putting it first.
I suggest the following modifications.
1. Keep MEMBER, MEMQ, MEMV, ASSOC, ASSQ and ASSV, for historical purposes --
backwards compatibility with RnRS. Kill the general MEM and ASS, and
instead extend MEMBER and ASSOC to take an optional third argument,
the comparison procedure (as was suggested by Sergei and others):
(member 'a '(this is a list))
(member 3 '(1 2 3 4 5) =)
2. Kill the comparison-specific deletion procedures
delq delv delete
delq! delv! delete!
delq-duplicates delv-duplicates delete-duplicates
delq-duplicates! delv-duplicates! delete-duplicates!
del-ass del-assq del-assv del-assoc
del-ass! del-assq! del-assv! del-assoc!
Alter the remaining procedures, changing the lexeme "DEL" to "DELETE",
moving the comparison-procedure parameter to the last argument, making
it optional, defaulting to EQUAL?. So we wind up with
delete delete!
delete-duplicates delete-duplicates!
alist-delete alist-delete!
Example: (delete 5 '(3 5 7 9 5 4 3) =)
Making the comparison procedure default to the general EQUAL? makes casual,
interactive use convenient.
3. Kill the 36 comparison-specific lists-as-sets operators, retaining only
lset-adjoin lset-adjoin!
lset-union lset-union!
lset-intersection lset-intersection!
lset-difference lset-difference!
lset-xor lset-xor!
lset-diff+intersection lset-diff+intersection!
As these operators are n-ary, the comparison procedure must come first,
hence cannot be made optional. So it goes.
Notice that the deleted bindings are still available for programmers
to define -- we haven't taken DELQ or DEL-ASSV!, so if the programmer
wishes to write the one-liner defining any of these procedures, he can
do so in a fashion that preserves the FOO?/FOOQ?/FOOV? convention.
This cleans out 58 procedures from the library -- a very large size
reduction in namespace for not much reduction in functionality.
Opinions?
-Olin