[plt-scheme] passing-on keyword arguments
On Mar 19, Jakub Piotr C?apa wrote:
> Eli Barzilay wrote:
> > (define outer
> > (make-keyword-procedure
> > (lambda (kws vals . args)
> > (+ (keyword-apply inner kws vals args) 5))))
> >
> > I think that I know how to make it easier, allowing something like
> > this:
> >
> > (define (outer args ...)
> > (+ (inner args ...) 5))
> >
> > to do the same, but it'll take some work to implement.
>
> OTOH you loose all the information on what are the arguments to both
> inner and outer.
You don't lose any information about `inner' -- you just avoid
repeating its interface.
> Sooner than you think you got those Python *args, **kwargs functions
> all over the place
In these situations you already get these with plain scheme functions
-- it just happens that a single `*args' is needed.
I think that you can divide uses of rest arguments in Scheme to two:
using it with functions that accept any number of uniform arguments
(like `append', `+' etc), and less frequently in cases where (some of)
your arguments are really intended for another function. The latter
are the problem here. Two examples:
;; `sort-lists' is just like `sort', but it sorts a list of lists
(define (sort-lists lists smaller?)
(map (lambda (list) (sort list smaller?))))
The definition above is incorrect -- it hard-wires a specific `sort'
interface that might change. Obviously, if `sort' actually changes,
then your code becomes broken -- but what if it's extended, for
example with an extra optional argument or keyword?
;; does a left- or right-fold
(define (fold* direction fun init list)
((case direction
[(left) foldl]
[(right) foldr])
fun init list))
Again, I need to hard wire a specific interface to `foldl' and
`foldr', which is the same problem, but say that I want to generalize
this pattern:
(define ((make-left-right fun-l fun-r) direction . args)
(apply (case direction [(left) fun-l] [(right) fun-r])
args))
(define fold* (make-left-right foldl foldr))
;; srfi-1 things
(define reduce* (make-left-right reduce reduce-right))
(define take* (make-left-rigth take take-right))
(define drop* (make-left-rigth drop drop-right))
This becomes impossible without some rest arguments.
> and runtime/editor documentation & reflection are worth nothing.
Huh? My best guess is that you refer to the fact that `sort-lists'
does not have its own interface. For that it would be nice to have
some way to say that its interface is exactly the interface of
`sort-lists'. This is possible in PLT with `procedure-arity' etc, but
again not too convenient. Keywords makes this problem harder, of
course.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!