From: ······@bridgetrix.com
Subject: Translating Lisp to Java
Date: 
Message-ID: <ncohen-2208001201390001@max3-56.ip.realtime.net>
I have 50 pages of Lisp code that I need translated to Java.  Are there
Lisp to java translators about?   

  If anyone is interested in doing the translation, please e-mail me with
salary requirements.  The code is well documented, but a knowledge of
bridge might be hlpful.  The program interprets a data file to play a hand
of bridge.  Basically, the program tells how to play basic bridge.  The
data file contains special instructions.  I need it done in a month or
two.

     Neil

Neil Cohen
Bridge Trix
Producers of the Bobby Wolff Bridge Mentoring Series

From: The Glauber
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <8numvn$a7o$1@nnrp1.deja.com>
In article <·······················@max3-56.ip.realtime.net>,
  ······@bridgetrix.com wrote:
> I have 50 pages of Lisp code that I need translated to Java.  Are there
> Lisp to java translators about?


There's a few Scheme compilers that output Java. Maybe that can get you
started. (By coincidence, 50 is also the number of pages in the Scheme
language spec! :-) ).

Kawa seems to be very good (my knowledge of Schems is limited).
http://www.gnu.org/software/kawa/
--
Glauber Ribeiro
··········@my-deja.com    http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.
From: David Bakhash
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <m3hf8d892o.fsf@cadet.dsl.speakeasy.net>
The Glauber <··········@my-deja.com> writes:

> In article <·······················@max3-56.ip.realtime.net>,
>   ······@bridgetrix.com wrote:
> > I have 50 pages of Lisp code that I need translated to Java.  Are there
> > Lisp to java translators about?

> Kawa seems to be very good (my knowledge of Schems is limited).
> http://www.gnu.org/software/kawa/

I don't think that Kawa will cut it, and even if it did, that just
produces the bytecodes.  I'm guessing that the original poster wants
readable Java source.

dave
From: Dowe Keller
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <slrn8q6pee.9id.dowe@localhost.localdomain>
On 22 Aug 2000 14:06:07 -0400, David Bakhash <·····@alum.mit.edu> wrote:
>The Glauber <··········@my-deja.com> writes:

>I don't think that Kawa will cut it, and even if it did, that just
>produces the bytecodes.  I'm guessing that the original poster wants
>readable Java source.
 ^^^^^^^^
I don't know about you, but I've never seen a lang converter that produces
anything like readable source code, it may be legal source code for the
target language, but I wouldn't want to have to maintain it.

-- 
····@sierratel.com		http://www.sierratel.com/dowe
From: Philip Lijnzaad
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <u7g0nwmkod.fsf@o2-3.ebi.ac.uk>
Dowe> I don't know about you, but I've never seen a lang converter that produces
Dowe> anything like readable source code.

Dave Gillespie's p2c (Pascal to C) compiler produces very readable code
indeed; even the comments are translated and put in the right places. But
Pascal and C is admittedly a close match. 
                                                                      Philip
-- 
When C++ is your hammer, everything looks like a thumb. (Steven Haflich)
-----------------------------------------------------------------------------
Philip Lijnzaad, ········@ebi.ac.uk \ European Bioinformatics Institute,rm A2-24
+44 (0)1223 49 4639                 / Wellcome Trust Genome Campus, Hinxton
+44 (0)1223 49 4468 (fax)           \ Cambridgeshire CB10 1SD,  GREAT BRITAIN
PGP fingerprint: E1 03 BF 80 94 61 B6 FC  50 3D 1F 64 40 75 FB 53
From: Kent M Pitman
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <sfwem3g0z5i.fsf@world.std.com>
Philip Lijnzaad <········@ebi.ac.uk> writes:

> Dowe> I don't know about you, but I've never seen a lang converter
> Dowe> that produces anything like readable source code.
> 
> Dave Gillespie's p2c (Pascal to C) compiler produces very readable code
> indeed; even the comments are translated and put in the right places. But
> Pascal and C is admittedly a close match. 

