rhombus-prototype icon indicating copy to clipboard operation
rhombus-prototype copied to clipboard

Some syntax that avoids the verbosity in the `keyword-apply` etc kind of functions in the common case of passing keywords around.

Open spdegabrielle opened this issue 6 years ago • 2 comments

Some syntax that avoids the verbosity in the keyword-apply etc kind of functions in the common case of passing keywords around.

from Wishlist of backwards incompatible things for a future Racket2. #33

spdegabrielle avatar Jul 22 '19 11:07 spdegabrielle

I really like Python's

def foo(a, b, c=1, d=2, *args, **kwargs):
    bar(3, z=4, *args, **kwargs)

Racket is good at dealing with *args:

(define (foo a b [c 1] [d 2] . args)
  (apply bar 3 args #:z 4))

but it's very painful to deal with **kwargs

(define foo
  (make-keyword-procedure
    (lambda (kw kw-args a b . args)
      (define kw+args (map cons kw kw-args))
      (define new-kw+args (remove* '(#:c #:d) kw+args (lambda (x y) (eq? x (car y)))))
      (keyword-apply bar #:z 4 (map car new-kw+args) (map cdr new-kw+args) 3 args))))

@alexknauth has been adding dict support for kwargs. That's a huge improvement because keyword and corresponding keyword argument now go together. However, we still can't extract keyword arguments.

At the very least, I hope that make-keyword-procedure will support extracting keyword arguments. But ideally, we shouldn't even need make-keyword-procedure. lambda should be enough. apply and keyword-apply should also be unified.

More radically, do we need apply? Why isn't function application syntax enough to deal with these?

See also: https://groups.google.com/d/msg/racket-users/3_Vc3t0fTGs/HpLZQCwADQAJ

sorawee avatar Jul 22 '19 19:07 sorawee

Related work: in my arguments package, there's a first-class arguments? struct wrapping positional and keyword args. There's also apply/arguments and define/arguments as easier alternatives to keyword-apply, make-keyword-procedure, etc.:

> (define/arguments (print-arg-counts args)
    (printf "Positional: ~a\n" (length (arguments-positional args)))
    (printf "Keyword: ~a\n" (hash-count (arguments-keyword args))))
> (print-arg-counts 1 2 3 4 5 #:foo 'foo #:bar 'bar)
Positional: 5
Keyword: 2
> (keyword-apply print-arg-counts (arguments 1 2 3 4 5 #:foo 'foo #:bar 'bar))
Positional: 5
Keyword: 2

This seems like the kind of thing that ought to be in the main distribution.

jackfirth avatar Jul 23 '19 05:07 jackfirth