unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* 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).