[PATCH] Add more flexible instantiation syntax for `new`

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Fri Feb 1 15:09:51 EST 2013

---
 collects/racket/private/class-internal.rkt |   41 ++++++++++++++++------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/collects/racket/private/class-internal.rkt b/collects/racket/private/class-internal.rkt
index 2c03780..57d08e7 100644
--- a/collects/racket/private/class-internal.rkt
+++ b/collects/racket/private/class-internal.rkt
@@ -3808,24 +3808,31 @@ An example
 ;;  instantiation
 ;;--------------------------------------------------------------------
 
+;; class instantiation syntax, allows mixed keywords and positionals
 (define-syntax (new stx)
-  (syntax-case stx ()
-    [(_ cls (id arg) ...)
-     (andmap identifier? (syntax->list (syntax (id ...))))
-     (quasisyntax/loc stx
-       (instantiate cls () (id arg) ...))]
-    [(_ cls (id arg) ...)
-     (for-each (lambda (id)
-                 (unless (identifier? id)
-                   (raise-syntax-error 'new "expected identifier" stx id)))
-               (syntax->list (syntax (id ...))))]
-    [(_ cls pr ...)
-     (for-each
-      (lambda (pr)
-        (syntax-case pr ()
-          [(x y) (void)]
-          [else (raise-syntax-error 'new "expected name and value binding" stx pr)]))
-      (syntax->list (syntax (pr ...))))]))
+  (syntax-parse stx
+    [(_ cls arg ...)
+     (define-values (kw-args pos-args)
+       (parse-init-args #'(arg ...)))
+     (with-syntax ([(kw ...) kw-args]
+                   [(pos ...) pos-args])
+      (quasisyntax/loc stx
+        (instantiate cls (pos ...) kw ...)))]))
+
+(begin-for-syntax
+ ;; listof<syntax> -> (values listof<syntax> listof<syntax>)
+ ;; parses arguments for `new` and collects them into two lists
+ (define (parse-init-args stx)
+   (define stxs (syntax->list stx))
+   (define-values (kw-args pos-args)
+     (for/fold ([kw-args '()]
+                [pos-args '()])
+               ([stx stxs])
+       (syntax-parse stx
+         [(kw:id arg)
+          (values (cons stx kw-args) pos-args)]
+         [arg (values kw-args (cons stx pos-args))])))
+   (values kw-args (reverse pos-args))))
 
 (define ((make-object/proc blame) class . args)
   (do-make-object blame class args null))
-- 
1.7.10.4


--Fba/0zbH8Xs+Fj9o--

Posted on the dev mailing list.