This is the mail archive of the
kawa@sourceware.cygnus.com
mailing list for the Kawa project.
Re: workaround for compiling gnu.expr.PrimProcedure literals?
- To: brlewis at alum dot mit dot edu
- Subject: Re: workaround for compiling gnu.expr.PrimProcedure literals?
- From: Per Bothner <per at bothner dot com>
- Date: 26 May 2000 11:38:51 -0700
- Cc: kawa at sourceware dot cygnus dot com
- References: <200005261734.NAA13252@tux.eatonvance.com>
brlewis@alum.mit.edu writes:
> When I try to compile the function below, I get ten errors like this:
>
> (compiling httpfun.scm)
> <unknown>:0: unimplemented support for compiling gnu.expr.PrimProcedure literals
> [...]
We probably should add support for PrimProcedure as a literal.
It is easier now, with the new literal framework: just have
PrimProcedure implement Externalizable, add write suitable
writeExternal/readExternal methods. (I need to document the
details. Basically, there needs to be either a static "make" method
or a constructor whose signature matches the calls made by
writeExternal.)
> Will it work if I rewrite it to use (primitive-interface-method ...)
> only as an argument to a procedure and don't try to assign it to a
> variable?
Not as an argument - only as the function.
> Or can I only use (primitive-interface-method ...) directly
> in procedure application?
You can use (primitive-interface-method ...) otherwise, but
only in interpreted code, as (primitive-interface-method ...) is
a macro that gets expanded at compile-time, yielding a
PrimProcedure. If the PrimProcedure is used in a procedure
application, then it gets inlined to a invokeinterface bytecode
instrcution, but otherwise the PrimProcedure needs to emitted
as a literal - which Kawa current can't do. (But see above.)
Note that using (primitive-interface-method ...) directly in
procedure application (where it can be inlined) is *much* more
effcient, as it does not require reflection.
Actually, I recommend using (invoke ...) instead of
((primitive-interface-method ...) ...) as the former is easier
to read, more compact, and just as efficient.
If you need methods as explicit object, it is more efficient
to use a procedure. For example:
(let ((method
(cond ((eq? cgi-variable 'SERVER_NAME)
(lambda ((req :: <javax.servlet.ServletRequest>))
(invoke req 'getServerName))
...
But better to just invoke the methods.
(lambda ((req :: <javax.servlet.ServletRequest>))
(case cgi-variable
((SERVER_NAME) (invoke req 'getServerName))
((SERVER_PORT) (invoke req 'getServerPort))
(else ...)))
Note the use of case, which should be just as efficient as the
cond-eq-chain you wrote. (While R4RS requires the keys to be
compared using eqv?, it is smart enough to realize that if one
of the operands of an eqv? is a symbol, then it might as well
use the faster eq? instead, since the result is the same.)
--
--Per Bothner
per@bothner.com http://www.bothner.com/~per/