Hylang

785 views
Skip to first unread message

Rui Carmo

unread,
Nov 9, 2013, 3:56:26 PM11/9/13
to clojure...@googlegroups.com
I came across http://hylang.org/ today, and am extremely impressed with it (even pdb works!).

Since it uses python AST, would it help move clojure-py forward? I'm tempted to just toss in bits of clojure-py and see where it breaks...

Antony Lee

unread,
Nov 9, 2013, 8:29:15 PM11/9/13
to clojure-py-dev
I think targeting the AST as Hy does is the way forward.  Targeting the bytecode is impossible to maintain (this is why clojure-py does not support Python 3).

The other huge advantage of Hy is that it does not attempt to reproduce the Clojure object model, but just the Python one.  Namespaces are just modules, objects are not wrapped in Vars, simple binary ops (+, -, etc.) are not wrapped in 1/ a Var and then 2/ a function that calls the BINARY_ADD opcode, etc.  I saw somewhere a comparison of fibonacci according to which Hy is much faster than clojure-py; if you look at the bytecode it's not a surprise:

$ hy -c '(import dis) (defn f [n] (if (< n 2) 1 (+ (f (- n 1)) (f (- n 2))))) (dis.dis f)'
  1           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       16
             12 LOAD_CONST               2 (1)
             15 RETURN_VALUE        
        >>   16 LOAD_GLOBAL              0 (f)
             19 LOAD_FAST                0 (n)
             22 LOAD_CONST               2 (1)
             25 BINARY_SUBTRACT     
             26 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             29 LOAD_GLOBAL              0 (f)
             32 LOAD_FAST                0 (n)
             35 LOAD_CONST               1 (2)
             38 BINARY_SUBTRACT     
             39 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             42 BINARY_ADD          
             43 RETURN_VALUE        

(which is the same as the bytecode for the naive Python implementation, of course)

