This page is part of the web mail archives of SRFI 50 from before July 7th, 2015. The new archives for SRFI 50 contain all messages, not just those from before July 7th, 2015.
> >>>>> "Marc" == Marc Feeley <feeley@xxxxxxxxxxxxxxxx> writes: > > Marc> But cond-expand is a portable 35 line R5RS macro. How can you say it > Marc> is difficult to implement in any reasonable Scheme system? I know > Marc> that you don't want to implement it in Scheme 48 because you disagree > Marc> with the philosophy behind it, and I respect that, but that is very > Marc> different from saying that it is technically difficult. > > You misunderstand. While it probably is also a matter of philosophy, > it's first and foremost a technical issue. Indeed, implementing > SRFI 0 in Scheme 48 would be technically trivial, but the result would > be useless: in Scheme 48, lots of features exist, but none are > available in the sense of SRFI 0. Essentially the same holds for PLT > Scheme. I got a similar reply from Richard Kelsey, and I feel I must answer because I just simply don't understand what the problem is. I'm CCing to the SRFI-0 mailing list since this should be archived there. SRFI-0 does not assume that all available SRFIs (i.e. "features") are built-in. It says so explicitly in the SRFI document. "cond-expand" simply tests for the presence of a feature. An implementation of Scheme may choose to make all available SRFIs built-in, or to have another mechanism (such as a module system) to do this. In fact an implementation of Scheme may have some features that must be requested through the module system and some others built-in (either because the system implements extensions to Scheme, like a thread system, that are available all the time, or because a particular feature can only be built-in, such as the char->integer/integer->char procedures obeying the Unicode encoding and allowing Unicode characters in Scheme strings). To implement the interaction between the module system and "cond-expand", the module system could maintain a "feature" environment or extend the cond-expand macro for the body of the module. So if the module does (require foo) and (require bar), then both "foo" and "bar" are recognized by cond-expand as available features for the body of the module (this is just to give the idea... it might be better to have the foo and bar modules explicitly indicate which features they provide, with a (provide foo) form, and only these features would be added to the available features for the body of the module). The need for "cond-expand" does not disappear when a module system is available. Here is an example. Suppose I write a web-server in Scheme using threads. The web-server needs basic thread primitives like those in SRFI-18 (Multithreading support). However, real-time response of the web-server can be improved by using the "thread-priority-boost-set!" procedure that is only available in SRFI-21 (Real-time multithreading support). This is the only feature of SRFI-21 that is useful; all other thread operations are from SRFI-18 (note that SRFI-21 is a strict superset of SRFI-18). Moreover assume that these thread SRFIs are not built-in. So the source-code of the web-server will look something like this: (module web-server (require (or srfi-21 srfi-18)) (cond-expand (srfi-18 (define (thread-priority-boost-set! thread boost) #f)) ; noop (srfi-21 ; thread-priority-boost-set! exists in srfi-21 )) ... (define (respond-to request) (let ((t (make-thread (lambda () (process request))))) (thread-priority-boost-set! t 10) (thread-start! t))) ... ) The "require" form used here is hypothetical. I use the "or" to indicate that the system tries to locate the modules in order and the first that is found prevents the search for the other modules. The nice thing with the module expressed with a "cond-expand" is that it adapts to the features that are available. The author of the web-server has designed the module so that it can work in either context. Unfortunately, the Scheme module systems I have seen don't support this form of "require". The "require" form usually means that this and only this module will do. So in such systems the web-server would probably be written like this: (module web-server (require srfi-21) ;;; if you do not have srfi-21 available it is OK ;;; to replace this line with (require srfi-18) (cond-expand (srfi-18 ...)) ... ) Here the author has left a comment that allows the user of the web-server to make a simple change to the code if srfi-21 is not available (this is not great, but it is better than having to read, understand, and modify the source code so that it does not use thread-priority-boost-set!, and so can be used with srfi-18). It is also better (in my view) than creating two web-server modules (one for srfi-21 and one for srfi-18) that only differ in a few places, or that use "include" forms to factor the common parts. Marc