

Pixie: A small fast, native lisp - emidln
https://github.com/pixie-lang/pixie

======
_halgari
Author of pixie here. The project is still pretty young (about a month old),
so I'll use that to explain away the lack of binaries, documentation,
examples, etc. I've been more focused on adding features than getting stuff
ready for presenting to the public. As an example, we didn't even have stack
traces until a day or two ago.

That being said I'll try to answer any questions you may have. Thanks!

~~~
sktatlo
This is an amazing effort! Now to clojure compatibility. You can only gain by
making it clojure compatible. What would be the possible reasons to diverge?
Another one: what are your plans for namespaces and code packaging and
distribution? What are your thoughts about a build system? I think the world
doesn't need another build and package distribution system. Which one would
you reuse?

~~~
_halgari
I love clojure, let me make this clear. But there are certain aspects of the
language that don't apply if you are writing a VM from scratch in RPython. If
I could make multimethods dispatching on types as fast as protocols, what is
the point of protocols?

A great example of this is the (fn [& args]) bit. In Clojure, variadic
parameters are passed in as a ISeq. In Pixie they are a vector (or an
immutable array actually). This allowed me to tune the JIT quite a bit to
allow it to remove the allocation of "args" completely. As well as allow for
things like unrolling a reduce over the args. This stuff would have been much
harder if the arguments were passed in as an ISeq.

This is the whole reason why Pixie exists, instead of something like "clojure-
on-rpython". Compatibility means constraining the feature set. And that's not
something I want to do yet.

~~~
emidln
It might be interesting down the line to see if I couldn't target pixie using
something like cljx (or actual feature expressions if they ever land in a
mainline clojure release). This wouldn't necessarily require any effort on the
part of my target, but still allow portability when it makes sense.

------
eddieplan9
The author is the creator of clojure-py [1]. Pixie looks like a follow-up
effort with strong influence from PyPy. The following post of his from over 2
years ago might provide some insight:
[https://groups.google.com/forum/#!topic/clojure-py-
dev/Lmhd0...](https://groups.google.com/forum/#!topic/clojure-py-
dev/Lmhd0VwwdgA)

