-
Notifications
You must be signed in to change notification settings - Fork 1
NAryDispatchProposal
dylan and clos' function congruency rules complicate function subtyping, decrease extensibility, and preclude conveniencies. it is impossible to write methods that specialize on different numbers of arguments, a style which has been shown to be useful in languages with static overloading.
- make things convenient.
- make things simple.
- support incremental development.
- features should be orthogonal as possible.
- pay as you go.
in addition to specializers, the number of parameters is also used to choose methods whereby methods with more parameters have priority over methods with fewer. rest parameters can take a type which specifies that all args must conform to that type. rest parameters come strictly after required parameters. only one rest parameter is allowed per parameter list.
parameter syntax:
rest-param-spec ::= ,name | ,name '|' ,rest-type rest-type ::= '...' | ('...' ,expression)
where type defaults to <any>.
dispatch:
find applicable methods based on required arguments present and (isa? arg_i arg-spec_i) where arg-spec_i is spec_i for i < number-required and rest_spec for i >= number-required sort applicable methods according to arg-subtype? across each parameter where arg-subtype? is subtype? with tie breaker rule that prioritizes specializers on required over rest args
nary arithmetic
(dm + (x|<int> y|<int> => <int>) ...) ;; m1 (dm + (x|<int> r|(... <int>) => <int>) ;; m2 (reduce + x r*)) (+ 1 2) ;; calls m1 (+ 1) ;; calls m2 (+ 1 2 3) ;; calls m2 which calls m1
specialization
(dm map (f|<fun> x|<col>) => <col>) ...) ;; m1 (dm map (f|<fun> x|<col>) (y <col>) => <col>) ...) ;; m2 (dm map (f|<fun> x|(... <col>) => <col>) ...) ;; m3 (dm map (f|<fun> x|<vec>) => <col>) ...) ;; m4 (map 1+ '(1 2 3)) ;; calls m1 (map + '(1 2 3) '(2 3 4)) ;; calls m2 (map + '(1 2 3) '(2 3 4) '(3 4 5)) ;; calls m3 (map + #(1 2 3) #(2 3 4)) ;; calls m4
are the rules for nary method specificity intuitive?