+ | fact (signum-gf) | %fact (fun) | %%fact (gf / 1meth) | fact (signum-gf / 1arg hash-special-case) |
+ |------------------+-------------+---------------------+-------------------------------------------|
+ | 0.284 | 0.004 | 0.016 | 0.032 |
+ | 0.076 | 0.008 | 0.012 | 0.024 |
+ | 0.072 | 0.004 | 0.012 | 0.116 |
+ | 0.264 | 0.004 | 0.008 | 0.120 |
+ | 0.292 | 0.008 | 0.012 | 0.120 |
+ | 0.264 | 0.004 | 0.016 | 0.084 |
+ | 0.276 | 0.008 | 0.012 | 0.092 |
+ | 0.264 | 0.008 | 0.012 | 0.036 |
+ | 0.276 | 0.008 | 0.004 | 0.104 |
+ | 0.272 | 0.004 | 0.012 | 0.020 |
+
+ We could allow the metaprogrammer to improve on the one-argument
+ performance by constructing a specialized cache: for =signum=
+ arguments of =rational= arguments, the logical cache structure is
+ to index a three-element vector with =(1+ signum)=. The current
+ protocol does not provide a way of eliding the two generic function
+ calls for the generic cache; we discuss possible approaches in
+ section WW.
+** HTTP Accept header
+ In this section, we implement a non-trivial form of dispatch. The
+ application in question is a web server, and specifically to allow
+ the programmer to support RFC 2616 \cite{rfc2616} content
+ negotiation, of particular interest to publishers and consumers of
+ REST-style Web APIs.
+
+ The basic mechanism in content negotiation is as follows: the web
+ client sends an HTTP request with an =Accept:= header, which is a
+ string describing the media types it is willing to receive as a
+ response to the request, along with numerical preferences. The web
+ server compares these stated client preferences with the resources
+ it has available to satisfy this request, and sends the best
+ matching resource in its response.
+
+ In the case where there are static files on the filesystem, and the
+ web server must merely select between them, there is not much more
+ to say. However, it is not unusual for a web service to be backed
+ by some other form of data, and responses computed and sent on the
+ fly, and in these circumstances the web server must compute which
+ of its known output formats it can use to satisfy the request
+ before actually generating the best matching response.
+
+ The =accept-specializer= below implements the dispatch. It depends
+ on a lazily-computed =tree= to represent the information in the
+ accept header, and a function =q= to compute the (defaulted)
+ preference level for a given content-type and =tree=; then, method
+ selection and ordering involves finding the =q= for each
+ =accept-specializer='s content type given the =tree=, and sorting
+ them according to the preference level.