- Being global, the registry inherits some of the usual problems with global variables.
Since the registry is not exposed as a variable, I don't understand this.
- The registry is much like a bunch of dynamically-scoped variables, whose problems we know from early Lisp dialects.
This I understand even less.
- The registry is shared across the whole Scheme process, meaning that libraries shouldn't register types (automatically), but only the user program should (see the related discussion on SRFI 128 comparators). This works until two previously separate user programs are merged together.
- That SRFI 225 allows implementations to pre-register dictionaries makes it impossible to write portable code because if I, say, register SRFI 125 hash tables as a user, I may provoke an error because they have already been pre-registered.
- The same Scheme type can only be used in one way as a dictionary.
That's true, but in comparators there are various counterexamples, like comparators that do decreasing order instead of increasing order. What counterexamples do you have in mind? I couldn't think of any, which is why I switched to implicit use and registration-by-default.
- The biggest problem, however, comes last: As the registry is a runtime object, an optimizing compiler has no way to optimize any generic access. This will make the SRFI 225 procedures way (!) slower than using type-specific procedures. This is especially problematic because SRFI 225 looks very convenient, drawing many users to it. But as it is now, it will be a honey pot.
So... coming to the title of this post: I would like to strongly ask the authors to think of a different mechanism to achieve polymorphism.
A certainly better way in all regards (apart from an extra argument) is to employ dictionary type descriptors bundling the predicate and accessor procedures of a dictionary type in a record.
I experimented with an extra-argument version (it was my first idea, given that's what the comparator functions do) and I found that it was excessively cumbersome. As for records, such records do exist (actually they are vectors, which should be even more efficient) inside the implementation. See externals.scm.
What is more, in the current design we check the dictionary type (currently done by iterating down an alist from type predicates to vectors, but this could be changed) only at an external call; when e.g. the internal version of dict-ref/default invokes the internal version of dict-ref (which invokes the user-supplied version of dict-search!) , the internal vector is passed along and used to find dict-ref and dict-search!. A vanilla implementation of dictionary records would wind up checking repeatedly. See internals.scm.