[ANN] clojure-py 0.1.0 Clojure on Python

294 views
Skip to first unread message

Timothy Baldridge

unread,
Mar 7, 2012, 10:42:13 PM3/7/12
to clo...@googlegroups.com
The Clojure-Py team is happy to announce the release of Clojure-Py 0.1.0.

https://github.com/halgari/clojure-py

Clojure-Py is an implementation of Clojure running atop the Python VM.
As it currently stands, we have translated over 235 functions from
clojure.core. This is not a clojure interpreter in python; the
Clojure-Py compiler compiles clojure code directly to python code.
Clojure-py functions are python functions. Clojure-py types are python
types, Clojure-py name spaces are python modules.

Please feel free to browse the examples at
https://github.com/halgari/clojure-py/tree/master/examples to get an
idea of what Clojure-Py can currently accomplish.

Version 0.1.0 should be considered "alpha" and "proof of concept".
That being said, if you stick to the afore mentioned 235 functions,
and python interop, the implementation is very usable and so far quite
stable.

The package is released via the Python Package index so you can simply type

easy_install clojure-py
clojurepy

To install and startup the repl. Python 2.6, 2.7 and PyPy are all
supported. Please check out this release and send us your feedback via
Github.
---

Upcoming in version 0.2.0:

Support for bindings
defprotocol and defmulti
defrecord
full support for pr-str

---

Thank you for all the interest we've received from the Clojure and
Python communities. We look forward to seeing this project grow.

Timothy Baldridge (halgari)

Shantanu Kumar

unread,
Mar 8, 2012, 12:59:30 AM3/8/12
to Clojure
Congrat's on the release! I am getting the following error on my
Macbook (running 64-bit Lion, Python 2.7.1) when trying to run "sudo
easy_install clojure-py":

