Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

&optional with &key

26 views
Skip to first unread message

Adam Warner

unread,
Dec 10, 2002, 2:45:11 AM12/10/02
to
Hi all,

Before I knew about &key I was using &rest to parse keyword parameters.
I could parse a URI in these three forms:

1. (a :href "uri")
2. (a :href "uri" "description")
3. (a "description" :href "uri")

I simply returned all keyword-value pairs in one list and non-keyword
arguments in another for processing.

I've now got many in the second form because I converted the URIs
automatically from the HTML syntax <a href="uri">description</a>.

While duplicating the second form using inbuilt Lisp functionality doesn't
appear possible (an &optional after &key is misplaced), I can't even work
out how to specify the first and third forms without using &rest and
parsing the input myself.

This doesn't work...

(defun a (&optional desc &key href) (write desc) (write href))

...because desc can't be omitted when :href is specified (it leads to the
error "Function called with odd number of keyword arguments.")

I'd like to know how far I can go to provide such variation in input
without having to resort to using &rest and then parsing the resulting
list myself.

Thanks,
Adam

Rob Warnock

unread,
Dec 10, 2002, 6:40:03 AM12/10/02
to
Adam Warner <use...@consulting.net.nz> wrote:
+---------------

| Before I knew about &key I was using &rest to parse keyword parameters.
| I could parse a URI in these three forms:
| 1. (a :href "uri")
| 2. (a :href "uri" "description")
| 3. (a "description" :href "uri")
...

| This doesn't work...
| (defun a (&optional desc &key href) (write desc) (write href))
...
| I'd like to know how far I can go to provide such variation in input
| without having to resort to using &rest and then parsing the resulting
| list myself.
+---------------

If you can make one massive search & replace edit over your corpus
and replace all occurences of #2 & #3 with the following alternatives,
life might become a lot simpler for you:

2'. (a :href "uri" :text "description")
3'. (a :text "description" :href "uri")


-Rob

p.s. I replied only because I've been using Tim Bradshaw's HTOUT macro
a lot recently, and he similarly finesses the inverse problem -- what to
do about an HTML attribute that has no value. His solution: Force the Lisp
keyword to be provided an explicit value of NIL in that case, e.g.:

((:ul :compact nil) ; outputs <UL COMPACT>
:li "First item."
:li "Second item.")

p.p.s. In HTOUT, one writes #2 as:

((:a :href "uri") "description")

which is yet another solution that works.

-----
Rob Warnock, PP-ASEL-IA <rp...@rpw3.org>
627 26th Avenue <URL:http://www.rpw3.org/>
San Mateo, CA 94403 (650)572-2607

Tim Bradshaw

unread,
Dec 10, 2002, 7:37:03 AM12/10/02
to
* Rob Warnock wrote:
> p.s. I replied only because I've been using Tim Bradshaw's HTOUT macro
> a lot recently, and he similarly finesses the inverse problem -- what to
> do about an HTML attribute that has no value. His solution: Force the Lisp
> keyword to be provided an explicit value of NIL in that case, e.g.:

> ((:ul :compact nil) ; outputs <UL COMPACT>
> :li "First item."
> :li "Second item.")

I'd forgotten that, but it seems like a good approach to me (well, it
would...).

> p.p.s. In HTOUT, one writes #2 as:

> ((:a :href "uri") "description")

> which is yet another solution that works.

I use this notation for the public HTOUT because it makes the common
no-attribute case easy to type, and HTOUT was designed (well, evolved)
in the expectation that people would be typing a fair amount of
lisp-format HTML (indeed, I wrote a whole lisp course in this format -
it's easier to type than real HTML even with all the strings...). In
the case where the sexp representation is being machine-generated, I
now (in a not-yet-public descendent of HTOUT) use a notation like:

(tag attributes &rest body)

where attributes is a keyword attribute list. So:

(a (:href "foo") "bar")

The disadvantage of this for stuff where you want to really type a lot
of lispy HTML is that you have a lot of (:p () ...) type stuff. The
advantage is that it's much more Lispy - the car of the form is the
`function' which does the work (and indeed, there are `macros' which
do transformation on this representation, so:

(tocify (...)
(h1 () ...)
...)

does what you might expect.

--tim


0 new messages