$ clojurepy                                                            [13-11-09 17:25:16]
clojure-py 0.2.4
Python 2.7.5 (default, Sep  6 2013, 09:55:21)
[GCC 4.8.1 20130725 (prerelease)]
user=> (defn f [n] (if (< n 2) 1 (+ (f (- n 1)) (f (- n 2)))))
#'user/f
user=> (dis/dis f)
  0           0 LOAD_CONST               1 (<function <_auto_ at 0x1004f50>)
              3 LOAD_FAST                0 (n)
              6 LOAD_CONST               2 (2)
              9 CALL_FUNCTION            2
             12 STORE_FAST               1 (p0__1443#)
             15 LOAD_FAST                1 (p0__1443#)
             18 LOAD_CONST               0 (None)
             21 COMPARE_OP               9 (is not)
             24 POP_JUMP_IF_FALSE       45
             27 LOAD_FAST                1 (p0__1443#)
             30 LOAD_CONST               3 (False)
             33 COMPARE_OP               9 (is not)
             36 POP_JUMP_IF_FALSE       45
             39 LOAD_CONST               4 (1)
             42 JUMP_ABSOLUTE          117
        >>   45 LOAD_CONST               5 (#'clojure.core/+)
             48 LOAD_ATTR                0 (deref)
             51 CALL_FUNCTION            0
             54 LOAD_CONST               6 (#'user/f)
             57 LOAD_ATTR                0 (deref)
             60 CALL_FUNCTION            0
             63 LOAD_CONST               7 (#'clojure.core/-)
             66 LOAD_ATTR                0 (deref)
             69 CALL_FUNCTION            0
             72 LOAD_FAST                0 (n)
             75 LOAD_CONST               4 (1)
             78 CALL_FUNCTION            2
             81 CALL_FUNCTION            1
             84 LOAD_CONST               6 (#'user/f)
             87 LOAD_ATTR                0 (deref)
             90 CALL_FUNCTION            0
             93 LOAD_CONST               7 (#'clojure.core/-)
             96 LOAD_ATTR                0 (deref)
             99 CALL_FUNCTION            0
            102 LOAD_FAST                0 (n)
            105 LOAD_CONST               2 (2)
            108 CALL_FUNCTION            2
            111 CALL_FUNCTION            1
            114 CALL_FUNCTION            2
        >>  117 RETURN_VALUE       
nil

Oh my...

So basically Hy is just a nice (if you like lisp) way to write Python code.  Which is good to have, of course, and I think if you want to use Clojure libs on top of that you basically "just" need to reimplement whatever parts are needed of the Clojure API in Python.

Antony


2013/11/9 Rui Carmo <rca...@gmail.com>
I came across http://hylang.org/ today, and am extremely impressed with it (even pdb works!).

Since it uses python AST, would it help move clojure-py forward? I'm tempted to just toss in bits of clojure-py and see where it breaks...

--
You received this message because you are subscribed to the Google Groups "clojure-py-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure-py-de...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Adam Feuer

unread,
Nov 9, 2013, 9:55:39 PM11/9/13
to clojure...@googlegroups.com
On Sat, Nov 9, 2013 at 5:29 PM, Antony Lee <anton...@berkeley.edu> wrote:
So basically Hy is just a nice (if you like lisp) way to write Python code.  Which is good to have, of course, and I think if you want to use Clojure libs on top of that you basically "just" need to reimplement whatever parts are needed of the Clojure API in Python.

Nice approach. It seems doable.

Hy seems like a good place to start since it has a lot of Lisp already working.

-adam
--
Adam Feuer <ad...@adamfeuer.com>

John Jacobsen

unread,
Nov 9, 2013, 10:59:20 PM11/9/13
to clojure...@googlegroups.com, ad...@adamfeuer.com
I had a lot of fun playing with/contributing to Hy when it first came out.  The AST manipulation is a neat approach, and I was impressed by its startup speed for short tasks (where Clojure and Clojure-py might perhaps be slower).

Though this might be a slight aside, regarding implementing Clojure libraries/API in Python: the Toolz project (http://toolz.readthedocs.org) is a growing implementation of many "functional" operations in Python based on / inspired by the Clojure API and similar libraries from other functional languages.  It may be of utility to people working on Python-based Lisps or anyone attempting to write Python in a more functional style.  (New contributors are most welcome.)  

Cheers,
John

Deniz Kurucu

unread,
Nov 10, 2013, 4:00:16 AM11/10/13
to clojure...@googlegroups.com, ad...@adamfeuer.com
Hi,

Is there any ongoing development on clojure-py? I would like to follow and help if i can.

Thanks.


--

Antony Lee

unread,
Nov 10, 2013, 2:00:34 PM11/10/13
to clojure-py-dev
No, you should go have a look at Hy...


2013/11/10 Deniz Kurucu <makk...@gmail.com>

Rui Carmo

unread,
Nov 11, 2013, 5:32:14 AM11/11/13
to clojure...@googlegroups.com, anton...@berkeley.edu
Maybe refactoring clojure-py atop hy is doable, as long as enough of clojure.core can be ported over? I'd love to be able to run "common" .clj files atop a Python runtime - and hy seems to work OK in pypy, too, which makes it all the more appealing.

Timothy Baldridge

unread,
Nov 11, 2013, 7:51:30 AM11/11/13
to clojure...@googlegroups.com
Firstly, yes, take a look at hy. It seems to be a very capable lisp on top of Python. My future RPython development will probably be done in Hy.

Yes, the goals if clojure-py and hy are completely different. Hy is designed to be python with a lisp syntax. Clojure-py was designed to be a variant of Clojure running on the python VM. Complete with immutable collections, dynamic vars, etc. This is both a  blessing and a curse. I prefer the Clojure semantics, but the amount of work that had to be done to get this to happen meant that clojure-py was quite a bit slower than "native" python. 

Porting most Clojure code to Hy will be impossible. Hy is still based on the same mutable constructs that Python uses, and so it carries the same drawbacks. 

At this point I've moved on from Clojure-Py. The amount of hoops I needed to jump through to get Clojure semantics on Python ended up having too many drawbacks. 

Thanks,

Timothy Baldridge (halgari)
“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)
Reply all
Reply to author
Forward
0 new messages