Searching for clojure-py
Reading http://pypi.python.org/simple/clojure-py/
Reading https://github.com/halgari/clojure-py
Best match: clojure-py 0.1.0
Downloading http://pypi.python.org/packages/source/c/clojure_py/clojure_py-0.1.0.tar.gz#md5=794da1e8031e2d4f3fbc6484ed51c172
Processing clojure_py-0.1.0.tar.gz
Running clojure_py-0.1.0/setup.py -q bdist_egg --dist-dir /tmp/
easy_install-feUpDQ/clojure_py-0.1.0/egg-dist-tmp-78bqof
Traceback (most recent call last):
File "/usr/bin/easy_install-2.7", line 10, in <module>
load_entry_point('setuptools==0.6c12dev-r85381',
'console_scripts', 'easy_install')()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 1712, in
main
with_ei_usage(lambda:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 1700, in
with_ei_usage
return f()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 1716, in
<lambda>
distclass=DistributionWithoutHelpCommands, **kw
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7/distutils/core.py", line 152, in setup
dist.run_commands()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7/distutils/dist.py", line 953, in run_commands
self.run_command(cmd)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7/distutils/dist.py", line 972, in run_command
cmd_obj.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 211, in
run
self.easy_install(spec, not self.no_deps)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 446, in
easy_install
return self.install_item(spec, dist.location, tmpdir, deps)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 476, in
install_item
dists = self.install_eggs(spec, download, tmpdir)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 655, in
install_eggs
return self.build_and_install(setup_script, setup_base)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 930, in
build_and_install
self.run_setup(setup_script, setup_base, args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/command/easy_install.py", line 919, in
run_setup
run_setup(setup_script, args)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/sandbox.py", line 62, in run_setup
lambda: execfile(
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/sandbox.py", line 105, in run
return func()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/
Extras/lib/python/setuptools/sandbox.py", line 64, in <lambda>
{'__file__':setup_script, '__name__':'__main__'}
File "setup.py", line 10, in <module>
File "/tmp/easy_install-feUpDQ/clojure_py-0.1.0/clojure/
__init__.py", line 2, in <module>
File "/tmp/easy_install-feUpDQ/clojure_py-0.1.0/clojure/main.py",
line 104, in <module>
File "/tmp/easy_install-feUpDQ/clojure_py-0.1.0/clojure/main.py",
line 48, in import_hook
ImportError: module clojure.core not found, looked in ['.', '/tmp/
easy_install-feUpDQ/clojure_py-0.1.0', '/usr/bin', '/Library/Python/
2.7/site-packages/mercurial-2.0-py2.7-macosx-10.7-intel.egg', '/
Library/Python/2.7/site-packages/hg_git-0.3.2-py2.7.egg', '/Library/
Python/2.7/site-packages/dulwich-0.8.3-py2.7-macosx-10.7-intel.egg', '/
Library/Python/2.7/site-packages/Pygments-1.4-py2.7.egg', '/System/
Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/
System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7', '/System/Library/Frameworks/Python.framework/Versions/2.7/
lib/python2.7/plat-darwin', '/System/Library/Frameworks/
Python.framework/Versions/2.7/lib/python2.7/plat-mac', '/System/
Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-
mac/lib-scriptpackages', '/System/Library/Frameworks/Python.framework/
Versions/2.7/Extras/lib/python', '/System/Library/Frameworks/
Python.framework/Versions/2.7/lib/python2.7/lib-tk', '/System/Library/
Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old', '/
System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/
lib-dynload', '/System/Library/Frameworks/Python.framework/Versions/
2.7/Extras/lib/python/PyObjC', '/Library/Python/2.7/site-packages', '/
tmp/easy_install-feUpDQ/clojure_py-0.1.0/clojure']

Shantanu

On Mar 8, 8:42 am, Timothy Baldridge <tbaldri...@gmail.com> wrote:
> The Clojure-Py team is happy to announce the release of Clojure-Py 0.1.0.
>
> https://github.com/halgari/clojure-py
>
> Clojure-Py is an implementation of Clojure running atop the Python VM.
> As it currently stands, we have translated over 235 functions from
> clojure.core. This is not a clojure interpreter in python; the
> Clojure-Py compiler compiles clojure code directly to python code.
> Clojure-py functions are python functions. Clojure-py types are python
> types, Clojure-py name spaces are python modules.
>
> Please feel free to browse the examples athttps://github.com/halgari/clojure-py/tree/master/examplesto get an

Konrad Hinsen

unread,
Mar 8, 2012, 5:10:52 AM3/8/12
to clo...@googlegroups.com
Timothy Baldridge writes:

> The Clojure-Py team is happy to announce the release of Clojure-Py 0.1.0.
>
> https://github.com/halgari/clojure-py

This looks really nice already. Keep up the good work!

For me, this could be the solution to the main problem I have with
Clojure: the JVM. Most of my legacy code is in Python and most of the
important libraries in my domain are in C or Fortran and have Python
interfaces.

Konrad.

Timothy Baldridge

unread,
Mar 8, 2012, 7:00:24 AM3/8/12
to clo...@googlegroups.com
>Congrat's on the release! I am getting the following error on my
>Macbook (running 64-bit Lion, Python 2.7.1) when trying to run "sudo
>easy_install clojure-py":

I've seen this once before, in Linux, I'll open a bug for it and see
if we can get it ironed out.

Timothy

Daniel Janus

unread,
Mar 8, 2012, 7:02:51 AM3/8/12
to clo...@googlegroups.com
I'm seeing it on Arch Linux as well, using both pip2 and easy_install-2.7.

Thanks,
Daniel

Timothy Baldridge

unread,
Mar 8, 2012, 7:32:25 AM3/8/12
to clo...@googlegroups.com
It seems to be a packaging issue. As an aside note, if you do a github
checkout then run

python setup.py install

it seems to work just fine. But I'll look into this issue as well.

Timothy

2012/3/8 Daniel Janus <nat...@gmail.com>:

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

--
"One of the main causes of the fall of the Roman Empire was
that-lacking zero-they had no way to indicate successful termination
of their C programs."
(Robert Firth)

Laurent PETIT

unread,
Mar 8, 2012, 7:36:44 AM3/8/12
to clo...@googlegroups.com
Amazing!

What startup time performance improvements do you see for eg using
this platform for shell scripts-like stuff ?

Timothy Baldridge

unread,
Mar 8, 2012, 9:22:51 AM3/8/12
to clo...@googlegroups.com
Okay, the Python package should be fixed now. It took a few tries, but
I was finally able to get it to include core.clj as part of the
distro.

> What startup time performance improvements do you see for eg using
> this platform for shell scripts-like stuff ?

Currently, it's about 3sec on my machine. This is because we're
parsing/compiling all 2600 lines of core.clj on every start-up. One of
my tasks this week is to compile the file to bytecode, then serialize
this bytecode as a .cljc file. This is the method the rest of python
uses, and at that point we should have almost instant start-up times.

Timothy

--

“One of the main causes of the fall of the Roman Empire was

that–lacking zero–they had no way to indicate successful termination

Michael Wood

unread,
Mar 8, 2012, 10:46:09 AM3/8/12
to clo...@googlegroups.com
On 8 March 2012 05:42, Timothy Baldridge <tbald...@gmail.com> wrote:
> The Clojure-Py team is happy to announce the release of Clojure-Py 0.1.0.
>
> https://github.com/halgari/clojure-py
>
> Clojure-Py is an implementation of Clojure running atop the Python VM.

Looks interesting :)

What's the plan for ratios and characters? I assume they're still on
the TODO list? (Maybe Issue 17 covers the ratios?)

e.g.:

$ python clojure.py
clojure-py 0.1.0
user=> \a
Compiling \a


Traceback (most recent call last):

[...]
CompilerException: Compiler Exception could not resolve '\a', '\a' not
found in user reference fn_787
user=> (/ 22 7)
3
user=> 22/7


Traceback (most recent call last):

[...]
clojure.lang.cljexceptions.ReaderException: Invalid number: 22/7
$

--
Michael Wood <esio...@gmail.com>

Timothy Baldridge

unread,
Mar 8, 2012, 10:53:51 AM3/8/12
to clo...@googlegroups.com
> What's the plan for ratios and characters?  I assume they're still on
> the TODO list?  (Maybe Issue 17 covers the ratios?)

Yeah, I need to run a few more tests, but I'm thinking of somehow
layering libgmp ontop of Python in order to implement ratios.

The lispreader needs to be fixed to handle characters. I'll create a
bug report for that. Thanks!

Timothy

Shantanu Kumar

unread,
Mar 8, 2012, 2:11:54 PM3/8/12
to Clojure


On Mar 8, 7:22 pm, Timothy Baldridge <tbaldri...@gmail.com> wrote:
> Okay, the Python package should be fixed now. It took a few tries, but
> I was finally able to get it to include core.clj as part of the
> distro.

Thanks, the install works for me now. However, when I run "sudo
clojurepy" pressing Ctrl+D exits the REPL fine, but when I run
"clojurepy" without sudo I get the error below:

user=> ^DError in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
IOError: [Errno 13] Permission denied
Error in sys.exitfunc:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/
python2.7/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
IOError: [Errno 13] Permission denied

It exits the REPL nevertheless.

Shantanu

Timothy Baldridge

unread,
Mar 8, 2012, 2:13:57 PM3/8/12
to clo...@googlegroups.com
It looks to be a bug with where the script is saving the history file.
We have a bug report for it
https://github.com/halgari/clojure-py/issues/41 and we'll look into
it. Thanks!

Timothy

Daniel Gagnon

unread,
Mar 12, 2012, 2:16:49 AM3/12/12
to clo...@googlegroups.com
On Thu, Mar 8, 2012 at 10:53 AM, Timothy Baldridge <tbald...@gmail.com> wrote:
> What's the plan for ratios and characters?  I assume they're still on
> the TODO list?  (Maybe Issue 17 covers the ratios?)

Yeah, I need to run a few more tests, but I'm thinking of somehow
layering libgmp ontop of Python in order to implement ratios.


Why wouldn't Python fractions work as ratios? 

Timothy Baldridge

unread,
Mar 12, 2012, 9:24:18 AM3/12/12
to clo...@googlegroups.com
>
> Why wouldn't Python fractions work as ratios?

Actually Python fractions would work perfectly. And the decimal class
in Python should be included as well.

Thanks for pointing these libraries out to me!

Timothy

Daniel Gagnon

unread,
Mar 12, 2012, 12:57:33 PM3/12/12
to clo...@googlegroups.com
Actually Python fractions would work perfectly. And the decimal class
in Python should be included as well.

Thanks for pointing these libraries out to me!

Timothy 
 

No problem. I really like how symbiotic with Python you are making this.

Daniel Gagnon

unread,
Mar 12, 2012, 1:04:07 PM3/12/12
to clo...@googlegroups.com
On Wed, Mar 7, 2012 at 10:42 PM, Timothy Baldridge <tbald...@gmail.com> wrote:
The Clojure-Py team is happy to announce the release of Clojure-Py 0.1.0.

https://github.com/halgari/clojure-py

Clojure-Py is an implementation of Clojure running atop the Python VM.
As it currently stands, we have translated over 235 functions from
clojure.core. This is not a clojure interpreter in python; the
Clojure-Py compiler compiles clojure code directly to python code.
Clojure-py functions are python functions. Clojure-py types are python
types, Clojure-py name spaces are python modules

I'm seeing a RPython test in the examples. Can Clojure-Py emit RPython code from my Clojure code? If so, that'd be really great we could go Clojure -> RPython -> C -> Native

I guess it probably isn't since I imagine that laziness uses generators which aren't well supported under RPython but if it did use make RPython code, it'd be really awesome. 

Timothy Baldridge

unread,
Mar 12, 2012, 1:21:28 PM3/12/12
to clo...@googlegroups.com
> I'm seeing a RPython test in the examples. Can Clojure-Py emit RPython code
> from my Clojure code? If so, that'd be really great we could go Clojure ->
> RPython -> C -> Native
>
> I guess it probably isn't since I imagine that laziness uses generators
> which aren't well supported under RPython but if it did use make RPython
> code, it'd be really awesome.

Well that's the one part where Clojure and Python diverge. Clojure-py
does not use Python's generators. This is because Python's generators
are mutable. So that actually wont' be a problem.

What is a problem though, is the way Clojure-py currently accesses
vars. Consider the following:

(+ 1 2)

In Clojure-py we'd compile this as

LOAD_CONST #user/+
LOAD_ATTR deref
CALL_FUNCTION 0
LOAD_CONST 1
LOAD_CONST 2
CALL_FUNCTION 2

It's this first line that causes the RPython translator to blow up.
Calling LOAD_CONST and supplying a complex type like VAR is more than
it can handle. Now it just so happens this is completely acceptable in
normal Python code, so that's where the issue is.

My plan is to abstract this a bit. I plan on providing global vars
that allow the user to specify how the current code is bound. For
instance, if #user/+ is a static var, there's no reason to deref it
every single time, since it will never change. However, dynamic vars
need to be deref'ed, and RPython vars need to use pure LOAD_GLOBAL,
LOAD_ATTR calls. The plan then is to provide the Clojure-py backend
with a simple (deref this var) object that will allow the compiler to
on-the-fly decide how certain pieces of code are called.

It just so happens that once this is implemented, it will also allow
us to serialize clojure code using CPickle. This should allow us to
drop the startup times of Clojure-py down into the <1sec range.

And actually, being able to run Clojure code on RPython is a personal
goal for me. It's probably one of the biggest motivations for me to
actually start this project. So as I find time, I do plan on exploring
this, and building up a good macro/function library to allow users to
experiment with RPython a bit more easily.

Timothy

Reply all
Reply to author
Forward
0 new messages