Our second example of the implementation and use of generalized
specializers is a reimplementation of one of the examples in
\cite{Costanza.etal:2008}: specifically, the factorial function.
- Here, we will perform dispatch based on the =signum= of the
+ Here, dispatch will be performed based on the =signum= of the
argument, and again, at most one method with a =signum= specializer
- will be appliable to any given argument, which makes the structure
+ will be applicable to any given argument, which makes the structure
of the specializer implementation very similar to the =cons=
specializers in the previous section.
(defmethod fact ((n (signum 1))) (* n (fact (1- n))))
#+end_src
- We do not need to include a method on =(signum -1)=, as the
- standard =no-applicable-method= protocol will automatically apply to
- negative real or non-real arguments.
+ The programmer does not need to include a method on =(signum -1)=,
+ as the standard =no-applicable-method= protocol will automatically
+ apply to negative real or non-real arguments.
** Accept HTTP header specializers
:PROPERTIES:
:CUSTOM_ID: Accept
(arg tbnl:request))
(make-instance 'accept-generalizer
:header (tbnl:header-in :accept arg)
- :next (class-of arg)))
+ :next (call-next-method)))
(defmethod specializer-accepts-p
((s accept-specializer)
(o tbnl:request))
(ensure-class nil :direct-superclasses
'(text/html image/webp ...))
#+end_src
- and dispatch operates using those anonymous classes. While
+ and dispatch would operate using those anonymous classes. While
this is possible to do, it is awkward to express content-type
negotiation in this way, as it means that the dispatcher must know
about the universe of mime-types that clients might declare that
filtering paradigm.
Note that in this example, the method on =specializer<= involves a
- nontrivial ordering of methods based on the =q= values specified in
- the accept header (whereas in sections [[#Cons]] and [[#Signum]] only a
+ non-trivial ordering of methods based on the =q= values specified
+ in the accept header (whereas in sections [[#Cons]] and [[#Signum]] only a
single extended specializer could be applicable to any given
argument).
(s string))
(make-instance 'accept-generalizer
:header s
- :next (class-of s)))
+ :next (call-next-method)))
(defmethod specializer-accepts-p
((s accept-specializer) (o string))
(let* ((tree (parse-accept-string o))
:END:
In section [[#Examples]], we have seen a number of code fragments as
- partial implementations of particular non-standard method dispatch,
- using =generalizer= metaobjects to mediate between the methods of
- the generic function and the actual arguments passed to it. In
- section [[#Generalizer metaobjects]], we go into more detail regarding
- these =generalizer= metaobjects, describing the generic function
- invocation protocol in full, and showing how this protocol allows a
- similar form of effective method cacheing as the standard one does.
- In section [[#Generalizer performance]], we show the results of some
- simple performance measurements on our implementation of this
- protocol in the SBCL implementation \cite{Rhodes:2008} of Common
- Lisp to highlight the improvement that this protocol can bring over
- a naïve implementation of generalized dispatch, as well as
- to make the potential for further improvement clear.
+ partial implementations of particular non-standard method dispatch
+ strategies, using =generalizer= metaobjects to mediate between the
+ methods of the generic function and the actual arguments passed to
+ it. In section [[#Generalizer metaobjects]], we go into more detail
+ regarding these =generalizer= metaobjects, describing the generic
+ function invocation protocol in full, and showing how this protocol
+ allows a similar form of effective method cacheing as the standard
+ one does. In section [[#Generalizer performance]], we show the results
+ of some simple performance measurements on our implementation of
+ this protocol in the SBCL implementation \cite{Rhodes:2008} of
+ Common Lisp to highlight the improvement that this protocol can
+ bring over a naïve implementation of generalized dispatch, as well
+ as to make the potential for further improvement clear.
** Generalizer metaobjects
:PROPERTIES:
cater for filtered dispatch, but they would have to explicitly
modify their method combinations. The Clojure programming language
supports multimethods[fn:5] with a variant of filtered dispatch as
- well as hierachical and identity-based method selectors.
+ well as hierarchical and identity-based method selectors.
In context-oriented programming
\cite{Hirschfeld.etal:2008,Vallejos.etal:2010}, context dispatch
amortized (though there remains a substantial overhead compared with
standard generic-function or regular function calls). We discuss
how the efficiency could be improved below.
-** Future Work
+** Future work
:PROPERTIES:
:CUSTOM_ID: Future Work
:END: