* Prevent keyword argumets from appearing in the rest
@ 2016-09-21 13:58 Panicz Maciej Godek
2016-09-21 17:05 ` Panicz Maciej Godek
0 siblings, 1 reply; 2+ messages in thread
From: Panicz Maciej Godek @ 2016-09-21 13:58 UTC (permalink / raw)
To: guile-user@gnu.org
Hi,
is there any way to prevent the defined keyword arguments from appearing in
the "rest" argument list?
For example, if I have a definition
(define* (f #:key (a 1) (b 2) (c 3) #:allow-other-keys . rest)
rest)
I would like (f #:a 5 #:d 6) to return (#:d 6) rather than (#:a 5 #:d 6)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Prevent keyword argumets from appearing in the rest
2016-09-21 13:58 Prevent keyword argumets from appearing in the rest Panicz Maciej Godek
@ 2016-09-21 17:05 ` Panicz Maciej Godek
0 siblings, 0 replies; 2+ messages in thread
From: Panicz Maciej Godek @ 2016-09-21 17:05 UTC (permalink / raw)
To: guile-user@gnu.org
For the record, I eventually came up with the following code:
(define-module (extra define-keywords)
#:use-module (ice-9 nice-9)
#:use-module (extra attributes)
#:replace ((define/keywords . define*)))
(define-syntax define/keywords
(lambda (x)
(define* (required args #:optional (gathered '()))
(match args
(((? symbol?) #:= . _)
(values (reverse gathered) args))
(((? symbol? s) . rest)
(required rest `(,s . ,gathered)))
(_
(values (reverse gathered) args))))
(define* (optional args #:optional (gathered '()))
(match args
(((? symbol? s) #:= value . rest)
(optional rest `((,s ,value) . ,gathered)))
(_
(values (reverse gathered) args))))
(define* (keyword args #:optional (gathered '()))
(match args
(((? keyword? k) (? symbol? s) #:= value . rest)
(keyword rest `((,s ,value ,k) . ,gathered)))
(((? keyword? k) (? symbol? s) . rest)
(keyword rest `((,s #f ,k) . ,gathered)))
(_
(values (reverse gathered) args))))
(define (required+optional+keyword+rest+keys args)
(let* ((required args* (required (syntax->datum args)))
(optional args** (optional args*))
(keyword rest (keyword args**))
(((names values keys) ...) keyword))
(datum->syntax x `(,required ,optional ,keyword ,rest ,keys))))
(syntax-case x ()
((_ (proc . args) body ...)
(with-syntax ((((required ...) (optional ...) (keyword ...) rest
keys)
(required+optional+keyword+rest+keys #'args)))
#'(define proc
(lambda* (required ... #:optional optional ...
#:key keyword ...
#:allow-other-keys . rest)
(let ((rest (remove-attributes 'keys rest)))
body ...))))))))
In addition to removing the supported keywords from the "rest" list, it
provides an alternative (incompatible) syntax for optional and keyword
arguments:
(define* (f r1 r2 r3 opt1 #:= 1 opt2 #:= 2 #:key1 k1 #:key2 k2 #:= 7)
...)
where r1, r2 and r3 are required, opt1 and opt2 optional (with default
values of 1 and 2, respectively), and variables k1 and k2 are accessible
via #:key1 and #:key2 keywords, where in addition k2 has a default value 7.
I'm not sure whether the use of #:= keyword is a good idea -- probably not.
But I'm not a big fan of the current syntax either.
The definition requires the (ice-9 nice-9) library, which -- traditionally
-- can be found here:
https://github.com/panicz/pamphlet/blob/master/libraries/ice-9/nice-9.scm
In addition, it requires a definition of "remove-attributes":
(define (remove-attributes attributes #;from attribute-list)
(match attribute-list
(((? keyword? key) value . rest)
(if (member key attributes)
(remove-attributes attributes rest)
`(,key ,value . ,(remove-attributes attributes #;from rest))))
(_
attribute-list)))
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-09-21 17:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-09-21 13:58 Prevent keyword argumets from appearing in the rest Panicz Maciej Godek
2016-09-21 17:05 ` 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).