[1]
[https://news.ycombinator.com/item?id=3649883](https://news.ycombinator.com/item?id=3649883)

------
wtbob
It looks cool enough, but I wish more of these modern Lisp implementations
would ask to implement the Common Lisp standard rate than their own,
informally-specified version of Lisp. Yeah, Common Lisp is not perfect, but it
does have a lot of excellent ideas, and some of the bits which don't look
excellent actually are (e.g. pathnames and logical pathnames).

~~~
sklogic
Common Lisp is too big for a typical application (e.g., embedded scripting
engines, mataprogramming hosts, etc.). And it's a Lisp-2, which is quite a
deterrent for many.

~~~
sedachv
> And it's a Lisp-2, which is quite a deterrent for many.

I used to be on the fence about multiple namespaces in programming languages.
After a decade of programming in Common Lisp and in other languages that
pretend to have a single namespace, I see multiple namespaces as a clearly
superior approach. I don't think it is a deterrent either - a reason to post
complaints on the Internet, yes.

~~~
sklogic
For me it's clearly a deterrent - it does not fit at all into my model of
building hierarchies of DSLs.

~~~
sedachv
> it does not fit at all into my model of building hierarchies of DSLs

Links to source code or GTFO. The only way people manage to combine DSLs in a
single-namespace language is by having stupid naming rules and restrictions
(see for example Ruby on Rails). Compare this to something like
[https://github.com/vsedach/cliki2](https://github.com/vsedach/cliki2) where I
could just throw arbitrary CL libraries that define their own DSLs together
and not worry that my function name is going to clobber some reference in the
template system.

~~~
sklogic
See
[https://github.com/combinatorylogic/mbase](https://github.com/combinatorylogic/mbase)

Problem with two namespaces is, well, need to maintain two namespaces, in all
your DSLs. Which in many cases may double the effort.

Of course, macros must have their own namespace, but that's an obvious thing,
you cannot mix compile-time and run-time namespaces anyway.

~~~
sedachv
> Problem with two namespaces is, well, need to maintain two namespaces, in
> all your DSLs. Which in many cases may double the effort.

How so? And why only two namespaces? Common Lisp probably has a dozen: package
name, lexical variable, dynamic variable, function (stores either function or
macro function), documentation string, property list, type name, class name,
slot name, etc.

As long as you have first-class identifiers, you can define arbitrary
namespaces without having to worry about conflicts between the namespaces.

> Of course, macros must have their own namespace

That doesn't have to be true, and is not true in Common Lisp:
[http://www.lispworks.com/documentation/HyperSpec/Body/03_bba...](http://www.lispworks.com/documentation/HyperSpec/Body/03_bba.htm)

Having an identifier denote a function and a macro at the same time like that
enables adding partial evaluation and other compile-time optimizations to DSLs
without having to dig into the compiler.

> but that's an obvious thing, you cannot mix compile-time and run-time
> namespaces anyway.

? You have to mix them if you want a compiler in your runtime.

------
gopalv
This is a lisp engine written in python - RPython, to be precise.

It literally compiles the lisp code into python bytecode, which is pretty neat
- sort of like clojure is for the JVM.

[https://github.com/pixie-
lang/pixie/blob/master/pixie/vm/com...](https://github.com/pixie-
lang/pixie/blob/master/pixie/vm/compiler.py#L598)

Perhaps not magical, but I like the effort (though lisp-as-shell has to
contend with emacs first).

~~~
srean
Ever since RPython had been announced I have wanted generator support in
RPython. TCO'ed coroutines would be even better. PyPy devs did not see much
use of it for writing their Python interprator so they left it out, which is a
pity.

How so ever shiny and neat dynamic typing might be, I have had very little use
of it in my own Python code. A situation where I _absolutely must_ store
values of different types in the same variable (that or bullet to the head)
has not presented itself that often if ever. For me RPython would have been a
fine enough replacement, except that I do like generators a lot.

Given the prominence of inversion of control (via coroutines) as a feature, I
assume it would have helped pixie implementation too.

~~~
fijal
RPython is not a language for normal usage and mostly because e.g. error
messages are obscure and hard to read. There is some basic support for
generators these days, however, unless you're writing another language, we
strongly encourage you don't use it.

------
daGrevis
I love little languages like this one! Just look at the source — it's still so
readable and easy to understand, and the size — I could read through it in an
evening!

It reminds me a bit of diy-lisp where you implemented Lisp in Python yourself!
[https://github.com/daGrevis/diy-lisp](https://github.com/daGrevis/diy-lisp)

------
andrewchambers
I'm glad there will be something like clojure, only with semi sane start up
times. (pypy based interpreters are still slow to start.)

------
duckingtest
>Math system is fully polymorphic

Does it have fully polymorphic other basic functions, like setq, eql (or
however they are named)? I guess not? Do you plan on introducing some parts of
CLOS?

Lack of OO integration in CL is one of its biggest drawback for me... for me
CLOS was the most powerful thing in lisp, not macros (mostly because they are
not dynamic).

~~~
_halgari
CLOS has been on my list to research for some time now, and I haven't made a
decision on it yet. The goal would be to get the JIT to remove the method
lookup completely, and that might get a bit tricky depending on how complex
the lookup code is, but it is the most open dynamic OO system I've seen, so it
might just be worth it.

------
cryptolect
I'm happy to see that some new 'modern lisp on x' projects are taking design
cues from Clojure (See Rhine and now Pixie).

~~~
dTal
Clojure's success, I believe, is due to retaining Java's semantics (preserving
library compatibility) while overhauling its syntax. Fighting the semantics of
your host language/VM just makes work and causes trouble. Therefore, if you
want a "Clojure on Python" that preserves the benefits of the original, you
need to give it Python semantics, not Java/Clojure's. Hylang is that project -
it uses Clojure syntax where sensible, and is _fully_ compatible with Python.

[https://groups.google.com/forum/#!topic/clojure-py-
dev/HbeNE...](https://groups.google.com/forum/#!topic/clojure-py-
dev/HbeNEkIG23U)

[http://hy.readthedocs.org/en/latest/](http://hy.readthedocs.org/en/latest/)

~~~
andrewchambers
Only hylang has a lot of stupid limitations and problems like scope leakage.

~~~
dTal
I take it you refer to your complaint here:
[https://github.com/hylang/hy/issues/543](https://github.com/hylang/hy/issues/543)

Your problem is with Python, not Hy. Hy inherits the "stupid limitations" of
Python, and not even all of those - for example, it does away with the
statement/expression distinction, which means multiline lambdas (at last!).

It's just Python with s-expressions. If you don't like it, you either don't
like Python or don't like s-expressions.

------
GuiA
What's magical about it?

~~~
616c
Well judging from the description, "native" actually means writing it in
RPython (a "restricted" Python with types for use in the PyPy Project for
static analysis and speeding things up[0]) and then compiling it down using
PyPy (I am guessing on the second part). That could be neat, the HyLang people
(Lisp written in vanilla CPython Python; I think no C extensions AFAIK).

[0] [http://pypy.readthedocs.org/en/latest/coding-
guide.html#id1](http://pypy.readthedocs.org/en/latest/coding-guide.html#id1)

~~~
dTal
Hy isn't a full Lisp interpreter in Python, it's an s-expression to Python AST
parser, which means it does everything Python does (including C extensions) at
essentially native speed anyway - you can even write RPython in it.

If you ask me, full Python interop makes Hy the most practical s-expression
language today.

~~~
JasonFruit
One problem with Hy for me is that it keeps Python scoping, either global or
function; that doesn't feel natural to me in a Lisp, and it gets in my way. If
it weren't for that and a few similar matters, I'd agree with you on Hy's
practicality; as it is, I'd give my nod to Clojure.

------
nicklovescode
Would love some examples that showoff the benefits

~~~
_halgari
I added a few comments to the README on that subject.

------
lsdafjklsd
Neat project, although I am struggling with getting it working. Looking
forward to installation instructions.

------
ottbot
Have fun.

