Re: [racket-users] Specializing functions accepting keywords

2019-07-11 Thread Philip McGrath
The easiest way I know is to use `curry`, since Alexis fixed its keyword
argument support

last year:

#lang racket

(define (fish #:name[name   #f]
  #:color   [color  #f]
  #:studio  [studio #f]
  #:eyes[eyes   2])
  (~a "The fish " name " is " color ", appears in a movie from " studio "
and has " eyes " eyes."))

(define disney-fish
  (curry fish #:studio "Disney"))

(disney-fish #:name "Nemo" #:color "orange")

… but it might be useful to have some other library functions for this sort
of thing: maybe a "curry once" or something like the `adjust-keyword-default
`
used in the `#lang slideshow` implementation.

-Philip


On Wed, Jul 10, 2019 at 1:25 PM Jens Axel Søgaard 
wrote:

> Consider the following fishy example wherein we try to
> reuse a function with keyword arguments.
>
>
> (define (fish #:name[name   #f]
>   #:color   [color  #f]
>   #:studio  [studio #f]
>   #:eyes[eyes   2])
>   (~a "The fish " name " is " color ", appears in a movie from " studio "
> and has " eyes " eyes."))
>
> Let's check see an example:
>
> > (fish #:name "Nemo"   #:color "orange" #:studio "Disney")
> "The fish Nemo is orange, appears in a movie from Disney and has 2 eyes."
>
> A few examples later one quickly realizes that Disney has
> a lot of fish in their movies:
>
>
> (fish #:name "Nemo"   #:color "orange" #:studio "Disney")
> (fish #:name "Dory"   #:color "blue"   #:studio "Disney")
> (fish #:name "Marlin" #:color "orange" #:studio "Disney")
> (fish #:name "Wanda"  #:color "gold"   #:studio "MGM")
> (fish #:name "Blinky" #:color "orange" #:studio "Fox" #:eyes 3)
>
>
> No worries, we can quickly define a  disney-fish  that simply
> calls  fish  using the #:studio keyword and passes other keywords
> along. The new  disney-fish must accept the same keywords as fish
> (except for the studio one), so  procedure-reduce-keyword-arity
> is needed to restrict the accepted keywords.
>
>
> (define disney-fish
>   (let ()
> (define (make-disney-fish kws kw-args . rest)
>   (keyword-apply/sort fish kws kw-args rest #:studio "Disney"))
>
> (define-values (fish-required fish-allowed) (procedure-keywords fish))
> (define fish-arity (procedure-arity fish)) ; number of by-position
> arguments
>
> (procedure-reduce-keyword-arity
>(make-keyword-procedure make-disney-fish)
>fish-arity
>(remove '#:studio fish-required)
>(remove '#:studio fish-allowed
>
> Now we can write:
>
> (disney-fish #:name "Nemo" #:color "orange")
>
> The new  disney-fish  accepts only keywords accepted by fish,
> so any error reporting works as expected.
>
> But ... the above solution wasn't quick - it took more work than I
> initially expected.
> Am I missing something that makes reusing functions accepting
> keyword arguments easier?
>
> /Jens Axel
>
>
> -- full example --
>
>
> #lang racket
>
> (require kw-utils/keyword-apply-sort)
>
> (define (fish #:name[name   #f]
>   #:color   [color  #f]
>   #:studio  [studio #f]
>   #:eyes[eyes   2])
>   (~a "The fish " name " is " color ", appears in a movie from " studio "
> and has " eyes " eyes."))
>
> (fish #:name "Nemo"   #:color "orange" #:studio "Disney")
> (fish #:name "Dory"   #:color "blue"   #:studio "Disney")
> (fish #:name "Marlin" #:color "orange" #:studio "Disney")
> (fish #:name "Blinky" #:color "orange" #:studio "Fox" #:eyes 3)
>
> (define disney-fish
>   (let ()
> (define (make-disney-fish kws kw-args . rest)
>   (keyword-apply/sort fish kws kw-args rest #:studio "Disney"))
> (define-values (fish-required fish-allowed) (procedure-keywords fish))
> (define fish-arity (procedure-arity fish)) ; number of by-position
> arguments
> (procedure-reduce-keyword-arity
>  (make-keyword-procedure make-disney-fish)
>  fish-arity
>  (remove '#:studio fish-required)
>  (remove '#:studio fish-allowed
>
>
> (disney-fish #:name "Nemo" #:color "orange"
>  #:studio "foo")
>
> ; Notes:
> ; > (disney-fish #:name "Nemo" #:color "orange" #:studio "Disney")
> ; correctly shows error (#:studio not expected)
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CABefVgyXzWW1WJjC9SViyzsheswJD9Ek4LDfwqaNg_v4mT6y%3DQ%40mail.gmail.com
> 
> .
> For more options, visit https://groups.google.com/d/optout

[racket-users] Specializing functions accepting keywords

2019-07-10 Thread Jens Axel Søgaard
Consider the following fishy example wherein we try to
reuse a function with keyword arguments.


(define (fish #:name[name   #f]
  #:color   [color  #f]
  #:studio  [studio #f]
  #:eyes[eyes   2])
  (~a "The fish " name " is " color ", appears in a movie from " studio "
and has " eyes " eyes."))

Let's check see an example:

> (fish #:name "Nemo"   #:color "orange" #:studio "Disney")
"The fish Nemo is orange, appears in a movie from Disney and has 2 eyes."

A few examples later one quickly realizes that Disney has
a lot of fish in their movies:


(fish #:name "Nemo"   #:color "orange" #:studio "Disney")
(fish #:name "Dory"   #:color "blue"   #:studio "Disney")
(fish #:name "Marlin" #:color "orange" #:studio "Disney")
(fish #:name "Wanda"  #:color "gold"   #:studio "MGM")
(fish #:name "Blinky" #:color "orange" #:studio "Fox" #:eyes 3)


No worries, we can quickly define a  disney-fish  that simply
calls  fish  using the #:studio keyword and passes other keywords
along. The new  disney-fish must accept the same keywords as fish
(except for the studio one), so  procedure-reduce-keyword-arity
is needed to restrict the accepted keywords.


(define disney-fish
  (let ()
(define (make-disney-fish kws kw-args . rest)
  (keyword-apply/sort fish kws kw-args rest #:studio "Disney"))

(define-values (fish-required fish-allowed) (procedure-keywords fish))
(define fish-arity (procedure-arity fish)) ; number of by-position
arguments

(procedure-reduce-keyword-arity
   (make-keyword-procedure make-disney-fish)
   fish-arity
   (remove '#:studio fish-required)
   (remove '#:studio fish-allowed

Now we can write:

(disney-fish #:name "Nemo" #:color "orange")

The new  disney-fish  accepts only keywords accepted by fish,
so any error reporting works as expected.

But ... the above solution wasn't quick - it took more work than I
initially expected.
Am I missing something that makes reusing functions accepting
keyword arguments easier?

/Jens Axel


-- full example --


#lang racket

(require kw-utils/keyword-apply-sort)

(define (fish #:name[name   #f]
  #:color   [color  #f]
  #:studio  [studio #f]
  #:eyes[eyes   2])
  (~a "The fish " name " is " color ", appears in a movie from " studio "
and has " eyes " eyes."))

(fish #:name "Nemo"   #:color "orange" #:studio "Disney")
(fish #:name "Dory"   #:color "blue"   #:studio "Disney")
(fish #:name "Marlin" #:color "orange" #:studio "Disney")
(fish #:name "Blinky" #:color "orange" #:studio "Fox" #:eyes 3)

(define disney-fish
  (let ()
(define (make-disney-fish kws kw-args . rest)
  (keyword-apply/sort fish kws kw-args rest #:studio "Disney"))
(define-values (fish-required fish-allowed) (procedure-keywords fish))
(define fish-arity (procedure-arity fish)) ; number of by-position
arguments
(procedure-reduce-keyword-arity
 (make-keyword-procedure make-disney-fish)
 fish-arity
 (remove '#:studio fish-required)
 (remove '#:studio fish-allowed


(disney-fish #:name "Nemo" #:color "orange"
 #:studio "foo")

; Notes:
; > (disney-fish #:name "Nemo" #:color "orange" #:studio "Disney")
; correctly shows error (#:studio not expected)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CABefVgyXzWW1WJjC9SViyzsheswJD9Ek4LDfwqaNg_v4mT6y%3DQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.