15 comments

[ 4.3 ms ] story [ 49.0 ms ] thread
This was very much a learning experience and I'm sure there will be lots in the code that isn't done properly. If you find something wrong, please let me know!

Pharen was also started to eventually abstract out things I don't like about PHP's syntax, and maybe add some new ones. It's not meant as a competitor to other lisps!

Some special features are micros (closer to C macros than true Lisp macros) and partials (partial evaluation). Documentation for those can be found near the end of the linked page.

It is by no means close to completion. Although lisp should be entirely expression-based, parts of Pharen can't really be used as expressions yet (namely conditionals). Closely related is that returning something other than the last expression in a function has to be done manually.

Any questions, glaring (or subtle) problems, or suggestions you have are definitely welcome.

Nicely executed this one! Is it me, though, or has writing cross-language compilers become a sort of open source fad in the last 12 months? There seem to be a ton popping up lately. It'd be cool to have a list actually..
To add one to your list: I just pushed out CoffeeScript 0.2.5 a couple of minutes ago. (CoffeeScript is a Ruby/Potion/Python/Harmony-ish to JavaScript compiler, for those who haven't seen it.)

I'm doing a talk about it tomorrow (Thursday) night at NYCJS, and if you live in New York and work on a source-to-source compiler, you should come and discuss implementation ideas.

Resources for doing this sort of thing are hard to find on the web. There's hardly space for comparison between "serious compilers", and things like like CoffeeScript and Pharen, which are both well under two thousand lines of code.

Looking at CoffeeScript was definitely an inspiration to pick up the pace on Pharen. :)

I'm actually a student in New York but can't be there Thursday. Will you be giving this talk at any other events?

That's too bad. I don't have any plans for other events at the moment, but if you're in New York we should go grab a coffee sometime and talk shop. jashkenas(at)gmail, if you want to get in touch.
Nice start. I was considering something simliar, but I just didn't care enough about PHP to work on it.

Stuff that I'd like to see improved:

1. if/elseif/else syntax is pretty ugly. What are the chances of getting if/when/unless/cond?

2. Nicer array syntax. Maybe coopt the vector literal syntax, since PHP doesn't have anything similar: [1 2 3]. Failing that, quotes: '(1 2 3) -> array(1, 2, 3). Not sure how to handle cases where you would have something inside the quote that would eval, though.

3. Not thrilled with the superglobals/array syntax, which are more verbose (or the same, in the case of superglobals).

4. It isn't clear if/how this interacts with objects. Does it work like: (object->method arg1…argN)? What about static methods?

Yeah, the IF paren'ning is a nightmare on the scale that keeps a lot of people away from LISP.
Thanks for the suggestions.

1. Pretty likely, though I'm a little hesitant to replace the current syntax for if. The others shouldn't be hard to implement.

2. I've been planning to use the vector literal syntax. I've basically been lazy since PHP's array() construct makes it easy to cheat.

3. Indexing into arrays presents a problem. Pharen doesn't know what's a scalar, array, or function name at the moment so a special function for indexing is needed. One possible solution is to prefix an array's name, so it would be (:some_array 4) or something similar. I personally think the superglobal syntax is cleaner, if not more succinct. Any suggestions?

4. I haven't implemented an object system yet because I want to try something new here instead of simply copying PHP's syntax.

1. Perhaps you could keep the PHP-style syntax around under a different name.

2. Sweet.

3. (:some_array 4) seems perfectly reasonable. Would that interact with superglobals the same way? e.g. ($:server "PHP_SELF"). I believe that PHP 5.3 or 6 has return value dereferencing, so I don't think it's necessary to know the type - you could just do (:(array 1 2 3) 1)

4. If you haven't played with Clojure, you might find inspiration there. It has interop with native Java instances, though I find it a little too syntaxy for a Lisp, and PHP doesn't have such deep class structure.

Thanks for responding.

Why so arcish? Lisp used def* forms from day ONE, like God/McCarthy indented.
I don't understand the proliferation of cross-language compilers. As an academic exercise, great, but for a large project, surely debugging is going to be a pain when the errors refer to code that you never wrote?
Right now I certainly wouldn't use it for any large projects. It's a pain to debug so it's really a tradeoff between better syntax and features and problems in the development cycle. Making the output code nicely formatted helps greatly.

The debugging problem can also be lessened by keeping each file small, so that syntax errors are easier to localize. In the future, it's possible that I'll make a debugging system that can read the PHP errors and find the Pharen code responsible for it.