This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: Upgrading kawa from 1.8 to latest SVN
- From: Per Bothner <per at bothner dot com>
- To: Margus Freudenthal <margus at cyber dot ee>
- Cc: kawa at sources dot redhat dot com
- Date: Mon, 04 Dec 2006 07:40:39 -0800
- Subject: Re: Upgrading kawa from 1.8 to latest SVN
- References: <45741BA6.6050002@cyber.ee>
Margus Freudenthal wrote:
Recently our company started to experiment with kawa (we create biggish
Java-based enterprise information systems) and so far we have very
positive experience with it. Our code base is now much smaller and
readable.
Welcome to the club!
Initially we used kawa version 1.8, but now I tried to upgrade to latest
SVN trunk. Now, with recent version, there are problems with building
the project. We have fair amount of defmacro-s that generate code
interfacing with Java API-s.
> With latest SVN version, this part does not work:
[java]
/home/margus/dev/icis/kawa-iglu/src/java/ee/cyber/iglu/model/tirstates/tiractions.scm:113:9:
warning - no declaration seen for
<ee.cyber.iglu.common.ReflectionHelper>:createPath
[java]
...
Any ideas about where to look for solution?
Yes. Stop using defmacro. Here are snippets of a longer
explanation I wrote earlier this year [in private email]:
Background: The Scheme reader translates:
foo:bar
into:
($lookup$ foo (quote bar))
When this form is inside a quote, then the quote-expander
(which is actually non-trivial) first looks for a known
namespace (in which case if creates a symbol in that namespace),
and if that fails it creates a symbol in the default namespace
identical to (string->symbol "foo:bar"). This transformation
is needed for compatibility with "legacy" code that doesn't
treat colon as a special operator. If the 'foo:bar symbol is then
returned by a defmacro, then the compiler has to undo this
transformation, and re-create the original ($lookup$ foo (quote bar)).
This may be difficult and it's questionale whether it makes sense.
I *really* *really* want you guys to stop using defmacro. It's a
bad idea for many reasons. One is that it is non-standard. The
standard is to use hygienic macros. R6RS will include syntax-case.
Supporting defmacro is a hack, which has to be secondary to supporting
hygienic macros. Non-hygienic macros in addition to the well-known
problems of unintentional name clashes also have the fundamental
problem that they *lose* information: The input to the macro expander
consists of "syntax forms" which also includes context information
including lexical information and line/column position. If you use
defmacro you're working with raw symbols yso ou lose this information,
and trying it get it back may be difficult and lead to unreliable macros.
Admittedly, syntax-case forms are somewhat awkward and verbose.
Can I suggest a wrapper macro:
(define-syntax define-syntax-case
(syntax-rules ()
((define-syntax-case name literals . parts)
(define-syntax name
(lambda form
(syntax-case form literals . parts))))))
The define-syntax-case form takes a name, a list of literals
(just like syntax-rules), and zero or more cases. Each case
is a pattern (just as in syntax-rules) followed by an
expression evaluated at macro-expand-time that evaluates to
a syntax form. This is juts like the body of a syntax-case.
The #' and #` reader forms are taken from SRFI-72.
#'FORM is syntactic sugar for (syntax FORM).
#`FORM is like #`FORM except you can "unquote" using comma.
These make it easy to write macros. Typically, you can translate:
(defmacro (NAME PATTERN-VAR ...) `(... PATTERN_VAR ...))
to:
(define-syntax-case NAME ()
((_ PATTERN_VAR ...) #`(... PATTERN_VAR ...))
and:
(defmacro (NAME ...)
(let ... `(... ,EXP ...)))
to:
(define-syntax-case NAME ()
((_ ...) (let #`(... EXP ...))))
--
--Per Bothner
per@bothner.com http://per.bothner.com/