Keywords are a subtype of symbols that are automatically bound to itself. It is extensively used in named arguments (keyword arguments), and keyword-value list.
Keywords used to be a disjoint type from symbols.
Since it isn’t conformant to R7RS, in which symbols can begin
:, we’ve introduced two modes since 0.9.5; keywords
can be a disjoint type of its own, or it can be a subtype of symbols.
The behavior can be switched by environment variables. If the environment
GAUCHE_KEYWORD_DISJOINT is defined when
up, keywords and symbols are disjoint. Otherwise, if the environment
GAUCHE_KEYWORD_IS_SYMBOL is defined, keywords are
a subtype of symbols.
The default behavior when neither environment variables are defined
has been switched since 0.9.8.
GAUCHE_KEYWORD_DISJOINT was assumed
in 0.9.7 and before, while
GAUCHE_KEYWORD_IS_SYMBOL is assumed
in 0.9.8 and after.
Most typical code run in either mode, but there can be some code that behaves differently. See Keyword and symbol integration, for effect of the change.
In future we’ll stop supporting
so we recommend you to ensure applications to run on the current
Read to a keyword whose name is :name.
#t if obj is a keyword.
Returns a keyword whose name is name prepended by
The name argument can be a string or a symbol.
(make-keyword "foo") ⇒ :foo (make-keyword 'foo) ⇒ :foo
Returns the name (without the initial
:) of the keyword keyword, in a string.
(keyword->string :foo) ⇒ "foo"
A useful procedure to extract a value from key-value list. A key-value list kv-list must contains even number of elements; the first, third, fifth … elements are regarded as keys, and the second, fourth, sixth … elements are the values of the preceding keys.
This procedure looks for key from the keys, and if it finds one, it returns the corresponding value. If there are more than one matching keys, the leftmost one is taken. If there is no matching key, it returns fallback if provided, or signals an error otherwise.
It is an error if kv-list is not a proper, even-number element list.
Actually, ‘keywords’ in the keyword-value list and the key argument
need not be a keyword—it can be any Scheme object. Key comparison
is done by
This procedure is taken from STk.
(get-keyword :y '(:x 1 :y 2 :z 3)) ⇒ 2 (get-keyword 'z '(x 1 y 2 z 3)) ⇒ 3 (get-keyword :t '(:x 1 :y 2 :z 3)) ⇒ #<error> (get-keyword :t '(:x 1 :y 2 :z 3) #f) ⇒ #f
get-keyword, but fallback is evaluated only
if kv-list does not have key.
Removes all the keys and values from kv-list for
keys that are
eq? to key.
delete-keyword doesn’t change kv-list, but the returned
list may share the common tail of it.
delete-keyword! doesn’t allocate, and may destructively
changes kv-list. You still have to use the returned value,
for the original list may not be changed if its first key matches
If there’s no key that matches key, kv-list is returned.
(delete-keyword :y '(:x 1 :y 2 :z 3 :y 4)) ⇒ (:x 1 :z 3)
you can specify a list of objects in keys;
when a key in kv-list matches any of keys,
the key and the following value is removed from kv-list.
(delete-keywords '(:x :y) '(:x 1 :y 2 :z 3 :y 4)) ⇒ (:z 3)
|• Keyword and symbol integration:|
In older versions of Gauche, keywords are of disjoint type
from symbols, and they are self-evaluating objects.
To maintain the compatibility, the current Gauche makes
symbols that begins with
: automatically bound to itself.
On the surface it won’t make much difference;
you can write a keyword
:key, which evaluates to itself; so you
can pass and receive keyword arguments just as they used to be.
If you use
:key as variables, however, e.g.
(define :key 3),
the value of
:key in your module changes
(it won’t affect other modules, which refer to the binding of
However, there are several subtle points that do make difference, that breaks compatibility of legacy code. We explain here how to change the code that works in both ways.
If you find a problem in new mode and want to get the old behavior
until you change the code, you can set the environment variable
(symbol? :key)used to return
#f, now returns
keyword? always returns
#t on keywords, but
if you need to switch behavior depending whether an object is a symbol
or a keyword, you should test keyword-ness first.
;; behaved differently in 0.9.7 and before (cond [(symbol? x) (x-is-symbol)] [(keyword? x) (x-is-keyword)]) ;; works on all versions (cond [(keyword? x) (x-is-keyword)] [(symbol? x) (x-is-symbol)])
In the old versions,
when keywords appear in a pattern of
syntax-rules, they only matched to themselves.
In the current version, such keywords in
a pattern are treated as pattern variables, since they are symbols.
;; In the old versions (match '(a b) [(:key z) (list :key z)] [_ "nope"]) ⇒ "nope" ;; In the current version ;; :key is treated just as a pattern variable (match '(a b) [(:key z) (list :key z)] [_ "nope"]) ⇒ (a b)
The same thing happens to the patterns in
To make the code work in both versions, explicitly mark the keywords as literals.
match, quote the keywords you want to be treated as literals.
(match '(a b) [(':key z) (list :key z)] [_ "nope"]) ⇒ "nope"
syntax-rules, list the keywords as literals.
(syntax-rules (:key) [(_ :key z) (list :key z)]) ;etc.
As of Gauche 0.9.5,
match warns if you have unquoted
keywords in match patterns.
(display :key) used to print
key (no colon), while it now
You can use
(display (keyword->string :key)) which prints
in both versions.
Keywords (symbols beginning with
:) are automatically bound to itself
Gauche code inherits the
gauche module by default, which inherits
keyword, so you can see the binding of the keyword by default.
In R7RS code, however, you don’t inherit
so symbols beginning with
: are just ordinary symbols by default.
Usually you do
(import (gauche base)) to use Gauche built-ins,
and that makes binding of
gauche.keyword available in your
code, too (since
But keep this in mind just in case you want to handle keywords in
your R7RS code separate from Gauche procedures—you have to either say
(import (gauche keyword)) to get just the self-bound keywords,
or quote them.
(import (scheme base)) :foo ⇒ ERROR: unbound variable: :foo (import (gauche base)) :foo ⇒ :foo
In the following example, the R7RS library
foo imports only
(gauche base); in that case,
you have to import
(gauche keyword) separately
in order to use
:size keyword without quoting.
:size explicitly in the imported symbol
(define-library (foo) (import (scheme base) (only (gauche base) copy-port) (gauche keyword)) (export cat) (begin (define (cat) (copy-port (current-input-port) (current-output-port) :size 4096))))