Indeed.  When I did my work with Fortran->Lisp translation, I puzzled over
the difference between the terms "translation" and "compilation".  I
concluded that something is typically regarded as translation if it
produces something that is structurally similar and which can rely on
a similar core subroutine base in the target to what it had in the 
original, such that abstractions are roughly preserved.  By contrast,
the term "compilation" as it's often used permits the compiler to destroy
abstractions as long as the effect is preserved.  In the terminology as
I personally came to think of it, what you're saying is that Pascal can
be translated to C, but Lisp can in the general case only be compiled to 
Java.  

I suspect others will see this differently.  I guess partly my post here
is to invite alternate points of view on the meaning of these puzzling
terms.
From: Xenophon Fenderson the Carbon(d)ated
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <w4owvh7fh36.fsf@lovecraft.irtnog.org>
>>>>> "Kent" == Kent M Pitman <······@world.std.com> writes:

    Kent> I suspect others will see this differently.  I guess partly
    Kent> my post here is to invite alternate points of view on the
    Kent> meaning of these puzzling terms.

Actually, in my compilers class, the terms "interpretation",
"compilation", and "translation" had identical definitions.  These are
all "conversion from one representation into another".  A compiler
need not generate machine code (e.g. byte-code compilers), and a
translator from FORTRAN-77 into assembly language is really no
different (in a "Church" kind of way) from a translator from
FORTRAN-77 to C.

I think the differences in the use of those three words is mostly that
of connotation.

-- 
"An object at rest cannot be stopped!"
 --The Evil Midnight Bomber What Bombs at Midnight
From: Kent M Pitman
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <sfw7l97p6vw.fsf@world.std.com>
········@irtnog.org (Xenophon Fenderson the Carbon(d)ated) writes:

> >>>>> "Kent" == Kent M Pitman <······@world.std.com> writes:
> 
>     Kent> I suspect others will see this differently.  I guess partly
>     Kent> my post here is to invite alternate points of view on the
>     Kent> meaning of these puzzling terms.
> 
> Actually, in my compilers class, the terms "interpretation",
> "compilation", and "translation" had identical definitions.  These are
> all "conversion from one representation into another".  A compiler
> need not generate machine code (e.g. byte-code compilers), and a
> translator from FORTRAN-77 into assembly language is really no
> different (in a "Church" kind of way) from a translator from
> FORTRAN-77 to C.

Well, interpreters I regard as strictly different since late-binding vs
early-binding can yield computationally different effects.  For example,
in CL, if you have an interpreted definition like:

 (defun foo (x) (if x (bar) (bar)))

and bar is a macro and you execute (foo t) and then redefine bar
before doing (foo nil), it's conceivable that the IF will cache
different definitions because the else branch will pick up the new
definition while the then branch holds the old.  Depends on the
implementation.  I don't usually expect the compiler/translator
situation to do that, since both are one-time syntactic analysis prior
to execution.

> I think the differences in the use of those three words is mostly that
> of connotation.

Even so, I'm curious about the connotational differences.
From: Jeff Dalton
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <x2k8d5lctj.fsf@todday.aiai.ed.ac.uk>
········@irtnog.org (Xenophon Fenderson the Carbon(d)ated) writes:

> Actually, in my compilers class, the terms "interpretation",
> "compilation", and "translation" had identical definitions.  These are
> all "conversion from one representation into another".

What conversion from one representation into another does an
interpreter for a programming language perform?

Consider a typical simple Lisp interpreter in Lisp, callable
as EVAL.  In a READ-EVAL-PRINT loop, all the conversions are done
by READ and PRINT.  Sure, you might argue that turning a function
call into its value is a "conversion", and that any output produced
by a call to some output function is a "conversion" of the function
call into some output, but that seems a pretty desperate move to me.

> A compiler
> need not generate machine code (e.g. byte-code compilers), and a
> translator from FORTRAN-77 into assembly language is really no
> different (in a "Church" kind of way) from a translator from
> FORTRAN-77 to C.

No interpreter example, I note.

> I think the differences in the use of those three words is mostly that
> of connotation.

