unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* keyword arguments and #:rest
@ 2012-11-10 14:33 Panicz Maciej Godek
  2012-11-10 21:46 ` Ludovic Courtès
  0 siblings, 1 reply; 3+ messages in thread
From: Panicz Maciej Godek @ 2012-11-10 14:33 UTC (permalink / raw)
  To: guile-user

Hello,
I've been writing a function to generate an array of random numbers.
I wanted it to optionally allow specifying the array type (and a few other
things) using keyword arguments. I eventually came up with the following
code:

(define remove-keyword-args
  (letrec ((self (lambda(list)
                   (match list
                     (((? keyword?) (? (?not keyword?)) . rest)
                      (self rest))
                     (((? (?not keyword?) x) . rest)
                      (cons x (self rest)))
                     (((? keyword?) . rest)
                      (self rest)) ; for completeness only
                     (() '())))))
    self))

(define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest dims)
  (let ((dims (remove-keyword-args dims)))
    (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
                (apply make-typed-array type mean dims))))

The problem was, that, as the manual says, "When `#:key' is used
together with a rest argument, the keyword parameters in a call
all remain in the rest list.  This is the same as Common Lisp.",
so I had to get rid of the keywords myself, using the "remove-keyword-args"
procedure defined above.

The thing is that although this suits my case, it isn't a good
sollution in general.
So I thought that maybe there could be another keyword controlling whether
the keywords are left in the rest list or not, so the above code could
look like this:

(define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest
dims #:no-key)
  (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
              (apply make-typed-array type mean dims)))

Wouldn't the world be a better place?
[The semantics I'd expect would be that if #:allow-other-keys is enabled,
those keywords that weren't specified after #:key would still be captured
to the #:rest argument]

Best regards



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: keyword arguments and #:rest
  2012-11-10 14:33 keyword arguments and #:rest Panicz Maciej Godek
@ 2012-11-10 21:46 ` Ludovic Courtès
  2012-11-12 10:19   ` Panicz Maciej Godek
  0 siblings, 1 reply; 3+ messages in thread
From: Ludovic Courtès @ 2012-11-10 21:46 UTC (permalink / raw)
  To: guile-user

Hi,

Panicz Maciej Godek <godek.maciek@gmail.com> skribis:

> So I thought that maybe there could be another keyword controlling whether
> the keywords are left in the rest list or not, so the above code could
> look like this:
>
> (define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest
> dims #:no-key)
>   (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
>               (apply make-typed-array type mean dims)))
>
> Wouldn't the world be a better place?

Perhaps, although that would make the ‘lambda*’ semantics yet more complex.

However, in your example, what about using a list instead of a rest
argument for ‘dims’?

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: keyword arguments and #:rest
  2012-11-10 21:46 ` Ludovic Courtès
@ 2012-11-12 10:19   ` Panicz Maciej Godek
  0 siblings, 0 replies; 3+ messages in thread
From: Panicz Maciej Godek @ 2012-11-12 10:19 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-user

Bonjour!

2012/11/10 Ludovic Courtès <ludo@gnu.org>:
> Hi,
>> So I thought that maybe there could be another keyword controlling whether
>> the keywords are left in the rest list or not, so the above code could
>> look like this:
>>
>> (define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest
>> dims #:no-key)
>>   (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
>>               (apply make-typed-array type mean dims)))
>>
>> Wouldn't the world be a better place?
>
> Perhaps, although that would make the ‘lambda*’ semantics yet more complex.

That's true, but it's only in regard that is already mentioned in the
documentation (and has to be, if we want to avoid confusion). So I
think that in a way this would be a natural extension

> However, in your example, what about using a list instead of a rest
> argument for ‘dims’?

That would also be a solution, but the way it is done now inherits the
interface from make-typed-array, which is one thing less to memoize

Best regards,
Panicz



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-11-12 10:19 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-10 14:33 keyword arguments and #:rest Panicz Maciej Godek
2012-11-10 21:46 ` Ludovic Courtès
2012-11-12 10:19   ` Panicz Maciej Godek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).