diff --git a/ice-9/optargs.scm b/ice-9/optargs.scm index d9687b47e..9824104a3 100644 --- a/ice-9/optargs.scm +++ b/ice-9/optargs.scm @@ -48,9 +48,9 @@ ;;; Summary of the lambda* extended parameter list syntax (brackets ;;; are used to indicate grouping only): ;;; -;;; ext-param-list ::= [identifier]* [#&optional [ext-var-decl]+]? -;;; [#&key [ext-var-decl]+ [#&allow-other-keys]?]? -;;; [[#&rest identifier]|[. identifier]]? +;;; ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]? +;;; [#:key [ext-var-decl]+ [#:allow-other-keys]?]? +;;; [[#:rest identifier]|[. identifier]]? ;;; ;;; ext-var-decl ::= identifier | ( identifier expression ) ;;; @@ -195,44 +195,15 @@ accum (loop (car rest) (cdr rest) accum))))))) - -;; reader extensions for #&optional #&key #&allow-other-keys #&rest -;; These need to be quoted in normal code, but need not be in -;; an extended lambda-list provided by lambda*, define*, or -;; define*-public (see below). In other words, they act sort of like -;; symbols, except they aren't. They're being temporarily used until -;; #!optional and #!key and such are available. #&rest is provided for -;; the convenience of confused Common Lisp users, even though `.' will -;; do just as well. - -(define the-optional-value - ((record-constructor (make-record-type - 'optional '() (lambda (o p) - (display "#&optional")))))) - -(define the-key-value - ((record-constructor (make-record-type - 'key '() (lambda (o p) - (display "#&key")))))) - - -(define the-rest-value - ((record-constructor (make-record-type - 'rest '() (lambda (o p) - (display "#&rest" p)))))) - -(define the-allow-other-keys-value - ((record-constructor (make-record-type - 'allow-other-keys '() (lambda (o p) - (display "#&allow-other-keys" p)))))) - +;; This is a reader extension to support the (deprecated) use of +;; "#&optional" instead of "#:optional" (read-hash-extend #\& (lambda (c port) (case (read port) - ((optional) the-optional-value) - ((key) the-key-value) - ((rest) the-rest-value) - ((allow-other-keys) the-allow-other-keys-value) + ((optional) #:optional) + ((key) #:key) + ((rest) #:rest) + ((allow-other-keys) #:allow-other-keys-value) (else (error "Bad #& value."))))) @@ -242,7 +213,7 @@ ;; lambda* creates a procedure that takes optional arguments. These ;; are specified by putting them inside brackets at the end of the ;; paramater list, but before any dotted rest argument. For example, -;; (lambda* (a b #&optional c d . e) '()) +;; (lambda* (a b #:optional c d . e) '()) ;; creates a procedure with fixed arguments a and b, optional arguments c ;; and d, and rest argument e. If the optional arguments are omitted ;; in a call, the variables for them are unbound in the procedure. This @@ -250,7 +221,7 @@ ;; ;; lambda* can also take keyword arguments. For example, a procedure ;; defined like this: -;; (lambda* (#&key xyzzy larch) '()) +;; (lambda* (#:key xyzzy larch) '()) ;; can be called with any of the argument lists (#:xyzzy 11) ;; (#:larch 13) (#:larch 42 #:xyzzy 19) (). Whichever arguments ;; are given as keywords are bound to values. @@ -258,7 +229,7 @@ ;; Optional and keyword arguments can also be given default values ;; which they take on when they are not present in a call, by giving a ;; two-item list in place of an optional argument, for example in: -;; (lambda* (foo #&optional (bar 42) #&key (baz 73)) (list foo bar baz)) +;; (lambda* (foo #:optional (bar 42) #:key (baz 73)) (list foo bar baz)) ;; foo is a fixed argument, bar is an optional argument with default ;; value 42, and baz is a keyword argument with default value 73. ;; Default value expressions are not evaluated unless they are needed @@ -268,17 +239,17 @@ ;; ;; lambda*-defined procedures now throw an error by default if a ;; keyword other than one of those specified is found in the actual -;; passed arguments. However, specifying #&allow-other-keys +;; passed arguments. However, specifying #:allow-other-keys ;; immediately after the kyword argument declarations restores the ;; previous behavior of ignoring unknown keywords. lambda* also now ;; guarantees that if the same keyword is passed more than once, the ;; last one passed is the one that takes effect. For example, -;; ((lambda* (#&key (heads 0) (tails 0)) (display (list heads tails))) +;; ((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails))) ;; #:heads 37 #:tails 42 #:heads 99) ;; would result in (99 47) being displayed. ;; -;; #&rest is also now provided as a synonym for the dotted syntax rest -;; argument. The argument lists (a . b) and (a #&rest b) are equivalent in +;; #:rest is also now provided as a synonym for the dotted syntax rest +;; argument. The argument lists (a . b) and (a #:rest b) are equivalent in ;; all respects to lambda*. This is provided for more similarity to DSSSL, ;; MIT-Scheme and Kawa among others, as well as for refugees from other ;; Lisp dialects. @@ -345,27 +316,27 @@ (else (cont lst '() #f)))) (define (parse-opt-and-fixed arglist keys aok? rest cont) (split-list-at - '#&optional arglist + #:optional arglist (lambda (before after split?) (if (and split? (null? after)) - (error "#&optional specified but no optional arguments declared.") + (error "#:optional specified but no optional arguments declared.") (cont before after keys aok? rest))))) (define (parse-keys arglist rest cont) (split-list-at - '#&allow-other-keys arglist + #:allow-other-keys arglist (lambda (aok-before aok-after aok-split?) (if (and aok-split? (not (null? aok-after))) - (error "#&allow-other-keys not at end of keyword argument declarations.") + (error "#:allow-other-keys not at end of keyword argument declarations.") (split-list-at - '#&key aok-before + #:key aok-before (lambda (key-before key-after key-split?) (cond ((and aok-split? (not key-split?)) - (error "#&allow-other-keys specified but no keyword arguments declared.")) + (error "#:allow-other-keys specified but no keyword arguments declared.")) (key-split? (cond - ((null? key-after) (error "#&key specified but no keyword arguments declared.")) - ((memq '#&optional key-after) (error "#&optional arguments declared after #&key arguments.")) + ((null? key-after) (error "#:key specified but no keyword arguments declared.")) + ((memq #:optional key-after) (error "#:optional arguments declared after #:key arguments.")) (else (parse-opt-and-fixed key-before key-after aok-split? rest cont)))) (else (parse-opt-and-fixed arglist '() #f rest cont))))))))) (define (parse-rest arglist cont) @@ -377,17 +348,17 @@ (lp (last-pair copy)) (ra (cdr lp))) (set-cdr! lp '()) - (if (memq '#&rest copy) - (error "Cannot specify both #&rest and dotted rest argument.") + (if (memq #:rest copy) + (error "Cannot specify both #:rest and dotted rest argument.") (parse-keys copy ra cont)))) (else (split-list-at - '#&rest arglist + #:rest arglist (lambda (before after split?) (if split? (case (length after) - ((0) (error "#&rest not followed by argument.")) + ((0) (error "#:rest not followed by argument.")) ((1) (parse-keys before (car after) cont)) - (else (error "#&rest argument must be declared last."))) + (else (error "#:rest argument must be declared last."))) (parse-keys before #f cont))))))) (parse-rest arglist cont)) @@ -401,16 +372,16 @@ ;; define* and define*-public support optional arguments with ;; a similar syntax to lambda*. They also support arbitrary-depth ;; currying, just like Guile's define. Some examples: -;; (define* (x y #&optional a (z 3) #&key w . u) (display (list y z u))) +;; (define* (x y #:optional a (z 3) #:key w . u) (display (list y z u))) ;; defines a procedure x with a fixed argument y, an optional agument ;; a, another optional argument z with default value 3, a keyword argument w, ;; and a rest argument u. -;; (define-public* ((foo #&optional bar) #&optional baz) '()) +;; (define-public* ((foo #:optional bar) #:optional baz) '()) ;; This illustrates currying. A procedure foo is defined, which, ;; when called with an optional argument bar, returns a procedure that ;; takes an optional argument baz. ;; -;; Of course, define*[-public] also supports #&rest and #&allow-other-keys +;; Of course, define*[-public] also supports #:rest and #:allow-other-keys ;; in the same way as lambda*. (defmacro-public define* (ARGLIST . BODY) @@ -442,10 +413,10 @@ ;; defmacro and defmacro-public extended for optional and keyword arguments ;; ;; These are just like defmacro and defmacro-public except that they -;; take lambda*-style extended paramter lists, where #&optional, -;; #&key, #&allow-other-keys and #&rest are allowed with the usual +;; take lambda*-style extended paramter lists, where #:optional, +;; #:key, #:allow-other-keys and #:rest are allowed with the usual ;; semantics. Here is an example of a macro with an optional argument: -;; (defmacro* transmorgify (a #&optional b) +;; (defmacro* transmorgify (a #:optional b) (defmacro-public defmacro* (NAME ARGLIST . BODY) (defmacro*-guts 'define NAME ARGLIST BODY))