Hello all!
While working on SRFI-167, SRFI-168 and RDBMS [0] it became clear to me that scheme requires something like single dispatch to ease the implementation of swap-able backend.
[0]
https://srfi-email.schemers.org/schemepersist/msg/12473867/
It can also help during (unit) tests to implement mocks.
I know that I don't know. In particular, I forgo to include subsumption, because I don't know where / when it is useful.
What do you think?
I started a pre-SRFI at:
https://github.com/amirouche/single-dispatch#predicate-single-dispatch
Here is the current full document:
# Predicate Single Dispatch
## Status
Early Draft
## Abstract
*Two or three sentences about what library this SRFI describes.*
## Rationale
*Explain why it is useful and how it can be put to good use.*
In many situations, the need arise to have several implementations of
a procedure that depends on the type of the first argument.
This specification describes an approach to solve that problem. It is compatible with R7RS-small records objects and more generally with any
objects that have disjoints predicates.
## Specification
### `(make-single-dispatch) → procedure`
Return a single-dispatch procedure. A single-dispatch procedure has
the same type as any other procedure.
### `(single-dispatch-register single-dispatch predicate? proc) → unspecified`
Register `PROC` to be called when `SINGLE-DISPATCH` is passed as first
argument an object for which `PREDICATE?` returns `#t`.
### Calling a single-dispatch procedure
A single-dispatch procedure when called with a first argument for
which there is one and only one predicate registered with `single-dispatch-register` returns `#t` will pass all the arguments to
the procedure that was associated with it.
When called with zero arguments the implementation must error. That
is, it can only be called with one or more arguments.
The implementation must error if the first argument can be associated
with more than one predicate registered with
`single-dispatch-register`.
If no registered predicate return `#t`, the implementation must error.
## Implementation
```scheme
(library (single-dispatch)
(export make-single-dispatch
single-dispatch-register)
(import (chezscheme))
(define %register (list '%register))
(define (make-single-dispatch)
(let ((%dispatcher '()))
(lambda (obj . rest)
(let loop ((dispatcher %dispatcher))
(if (null? dispatcher)
(cond
((eq? obj %register)
(set! %dispatcher (cons (cons (car rest) (cadr rest)) %dispatcher)))
((null? %dispatcher)
(error 'single-dispatch "there is no procedure registred"))
(else (error 'single-dispatch "unknown object")))
(if ((caar dispatcher) obj)
(apply (cdar dispatcher) obj rest)
(loop (cdr dispatcher))))))))
(define (single-dispatch-register single-dispatch predicate? proc)
(assert (procedure? predicate?))
(assert (procedure? proc))
(single-dispatch %register predicate? proc)))
```
## Acknowledgements
Give credits where credits is due.
## Copyright
Copyright (C) Amirouche Boubekki (2019).
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)