Re: Lisp2Perl - Lisp to perl compiler
From: David (hhdave_at_SPAMAROONEY.blueyonder.co.uk)
Date: 01/18/04
- Next message: jennyjenny: "LISP apply question"
- Previous message: Samuel Walters: "Re: Programming languages for the very young"
- In reply to: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Next in thread: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Reply: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 18 Jan 2004 22:29:01 +0000
Thomas F. Burdick wrote:
> David <hhdave@SPAMAROONEY.blueyonder.co.uk> writes:
>
>
>>Hi,
>>
>>Is anyone here at all interested in programs to translate lisp into
>>perl? I see there's a lisp interpreter on CPAN but I have implemented
>>something a bit different.
>>
>>Basically its a program which can translate lisp programs (written in a
>>rather scheme-like dialect - even has a single namespace) into efficient
>>perl scripts. Perl has enough lisp like features to be able to implement
>>most things which can be done in lisp (lexical closures - hurrah!).
>
>
> I have a grungy Lisp->Perl compiler. The major goal was to produce
> readable Perl code, that looked like it might as well have been
> written by a human, and could be maintained by a normal Perl hacker.
> The lowest-level Lisp dialect is pretty much Perl-in-Lisp, then there
> are enough macros and functions built on top of it to make it fairly
> Lispy.
>
Producing readable, hackable perl code was not one of the goals of my
program (as you might have guessed if you've seen any of the output!). I
had sort of figured that when you started using macros of any degree of
complexity then, whether you are translating to perl or not, you
wouldn't want to see the entirety of the macro expanded code anyway.
This is certainly the case with one largeish program I've written - the
amount of expanded code is enormous compared to the un-macro-expanded
code. Also, using (cond) statements, especially nested ones, produces
horrible looking perl code. They compile down to lots of trinary ifs
(a?b:c) in perl. The fact is, if I were programming in perl my program
just wouldn't be structured like that, whereas in lisp it seems a
natural thing to do.
I guess readable code is nice to have if you are 'supposed to be'
programming in perl, but really want to use Lisp :)
I'd be very interested in seeing the source code to your program if I may.
> I have to say, I'm horrified that you're thinking of a scheme-like
> Lisp. Perl itself has 4 namespaces, and I preserved that at my Lisp
> level (special-forms called FUNCTION, SCALAR, HASH, and ARRAY, but an
> inferencing engine generally takes care of picking the correct
> namespace for you). Of course, my Lisp->Perl is hosted on Common
> Lisp, so it was a pretty natural choice.
>
I didn't intend it to be horrific! (well, not _too_ horrific :)
I know it seems an odd thing to use a 1 namespace language to translate
to a 4 namespace language. The reason I'm doing the scheme thing as
opposed to the common lisp thing is that I just kind of like the 1
namespace approach. It seems to be a lot simpler and remove the
necessity for ways of dealing with different kinds of bindings. I guess
that's just personal preference. It does produce rather odd looking perl
code (lots of '$fn->(...)'), but as I say, I don't really care about
that. As long as it executes fast enough. I don't know if $fn->()
executes any slower than &fn() - haven't checked.
The other thing I find, with hashes and arrays and such, is that half
the time in perl I end up using references to those things stored in
scalars anyway. Particularly when I need nested structures.
>
>>This lisp2perl translator/compiler works rather well. I've used it for a
>>major project at work. It's also self hosting (used to compile itself).
>>
>>I've put a bit more info, though not much, and the source on my website:-
>>
>>http://www.hhdave.pwp.blueyonder.co.uk
>>
>>Any thoughts or comments anyone?
>
>
> - Since you're really compiling Scheme to Perl, I'd think scheme2perl
> would be a better name. You might as well pick the most specific
> name (otherwise someone might think you mean elisp, for example :)
>
Yeah, I know. It's just that, although it is scheme-like, it certainly
isn't scheme. It doesn't conform to the standard. It has unschemish
concepts of truth, for example, and the fundamental datatypes don't
behave as they should. 'lisp' is a less specific term though,
encompassing a multitude of similar, but distinct thing. It's its own
peculiar dialect of lisp :)
> - If you're at all interested in readability of the resulting Perl,
> don't offer gensym, just make-symbol (I accompanied mine with a
> with-gensyms macro that takes the symbol names from the vars that
> are bound to the new symbols). The compiler has to pay attention
> to scoping anyway, so you can have it resolve the names. Hmm, that
> wasn't a very comprehensible sentance, was it? How about an
> example:
>
> (let ((a (make-symbol "a"))
> (b (make-symbol "a"))
> (c (make-symbol "a")))
> `(let ((,a 0))
> (let ((,b 100))
> (setf ,a (+ ,b 1)))
> (let ((,c "hi"))
> (print ,c))
> (print ,a)))
> => (let ((#1=#:a 0))
> (let ((#2=#:a 100))
> (setf #1# (+ #2# 1)))
> (let ((#3=#:a "hi"))
> (print #3#))
> (print #1#))
> => { my $a = 0;
> my $a2 = 100;
> $a = $a2 + 100;
> {
> my $a = "hi";
> print $a
> }
> print $a; }
>
I'm not quite sure I understand this at the moment. I'll have to think
about it some more. If the generated perl looked like that wouldn't it
clash with a variable called 'a'? I know I'm probably being thick here.
> - I'm not sure how you can get better undefined-function error
> reporting if you use the scheme approach. If you use multiple
> namespaces in your Lisp, the function namespace maps directly from
> Lisp to Perl, so you get normal Perl error reporting.
>
I know, and it would seem the obvious thing to do wouldn't it? I still
like the single namespace though, but fear not - I thought of a solution
[me: looks up solution in files of notes about the program...]
Ah, here we go: I'm planning to modify the compiler to keep track of
lexical scope. That way, when it compiles a reference to an undefined
variable it should know and generate a warning about it. This may be
related to the gensym issue above. I guess generating symbols can be
done if I keep track of scope. I'll have to think about that some more.
Incidentally, can you think of a good argument AGAINST the scheme single
namespace approach?
> One thing you might consider here is losing the Lisp1-ness, but
> keeping the Scheme-like handling (normal evaluation) of the first
> position in a form. IE:
>
> (defun foo (x) ...)
> (let ((foo (lambda () ...)))
> ((complement (function foo)) ((var foo))))
>
> For an unadorned symbol in the first position, you could have the
> compiler infer the namespace based on the innermost lexical
> binding. EG:
>
> (let ((x 1))
> (foo x)
> (let ((foo (lambda (x) ...)))
> (foo x)))
> <==>
> (let ((x 1))
> ((function foo) x)
> (let ((foo (lambda (x) ...)))
> ((var foo) x)))
>
That is a thought. I suppose it would make it play nicer with 'normal'
perl code. It would be particularly useful for using built in functions.
At the moment I have to 'declare' those:-
(<perl-sub> print)
which expands to a (defmacro ...)
I guess the first thing to do in any case is to extend the compilartion
functions so that they keep track of lexical scope.
- Next message: jennyjenny: "LISP apply question"
- Previous message: Samuel Walters: "Re: Programming languages for the very young"
- In reply to: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Next in thread: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Reply: Thomas F. Burdick: "Re: Lisp2Perl - Lisp to perl compiler"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|