Hi everyone, I'm the creator of Pharen. Feel free to ask me questions or remind me why this is a terrible idea. :)
Yes there are a lot of issues with cross-language compilers. That said, Coffeescript: http://coffeescript.org, which compiles its own language to Javascript has had a lot of success and is being used in production. So it's at least possible to use languages like this.
The extra layer of abstraction is a big hurdle. When debugging you have to find the source of the problem in the PHP, though ideally after that you can just find the matching Pharen code and go from there. One of the things on my todo list is to have at least a rough line-to-line tracker built, so that it could at least tell you the general location a problem happened, if not the exact line.
Translating docs and example code for existing libraries into Pharen is a bigger issue, I think. Mainly because Pharen emphasizes a functional style of coding while most PHP code assumes you are doing things imperatively. This is something Clojure has to deal with in terms of Java interop so again it shouldn't be too hard to get around.
In terms of efficiency there is tail recursion optimization (converts a recursive function to having a while loop at the end) and a persistent sequence library in the works that would make functional looping through a list about as fast as imperative iteration. More aggressive optimizations might come in the future.
If you're interested, feel free to contribute: http://scriptor.github.com/pharen/contribute.html. If you use IRC you can come hang out (or berate me personally) on #pharen on Freenode. Any suggestions or ideas are welcome.
> When debugging you have to find the source of the problem in the PHP, though ideally after that you can just find the matching Pharen code and go from there.
You could always just add the S-Expression that became the php code as a comment. From there it should be trivial to find it in the Pharen code.
Nope, it should work for PHP 5.2 as well. Closures are implemented using a static member on a class that handles all the lexically scoped variables, not PHP 5.3's native closures.
This makes me curious, why reimplement features that would've been built-in in PHP 5.3? After all, 5.3 is now available in most major platforms including a Ubuntu LTS release and the latest RHEL.
Other than that, Pharen looks very interesting. A minor detail is that I didn't yet figure out how to call static methods of external PHP classes.
I guess I wasn't exactly sure just how widespread PHP 5.3 was and wanted to play it safe. Also, even if new servers nowadays come with 5.3, a lot of existing code is still running on 5.2.
This is really cool and for the most part the syntax seems to make sense.
One thing I don't understand is why there is special unnatural-looking syntax for dictionaries. It is inconsistent that comma=whitespace everywhere else. Perhaps something like:
(array "a"=>1 "b"=>2)
Note that this currently compiles to array("a", =>1, "b", =>2)
The current dictionary syntax is actually typical for lisps, particularly this is exactly what Clojure does. It's just a series of elements except in this case it's designed to look at every two elements as a pair.
What do you mean by it's inconsistent? Commas are the same both in dictionaries and anywhere else, they're completely optional.
It gives you a chance to use Lisp's syntax and mentality if you're stuck with PHP on the backend. Moreover, you have features like macros and lexical scope, which can be useful.
I just wondered if it had been built for a specific project and if so what problems it was trying to solve.
It's funny - I've spent the past few years thinking about high-level languages that would compile down to lisp. Recently I've seen a number that go the other way.
This actually doesn't suck. I was expecting something much much worse, but I was pleasantly surprised. If the author just focuses on a few primitives and how to make them as efficient as possible (i.e. closure efficiency, tail-calls, macros, efficient list representation, etc), if he just gets those right, others can always use it as a target and develop more comfortable lisp substrates on top of it.
Efficient sequences are what I'm working on right now, particularly trying to make persistent versions of the major data structures in PHP.
Tail calls are another thing, though with PHP 5.3's gotos they could be done (who'd have thought that feature would ever be useful?) Could you elaborate on how I could improve efficiency for macros?
Is the intended user a Lisp programmer forced to work on a php code base...or a Lisp programmer looking to take advantage of some of php's native server scripting features?
Fair enough. I've never programmed in lisp. I just assumed that lisp didn't have native server abstractions like $_REQUEST - and that Pharen may expose those.
Do you believe there are or will be good reasons to choose Pharen over Scheme, Common Lisp or Clojure in a situation where one isn't forced in to using a PHP backend? With Clojure, for example, I consider the baked-in concurrency models and data structures very valuable, but haven't had much cause to care that it runs on the JVM.
That's a really good question. The main case I can see is if someone is already familiar with PHP and its deployment and doesn't want to learn another language/platform. It might also be useable for basic scripting tasks (the compiler has an --executable flag that adds a PHP hashbang to the top of a script).
Other than that Pharen is still pretty new and nowhere near the same level as mature lisps. Making debugging and interop with 3rd party libraries easier are the main long-term goals, so maybe after that it'll be at least a little viable.
The big one is that Lisphp is an interpreter while Pharen is a compiler. Lisphp takes source code and just runs it, which means that it's lisp code running on Lisphp, which in turn is running on the PHP interpreter.
Pharen generates regular PHP source files that you can then throw wherever PHP works.
How do they compare performance wise? I've tried some 'toy' lisp programs in Lisphp and was pretty disappointed at the speed, does Pharen fare better in this respect?
I haven't done any real benchmarks, but theoretically Pharen would have at least the same order of magnitude performance as regular PHP. The main things slowing it down is the memory overhead needed for using lexical scope.
From reading the examples this looks awesome, I'll give it a try tomorrow at the office. Is there a way to expand macros only and not do the compile-to-php step?
My current project involves generating php from a declarative definition and this could be just the right tool for the job! Maybe it will make switching to common lisp a lot easier once I learned enough of it :D
>Is there a way to expand macros only and not do the compile-to-php step?
So that it would just generate the Pharen code resulting from the expansion? Unfortunately, not yet. As soon as a macro is done executing it returns the node tree itself, which is then compiled. There might be a way to hack macro-expand in though.
Let me know how trying to work it into your project goes! I'll be glad to help with any problems that come up.
I'd say it's closer to Clojure than others lisps, but there are still some differences. For example, no keywords (:foo, :bar, etc.) and lists are not functions of their members. This can get a little confusing with Pharen's array access syntax:
(:some-list 1)
Here, some-list is just a variable while the : prefix tells Pharen that you are trying to index into it.
I pretty much like the partial such as (map (* 2) [1 2 3]). Do you plan on adding something like (map (/ _ 2) [1 2 3]) like Arc or a #(.. % ..) clojure equivalent?
Yes there are a lot of issues with cross-language compilers. That said, Coffeescript: http://coffeescript.org, which compiles its own language to Javascript has had a lot of success and is being used in production. So it's at least possible to use languages like this.
The extra layer of abstraction is a big hurdle. When debugging you have to find the source of the problem in the PHP, though ideally after that you can just find the matching Pharen code and go from there. One of the things on my todo list is to have at least a rough line-to-line tracker built, so that it could at least tell you the general location a problem happened, if not the exact line.
Translating docs and example code for existing libraries into Pharen is a bigger issue, I think. Mainly because Pharen emphasizes a functional style of coding while most PHP code assumes you are doing things imperatively. This is something Clojure has to deal with in terms of Java interop so again it shouldn't be too hard to get around.
In terms of efficiency there is tail recursion optimization (converts a recursive function to having a while loop at the end) and a persistent sequence library in the works that would make functional looping through a list about as fast as imperative iteration. More aggressive optimizations might come in the future.
If you're interested, feel free to contribute: http://scriptor.github.com/pharen/contribute.html. If you use IRC you can come hang out (or berate me personally) on #pharen on Freenode. Any suggestions or ideas are welcome.