* doc srfi-10 #,()
@ 2004-09-01 23:24 Kevin Ryde
0 siblings, 0 replies; only message in thread
From: Kevin Ryde @ 2004-09-01 23:24 UTC (permalink / raw)
A bit of an expansion of the srfi-10 docs, trying to make the quoting
business clearer, and give more examples.
3.1.1 SRFI-10 - Hash-Comma Reader Extension
-------------------------------------------
This SRFI implements a reader extension `#,()' called hash-comma. It
allows the reader to return new kinds of objects, for use both in data
and as constants or literals in source code. This feature is available
with
(use-modules (srfi srfi-10))
The new read syntax is of the form
#,(TAG ARG...)
where TAG is a symbol and the ARGs are objects taken as parameters.
TAGs are registered with the following procedure.
-- Scheme Procedure: define-reader-ctor tag proc
Register PROC as the constructor for a hash-comma read syntax
starting with symbol TAG, ie. #,(TAG arg...). PROC is called with
the given arguments `(PROC arg...)' and the object it returns is
the result of the read.
For example, a syntax giving a list of N copies of an object.
(define-reader-ctor 'repeat
(lambda (obj reps)
(make-list reps obj)))
(display '#,(repeat 99 3))
-| (99 99 99)
Notice the quote ' when the #,( ) is used. The `repeat' handler
returns a list and for the program to use that literally it must be
quoted the same as any other list. Ie.
(display '#,(repeat 99 3))
=>
(display '(99 99 99))
When a handler returns an object which is self-evaluating, like a
number or a string, then there's no need for quoting, just as there's
no need when giving those directly as literals. For example a simple
addition,
(define-reader-ctor 'sum
(lambda (x y)
(+ x y)))
(display #,(sum 123 456)) -| 579
A typical use for #,() is to get a read syntax for objects which
don't otherwise have one. For example, the following allows a hash
table to be given literally, with tags and values, ready for fast
lookup.
(define-reader-ctor 'hash
(lambda elems
(let ((table (make-hash-table)))
(for-each (lambda (elem)
(apply hash-set! table elem))
elems)
table)))
(define (animal->family animal)
(hash-ref '#,(hash ("tiger" "cat")
("lion" "cat")
("wolf" "dog"))
animal))
(animal->family "lion") => "cat"
Or for example the following is a syntax for a compiled regular
expression (*note Regular Expressions::).
(use-modules (ice-9 regex))
(define-reader-ctor 'regexp make-regexp)
(define (extract-angs str)
(let ((match (regexp-exec '#,(regexp "<([A-Z0-9]+)>") str)))
(and match
(match:substring match 1))))
(extract-angs "foo <BAR> quux") => "BAR"
#,() is somewhat similar to `defmacro' (*note Macros::) in that
handler code is run to produce a result, but #,() operates at the read
stage, so it can appear in data for `read' (*note Scheme Read::), not
just in code to be executed.
Because #,() is handled at read-time it has no direct access to
variables etc. A symbol in the arguments is just a symbol, not a
variable reference. The arguments are essentially constants, though
the handler procedure can use them in any complicated way it might want.
Once `(srfi srfi-10)' has loaded, #,() is available globally,
there's no need to use `(srfi srfi-10)' in later modules. Similarly
the tags registered are global and can be used anywhere once registered.
There's no attempt to record what previous #,() forms have been
seen, if two identical forms occur then two calls are made to the
handler procedure. The handler might like to maintain a cache or
similar to avoid making copies of large objects, depending on expected
usage.
In code the best uses of #,() are generally when there's a lot of
objects of a particular kind being used as literals or constants. If
there's just a few then some local variables and initializers are fine,
but that becomes tedious and error prone when there's a lot and the
anonymous and compact syntax of #,() is much better.
_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-09-01 23:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-01 23:24 doc srfi-10 #,() Kevin Ryde
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).