1. I've been writing a couple of things in hy again this week. What's Hy? It's a cute idea. It's a lisp that compiles? (transpiles? I never get the difference) to the Python AST. I guess the elevator pitch might be something like clojure but for python. So yeah, a rich, super stable class-tree sort of OO language, with enormous portablility and twenty-odd years of library support for everything you might want to do, but with a nice, dynamic, lispy language and a repl.

    I've played with hy a little bit on and off over the years. Actually, when I was working at SMR, I actually deployed some in production. (Somehow, I doubt that's still a thing). Python is my go-to scripting language, because it's very plain, very portable, batteries included, somewhat modern, probably already installed everywhere I work. I try to use it for scripty things, rather than shell or perl or something. Lisps are my favourite programming language. I just like how it fits together. I know lots of people don't, and I'm fine with that, but I always enjoy it.

    So over the holiday weekend I found myself wanting a couple of almost throwaway scripts, and I decided to reach back into the hy bucket, and give that another try. I wrote a script to grab my selfie tweets from a twitter archive, and a rough script to publish formatted micro-blog entries directly from the shell.

    It was a fun exercise. Hy has moved on a bit since I last tried. (They seem to have removed let, and car, and cdr, and lambda which I feel funny about), but by and large it works really well.

    Things I like

    • I like mapping over lists of things, and in straight Python this is often clumsy and leads to densely nested comprehensions
    • actual lambdas!
    • Python3 support ( hy3 )
    • easy importing of python modules
    • mostly seamless python interop
    • repl works great
    • the repl shows you the pythonic syntax of the forms it evaluates, which is helpful if you know Python
    • emacs mode (obv)
    • it has lazy sequences
    • and multimethods!
    • it is fun to work in

    Things I like less

    • Missing some olde lisp things like car/cdr/lambda
    • Things often expect you to be using methods on stateful objects, which gets you an OO impedance mismatch (I have the same problems in scala and clojure)
    • Slightly more typed than you expect, whilst not really offering you a type system. (Particularly with distinctions between lists, sequences, iterators.)
    • it often seems easier to imperative loop with for than map / reduce / filters, and this seems weird.
    • i don't feel I have any understanding about setv variable scoping.
    • no STM, which I think is one of the most interesting things about clojure
    • I don't think the error handling does restarts and conditions and things

    Summary

    I don't think I would choose to use it to build any complicated systems. (Typically this is true of Python as well to be fair). I'd love to see something like an idomatic web framework in it. I could imagine using it to build serverless workers over something like apex up or chalice perhaps. I should totally try that!

    I am not really very good at it yet, so I doubt I'm writing optimal programs. My scripts often look like Dr. Moreau designs halfway between a python script and something more lispy. This could well improve as I understand the underlying sequence / itertools glue a bit more, I'm often routing around confusing sequenced things. I absolutely enjoy writing little scripts like this in it, and I think I maybe enjoy it more than I would if I was writing plain python. I gave some thought about why this might be and I think I figured it out.

    It could just be as simple as being all about the code editing. Python, and it's whitespace delimited blocks, is fine, and super readable, but it's always slightly fiddly to edit. Some of this is my toolchain, I'm sure. There's a lot of bells and whistles you can glue over emacs for Python work, and they're pretty good, but I do always find it a slightly fiddly experience. Balanced expressions and sexprs though are obviously an absolute joy to edit in emacs, alongside an embedded inferior lisp repl, and although it's nowhere near as integrated an experience as using slime with a "real" lisp, it's closer to that than editing Python ever feels, and for me that's a significant productivity win. So I think it will stay in the toolbox.

    I recommend Hy to anyone who is interested in interesting lightweight languages, especially scripting languages. Obviously it's particularly relevant to anyone who likes python or lisps, even if just as a curiosity. If you work with Python and like using emacs though, and like the sound of 'Python but with structured editing' I would strongly recommend you look at how it might integrate into your workflow.

    posted by cms on
    tagged as
  2. I ran into some problems while I was trying to install python bindings for the Growl notification framework on my MacBook Pro. My Mac is running the current release of Snow Leopard ( 10.6.4 ) and I'm using a python.org installed binary package of python, under /usr/local/python. Building using distutils and the supplied setup.py failed, seemingly because the compiler was unable to find quite routine include files, such as stdarg.h and float.h .

    /Developer/SDKs/MacOSX10.4u.sdk/usr/include/stdarg.h:4:25: error: stdarg.h: No such file or directory


    This error message both confused and perturbed me, because stdarg is a fairly fundamental component of a working C library, and I am pretty certain that my compiler isn't that fundamentally broken.

    Picking apart the build output from the generated Makefile, I see that it is setting the -isysroot gcc flag, to /Developer/SDKs/MacOSX10.4u.sdk/ . I presume this is because the python installation is built to use the OS X 10.4 compatability SDK. This is why it's pulling in /Developer/SDKs/MacOSX10.4u.sdk/usr/include/stdarg.h . That header is a stub, and included the following stanza



    /* GCC uses its own copy of this header */
    #if defined(GNUC)
    #include_next


    #include_next is a gcc extension to cpp, and instructs the preprocessor to start searching for the include file again starting with the next directory on the include path after this one. Standard libraries like stdarg and float can be quite compiler specific, and as the comment indicates, GCC is expected to have it's own copy of this header file, which would be put away somewhere under /usr/lib/gcc .

    At this point, a nagging memory of building cocoa apps with XCode resurfaced, suggesting that the 10.4 SDK isn't compatible with gcc-4.2 ( the system default gcc under snow leopard ). GCC 4.0 is supplied though, for use with building against legacy SDKs. On this whim, I tried exporting CC=/usr/bin/gcc-4.0 and rebuilding, and everything worked as it should.

    From inspection, it seems like the snow supplied leopard python is built to use 10.6 SDKs and gcc-4.2 and may well be a more sensible python to use. Further googling ducking , turned up this bug report .

    posted by cms on
    tagged as
  3. Apple released iTunes version 8 this week , which introduced some excellent new features , such as Genius playlists, but broke the fancy perl script that I wrote to rotate my music library on my iPod touch.

    While revisiting this, I took the opportunity to re-implement it, aiming to fix a few of it's faults, most specifically the terrible performance. I decided to use Python this time around, chiefly because of the existence of appscript , an apple event bridge with a nice syntax. Python's object and sequence semantics are a slightly better fit with AppleScript's data models, and appscript should be a more optimal solution than Mac::Glue for sending lots of messages iteratively.

    I've also improved the actual command recipe, using 'duplicate' rather than 'add' to build the playlist seems more efficient. Also the overhead of having to periodically build glue modules with the ' gluemac ' tool is removed. Sadly appscript isn't shipped with OS X, but installing it ( at least on Leopard ), is as simple as ' sudo easy_install appscript '.

    The concept behind the tool is the same : use a nominated playlist to synchronise the albums with the iPod, and pick a random set of albums from buckets organised by album rating. Currently it's set to shuffle in 10 '2 star' albums, 20 'three star' albums, and 30 'four star' albums, selected from a 'just music' smart playlist that filters the master library, removing all spoken word, and podcasts and other miscellany from the pool.

    Here's the source . I'm far less experienced at python than I am perl, so I wouldn't claim it was a particularly idiomatic solution. It does run many times more quickly than the perl / Mac::Glue solution, taking a minute or so, rather than the best part of an hour. I would put all the performance gains down to the AppleEvents bridge , appscript interface, and using more efficient apple event set operations, rather than iterating over individual data.





    posted by cms on
    tagged as