For "compilation" and "transdlation" maybe.
From: Xenophon Fenderson the Carbon(d)ated
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <w4og0ns7v3w.fsf@lovecraft.irtnog.org>
>>>>> "Jeff" == Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:

    Jeff> What conversion from one representation into another does an
    Jeff> interpreter for a programming language perform?

An interpreter translates a program into machine code, just like a
compiler.  Consider a simplified Lisp interpreter that only handles
addition.  "(+ 2 3)" must, somewhere along the line between parsing
and printing, be computed.  If "+" is implemented as a call to the
hosting language's addition function (the easy way), this very quickly
becomes a call to the host processor's addition operation.  If "+" is
implemented in some simulated Turing machine (e.g. with a series of
branch-if-equal and set operations), this very slowly becomes calls to
the branch-if-equal and set operations of the host processor.  Either
way, one representation (in this case, ASCII encoding) is converted to
another (the host machine's instruction stream).  Generating one's own
machine code is, in a Church-Rosser sense, not much different.

(If posting a sample interpreter helps me make my point to you, just
say the word and I'll dredge out a Scheme meta-interpreter (hopefully
not too risque for this venerable newsfroup) and show you how the
primitive operations +, -, etc. were calls to the hosting Scheme,
which must, eventually, become instructions executed by the hosting
processor.)

Defining both "interpreter" and "compiler" as "something that
transforms code from one representation into another" is, from this
perspective, completely correct.  The thoughts that with a compiler
one can save this machine code to disk and that usually the machine
code compilers generate much faster than interpreters are merely
connotation (and interpreters which effectively dump core to create
executables, such as GNU Emacs, blurs this line between compilers even
more effectively).

Satisfied?

    Jeff> No interpreter example, I note.

Oh, I'm a hypocrite, of course, and was purposefully trying to mislead
the gentle reader with what could be also be interpreted (har har) as
an inadvertent omission.  Sell out early and often, that's my motto!
Praise "Obo"!!!

Or maybe the simplest explaination really IS the correct one, that I
thought I'd made my point enough and didn't bother mentioning that
Emacs, an interpreter by everyone's defintion, turns a whole chunck of
so-called interpreted code into a perfectly valid executable file
(which, gosh, is what a compiler does!)

You'd think that by know I would know better than to get caught up in
an argument about definitions.  Don't bother, I'll *plonk* me myself.

-- 
... [L]oad averages on moe were extremely high (above 3 ) because lightss
seems to think he can solve for world peace by brute force using magma.
        -- Joe Boyd
From: Eugene Zaikonnikov
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <6yzom1f3nt.fsf@localhost.localdomain>
>>>>> "Jeff" == Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:

    Jeff> ········@irtnog.org (Xenophon Fenderson the Carbon(d)ated)
    Jeff> writes:

[...]

    >> I think the differences in the use of those three words is
    >> mostly that of connotation.

    Jeff> For "compilation" and "transdlation" maybe.

AFAIK 'translation' is often used as a generic substitute for both
interpretation and compilation, denoting process required to execute
a program described in a high-level language.

--
  Eugene.
From: Christopher Browne
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <0ukp5.289226$t91.3062977@news4.giganews.com>
Centuries ago, Nostradamus foresaw a time when Xenophon Fenderson the
Carbon(d)ated would say: 
>>>>>> "Kent" == Kent M Pitman <······@world.std.com> writes:
>    Kent> I suspect others will see this differently.  I guess partly
>    Kent> my post here is to invite alternate points of view on the
>    Kent> meaning of these puzzling terms.
>
>Actually, in my compilers class, the terms "interpretation",
>"compilation", and "translation" had identical definitions.  These are
>all "conversion from one representation into another".  A compiler
>need not generate machine code (e.g. byte-code compilers), and a
>translator from FORTRAN-77 into assembly language is really no
>different (in a "Church" kind of way) from a translator from
>FORTRAN-77 to C.
>
>I think the differences in the use of those three words is mostly that
>of connotation.

