Abstract

This SRFI defines keyword objects, a data type similar to
Scheme symbols. Keyword objects have the same lexical syntax as
symbols but they must end in a colon. Moreover keyword objects
are self-evaluating.
Procedures for converting between strings and keyword objects
(string->keyword and keyword->string)
and a type predicate (keyword?) are defined. Finally
this SRFI specifies the changes to the Scheme lexical syntax required
to accomodate keywords.

Rationale

The motivation for keyword objects stems from the need for markers to
identify optional named parameters, such as in
SRFI 89 (Optional positional
and named parameters). Here we mean ``parameter'' in the general sense
of an API parameter (whether it is a syntactic or procedural API).
Nevertheless we will use the terminology of procedures, namely the
caller and callee, to identify the two sides of the API.

Optional named parameters are useful for APIs with many parameters,
most of which have a reasonable default value. Using optional
positional parameters in this case is not appropriate because it is hard
to remember the position of a particular parameter P and it forces the
caller to supply the values of parameters that come before P, whether
it is the default value or not. Here are a few APIs where optional
named parameters are particularly useful:

The specification of the syntax for expressing optional named
parameter (such as an extension to the parameter list syntax) is left
for another SRFI, such as SRFI
89 (Optional positional and named parameters). This SRFI
only specifies the keyword objects as a datatype.

Several implementations of Scheme currently feature keyword objects,
often modeled after the keyword objects specified in the DSSSL
standard or Common Lisp. Here is a partial list: Bigloo, Chicken,
EdScheme, Gambit, Gauche, Guile, Jade (an implementation of DSSSL),
Kawa, MzScheme, STKlos, and Sizzle.

Unfortunately few of these implementations are compatible. As far as
lexical syntax is concerned, in some implementations the colon must
come at the end (like in DSSSL), in some implementations it must come
at the beginning (as in Common Lisp) possibly prefixed with a hash
sign, and in other cases either at the beginning or end. This SRFI
uses the trailing colon syntax because it does not conflict with
existing Scheme code which use identifiers with leading colon,
such as SRFI 42
(Eager Comprehensions). The main purpose of this SRFI is to help
standardize keyword objects in these implementations and future
implementations that support them.

Specification

Like symbols, keywords are objects whose usefulness rests on the fact
that two keywords are identical (in the sense of eqv?)
if and only if their names are spelled the same way. However,
keywords and symbols are distinct datatypes. No keyword is identical
to a symbol (in the sense of eqv?) or any object of
another datatype.

At the lexical syntax level, keywords look like symbols that end with
a colon. The R5RS lexical syntax category for symbols is
<identifier>. This category must be changed so that
an identifier cannot end with a colon unless the symbol is : (a
symbol consisting of only a colon). The categories
<token> and <simple datum> need to
be extended and the category <keyword object> needs
to be added as follows:

Note that the rule for <keyword object> must be valid
even in Scheme implementations that have extended the
<identifier> syntax to support quoted symbols as
specified in the original specification of
SRFI 75 (R6RS Unicode data).
In other words, in such
implementations, |foo|: and foo: are the
same keyword, and |foo:| is a symbol, not a keyword,
and ||: is a keyword. Using this quoted keyword
lexical syntax all keyword objects produced by the
string->keyword procedure and written with the
write procedure will be read back in with the
read procedure as the identical keyword (in the sense
of eqv?).

Keywords are self evaluating. The syntax of expressions must be
extended by modifying the category <self-evaluating>
to include <keyword object>:

Implementation

The implementation of keyword objects requires changing the reader and
the evaluator. Although the changes are expected to be
straightforward they are obviously highly system dependent. Here we
offer a simplistic `user-level' implementation (a.k.a. kludge) that
will work in Scheme implementations that allow colons anywhere in the
symbol. The following implementation redefines the symbol related
primitives so that symbols ending with a colon are considered to be
keywords, not symbols.

Note that this code does not implement the self-evaluation property of
keyword objects. If the set of keyword objects used by a program is
known in advance, self-evaluation can be simulated with a set of
top-level definitions such as:

(define foo: 'foo:)
(define bar: 'bar:)

Although the implementation presented here is not generally
applicable, it may be useful to bootstrap a complete implementation of
keyword objects in a compiler.

Copyright

Copyright (C) Marc Feeley (2006). All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.