Christopher R. Barry <cbarry@2xtreme.net> wrote:
+---------------
| Tim Bradshaw <tfb@tfeb.org> writes:
| > Are you aware how scheme does optional arguments? I guess not.
|
| I know how scheme does &rest arguments:
| ((lambda (x . y) (list x y)) 1 2 3 4 5) => (1 (2 3 4 5))
| I don't know how to do &optional or &key ones, however. Do enlighten me.
+---------------
You can of course "do" &optional and &key (or rather, provide somewhat
similar functionality) with explicit post-processing of the &rest argument
in your function. [Note: In Scheme, most people use simple symbols with
no colon prefix as "keywords", though MzScheme provides an explicit
"keyword" datatype that may be helpful.] This is made much more readable
(but certainly no faster) by using convenience routines, so that you could
write the CL function:
(defun foo (a b c &key d (e 123) (f 456 f-p))
... )
in Scheme like this, maybe:
(define (foo a b c . rest)
(let ((d (key-value rest 'd))
(e (key-value rest 'e 123))
(f (key-value rest 'f 456))
(f-p (key-present? rest 'f)))
... ))
Or assuming you had non-hygenic macros available (such as "defmacro",
which most Schemes either have or can craft up out of whatever low-level
macros they *do* have), you might decide that by convention your macro
would capture the variable name "rest", and write something like this:
(define (foo a b c . rest)
(with-parsed-keys (d (e 123) (f 456 f-p))
... ))
As far as &optional goes, if you use explicit parsing you usually
have to manually supply an index, e.g., from some actual code I wrote
a long time ago (before I knew that CL called them &optional, or I
might have called the helper function "opt-value" instead of "dlft")
(define (dump . rest) ; &optional addr size
(let* ((addr (dflt rest 0 dump-prev-addr))
(size (dflt rest 1 dump-prev-size))
(j (modulo addr 16)))
...))
Or, as above, with macro support:
(define (dump . rest) ; &optional addr size
(with-parsed-optionals ((addr dump-prev-addr)
(size dump-prev-size))
... ))
[Or even knock yourself out and write a "defun" macro that does it all
for you automatically...] ;-} ;-}
Yes, it's ugly. Yes, CL does it better, and it's all IN THE STANDARD!
But also, yes, with a little macrology[*] one can approximate the
convenience even in Scheme.
-Rob
[*] And SIOD *does* have just enough of a macro facility to enable
defining "defmacro", and hence be able to write in the above style.
And with a bunch of work (once), you can even use SIOD's macros to
get (almost) all of the R4RS syntax.
-----
Rob Warnock, 8L-846 rpw3@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
1600 Amphitheatre Pkwy. FAX: 650-933-0511
Mountain View, CA 94043 PP-ASEL-IA