If the words truly were identical in meaning, there would be no need
to have the three words.  Were that so, I'd prefer to replace them all
with the mathematical term "transformation," which can involve
arbitrary changes.

In the context of human languages, interpretation tends to be a thing
done "on the fly," where one person says a few words, and the
interpreter repeats them in the destination language.  In contrast,
translation is usually performed "offline," where the translator does
the conversion on a complete document.  

The distinction there is that interpretation is a more "dynamic"
action than translation, and that seems to fit reasonably well with
the distinctions between "interpretive" and "translating"
environments.

And "compilation," outside of computing, has the connotation of being
a more "by-rote" sort of transformation than either interpretation or
translation.  I'd consider that that doesn't fit too badly with the
meaning usually attributed to the computing context.
-- 
(concatenate 'string "cbbrowne" ·@" "acm.org")
<http://www.ntlug.org/~cbbrowne/linux.html>
"Just because it's free doesn't mean you can afford it."  -- Unknown
From: Christopher Browne
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <kWGp5.14931$g53.280302@news5.giganews.com>
Centuries ago, Nostradamus foresaw a time when Xenophon Fenderson the
Carbon(d)ated would say: 
>>>>>> "Kent" == Kent M Pitman <······@world.std.com> writes:
>    Kent> I suspect others will see this differently.  I guess partly
>    Kent> my post here is to invite alternate points of view on the
>    Kent> meaning of these puzzling terms.
>
>Actually, in my compilers class, the terms "interpretation",
>"compilation", and "translation" had identical definitions.  These are
>all "conversion from one representation into another".  A compiler
>need not generate machine code (e.g. byte-code compilers), and a
>translator from FORTRAN-77 into assembly language is really no
>different (in a "Church" kind of way) from a translator from
>FORTRAN-77 to C.
>
>I think the differences in the use of those three words is mostly that
>of connotation.

If the words truly were identical in meaning, there would be no need
to have the three words.  Were that so, I'd prefer to replace them all
with the mathematical term "transformation," which can involve
arbitrary changes.

In the context of human languages, interpretation tends to be a thing
done "on the fly," where one person says a few words, and the
interpreter repeats them in the destination language.  In contrast,
translation is usually performed "offline," where the translator does
the conversion on a complete document.  

The distinction there is that interpretation is a more "dynamic"
action than translation, and that seems to fit reasonably well with
the distinctions between "interpretive" and "translating"
environments.

And "compilation," outside of computing, has the connotation of being
a more "by-rote" sort of transformation than either interpretation or
translation.  I'd consider that that doesn't fit too badly with the
meaning usually attributed to the computing context.
-- 
(concatenate 'string "cbbrowne" ·@" "acm.org")
<http://www.ntlug.org/~cbbrowne/linux.html>
"Just because it's free doesn't mean you can afford it."  -- Unknown
From: Fernando D. Mato Mira
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <39AD9B0B.466C6B7C@iname.com>
Kent M Pitman wrote:

> Indeed.  When I did my work with Fortran->Lisp translation, I puzzled over

> I suspect others will see this differently.  I guess partly my post here
> is to invite alternate points of view on the meaning of these puzzling
> terms.

I would think that the underlying reason for prefering one term over the
other
in different situations is the relative richness of the target language,
ie,
there's a threshold where this is comparatively so lower-level that you
stop sayin "translation" and you start saying "compilation"

Example:

Fortran -> Lisp : translation
C -> Pascal : translation
Java -> C++ : translation
CL -> Java (not JVM): fuzzy tending to translation
CL -> C++ : fuzzy tending to compilation
Lisp -> C: compilation
Scheme with call/cc -> Java : compilation

Scheme with call/cc -> CL : compilation, interpretation

-- 
Fernando D. Mato Mira			   Phone    : +41 (78) 778 FDMM
 				           E-mail   : matomira AT acm DOT org
From: Christian Lynbech
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <87k8d2wpuh.fsf@ericssontelebit.com>
>>>>> "Philip" == Philip Lijnzaad <········@ebi.ac.uk> writes:

Dowe> I don't know about you, but I've never seen a lang converter
Dowe> that produces anything like readable source code.

Philip> Dave Gillespie's p2c (Pascal to C) compiler produces very
Philip> readable code indeed; even the comments are translated and put
Philip> in the right places. But Pascal and C is admittedly a close
Philip> match.

The ECLIPSE CommonLisp->C compiler brags about producing human
readable C code, but I have no idea whether that is correct or not.

Does anybody know what is happening to it? The WWW page says (last I
looked) that company has stopped supporting it and is still thinking
about what to do with it.

(I haven't got the URL handy, but I can look it up if anybody else is
curious.)


---------------------------+--------------------------------------------------
Christian Lynbech          | Ericsson Telebit, Fabrikvej 11, DK-8260 Viby J  
Fax:   +45 8675 6881       | email: ···@ericssontelebit.com
Phone: +45 8675 6828       | web:   www.ericssontelebit.com
---------------------------+--------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - ·······@hal.com (Michael A. Petonic)
From: Kent M Pitman
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <sfwg0nw0zej.fsf@world.std.com>
····@krikkit.localdomain (Dowe Keller) writes:

> On 22 Aug 2000 14:06:07 -0400, David Bakhash <·····@alum.mit.edu> wrote:
> >The Glauber <··········@my-deja.com> writes:
> 
> >I don't think that Kawa will cut it, and even if it did, that just
> >produces the bytecodes.  I'm guessing that the original poster wants
> >readable Java source.
>  ^^^^^^^^
> I don't know about you, but I've never seen a lang converter that produces
> anything like readable source code, it may be legal source code for the
> target language, but I wouldn't want to have to maintain it.

My Fortran->Lisp translator [*] produced quite readable translated code,
but only because of Lisp's powerful ability to offer macro libraries
on the target end that made a "middle ground" between Fortran and
Lisp.  Its output was probably more readable to a Fortran programmer
than to a Lisp programmer, but mainly only because the translation
result still enforced a call-by-reference semantics by default, and
that would perplex the uninitiated Lisp programmer.  The target code
was definitely maintainable, though as with all heavily macrofied lisp
you could argue that maybe it just wasn't lisp any more.  That's one
of the cool things about lisp--that you're not stuck with it forever
if you want to morph it to something else that better suits your
domain.

At the metalevel, the point of this remark is to observe that Java has
no syntactic abstraction capability and so translation efforts are not
likely to result in anything pretty because you are bound and required to
see the most nitpicky guts of whatever you translate, except insofar as
you can functionally abstract it--which is a tall order.

I do think, in general, that language translators to languages with macro
capability can be quasi-successful in making readable output.  Or at least
in not drowning the reader in drivel.

- - - 

[*] The translator was going to be my bachelor's thesis back in
college before I changed from a C.S. major to philosophy, which
required no thesis. I finished the translator, but never wrote it up
as a thesis.  I did write a conference paper, 
  http://world.std.com/~pitman/Papers/Fortran-to-Lisp.html
and it did translate the entire IMSL numerical library for use in 
Macsyma on the PDP10, way back when.  

(This program is curious also because, odd as it sounds, it never had
any bugs reported in its translation once it was released.  It wasn't
used by millions of users, but it was used.  And it seemed to work
reliably.  I always think of it when someone says it's impossible to
build a large system with no bugs.  I once spent weeks debugging what
I thought was a bug only to find that the IMSL fortran library had
mis-documented one of its routines, showing an input matrix laid on
its side and confusing me into thinking my translator ought to produce
the erroneous output they were showing...)
From: Lieven Marchand
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <m3ya1nkig0.fsf@localhost.localdomain>
Kent M Pitman <······@world.std.com> writes:

> That's one of the cool things about lisp--that you're not stuck with
> it forever if you want to morph it to something else that better
> suits your domain.

I forgot who said it but:

If you give someone Fortran, he has Fortran.
If you give him Lisp, he has any language he wants.


-- 
Lieven Marchand <···@bewoner.dma.be>
Lambda calculus - Call us a mad club
From: Per Bothner
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <m2g0nvlv72.fsf@bothner.com>
David Bakhash <·····@alum.mit.edu> writes:

> The Glauber <··········@my-deja.com> writes:
> 
> > In article <·······················@max3-56.ip.realtime.net>,
> >   ······@bridgetrix.com wrote:
> > > I have 50 pages of Lisp code that I need translated to Java.  Are there
> > > Lisp to java translators about?
> 
> > Kawa seems to be very good (my knowledge of Schems is limited).
> > http://www.gnu.org/software/kawa/
> 
> I don't think that Kawa will cut it, and even if it did, that just
> produces the bytecodes.  I'm guessing that the original poster wants
> readable Java source.

 you want readable Java source, Kawa won't help.  If you have some
Lisp code that you want to have run under the JVM and perhaps interoperate
with Java, then Kawa can help.  While Kawa primarily supports Scheme,
I recently added the tiny beginnings of a Common Lisp front-end, and I
would be quite interested in turning this into something useful,
especially if there is some funding available.
-- 
	--Per Bothner
···@bothner.com   http://www.bothner.com/~per/
From: Donald Fisk
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <39AAFD6C.A4BE1EB2@enterprise.net.nospam>
Per Bothner wrote:

>  you want readable Java source, Kawa won't help.  If you have some
> Lisp code that you want to have run under the JVM and perhaps interoperate
> with Java, then Kawa can help.  While Kawa primarily supports Scheme,
> I recently added the tiny beginnings of a Common Lisp front-end, and I
> would be quite interested in turning this into something useful,
> especially if there is some funding available.

I read your paper on Kawa some time ago, and don't have it
to hand, so I'm relying on memory now.

You made a separate class for each function (e.g. an append
class), when an append method, operating on a List class, would
have been the more natural way to implement things.   Presumably
you did this so that you could have incremental compilation, but
is there no way of taking an existing Java class and extending it
to by adding a single function compiled into the byte codes of
a Java method?

>         --Per Bothner

-- 
Le Hibou
With regard to Mr Blair's "gut British instinct" --
would that be the same British gut, with "pussy-
hunter" tattooed on it, we saw being repatriated
from Charleroi recently? -- Peter Kenvyn Jones
From: felix
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <sqn30icct9166@corp.supernews.com>
Donald Fisk wrote in message <·················@enterprise.net.nospam>...
>
>You made a separate class for each function (e.g. an append
>class), when an append method, operating on a List class, would
>have been the more natural way to implement things.   Presumably
>you did this so that you could have incremental compilation, but
>is there no way of taking an existing Java class and extending it
>to by adding a single function compiled into the byte codes of
>a Java method?


So how do you implement higher-order functions, then?
There is no way of handling functions as first-class objects but
putting each into a separate class.
A Stalin-like block-compiler would perhaps be more flexible,
but only for a certain price.


felix
From: Per Bothner
Subject: Re: Translating Lisp to Java
Date: 
Message-ID: <m2r977osot.fsf@bothner.com>
Donald Fisk <··········@enterprise.net.nospam> writes:
> I read your paper on Kawa some time ago, and don't have it
> to hand, so I'm relying on memory now.

http://www.gnu.org/software/kawa/internals.html

> You made a separate class for each function (e.g. an append
> class), when an append method, operating on a List class, would
> have been the more natural way to implement things. 

The current implementation (not documented yet in the internals.html
manual unfortunatately) usually generates one method for each
Scheme procedure, with each source file generating a single
Java class.  (Exceptions include nested functions.)

> you did this so that you could have incremental compilation, but

Not just that.  You need to be able to apply an unknown procedure,
and Java does not directly support that, except by using reflection,
which is too slow for this purpose.

> is there no way of taking an existing Java class and extending it
> to by adding a single function compiled into the byte codes of
> a Java method?

No, not in Java per se.  Some implementations may support class
modification as part of the development environment,
but that is non-portable and not defined.
-- 
	--Per Bothner
···@bothner.com   http://www.bothner.com/~per/