May 1 2010

py2rb: A Python-to-Ruby Porting Assistant

I’ve never figured out whether I prefer Python or Ruby, so I’ve written things in both languages. Sometimes I start in one and decide I’d rather use the other. Unfortunately, converting code is painful, even though both have fairly similar syntax. For instance, converting to Ruby means inserting zillions of “end” statements!

Having a need to do this recently, I lazily looked around for a script that would do the grunt-work of Python-to-Ruby translation. I couldn’t find one, so I ended up writing one myself. And I’ve uploaded it for the benefit of others who might have the same need, and who might even improve it.


Dec 20 2008

Lazyweb: Is there a Ruby template engine like Genshi or Kid?

Ruby has a wide variety of HTML/XML templating engines, but none of the ones I’ve found work the way I’d like. It’s quite possible I’ve overlooked some, though.

My current gold standard for templaters is the Python library Genshi (which was inspired by Kid)—what I like about these is that your templates are valid XML: the parameters and control structures are expressed as special XML attributes and tags. This makes it easy to edit your templates in syntax-checking XML editors, and guarantees that your app serves valid XML or HTML.

But as I said, none of the Ruby template engines I’ve seen work this way. They’re all either generic macro systems that intermix markup and Ruby (like ERB), or they’re ruby APIs that output markup (like Builder, HAML and Markaby). I don’t really like either approach.

If you’ve got a good suggestion, I’ve got a gold star ready to stick on your forehead!


Dec 6 2008

James Bennett: “Let’s talk about Python 3.0”

James Bennett has posted a very informative defense of Python 3, in reaction to my more negative article.

I learned things from it, as from many of the comments on my post. I even agree with most of what he says, but it hasn’t really changed my opinion, because it seems like we’re not talking about the same things.

From the standpoint of writing Python code, Python 3 sounds great. It’s so nice not to have to deal with crufty APIs that don’t make sense anymore, or half-baked mechanisms like the original string class.

But from the standpoint of using Python libraries, I still think this is terrible. Any time I want to use a library I’ll have to check whether it works with the version of Python I’m on. I may find that a library I use, and need updates to, will no longer support Python 2.x going forward. And the porting and branch-maintenance process will definitely take time out of library developers’ schedules, slowing down other work.

(Since James had several great quotes in his article, here’s one making my point: In Elbonia, cars have always driven on the left side of the road. Finally, the government decides that it’s time to [...]


Dec 4 2008

Python 3.0: What’s The Point?

Python 3.0 is finally out. I like Python (though it and Ruby are always competing for my affections), and I’m always a sucker for new features in any language, but I’m having trouble getting excited about this. Despite the longtime code-name “Python 3000”, it doesn’t seem very futuristic; and it introduces a lot of compatibility problems. In fact, after reading the docs, I can’t come up with any good reasons to install or use the new version. Am I missing something?

Looking at the official What’s New page, my takeaway is that the benefits are:

A bunch of minor language features cleaned up
Better (at least less confusing) Unicode support
Some nice but minor new syntactic features

while the drawbacks are:

Won’t run any pre-existing Python software. Just one minor example: the xrange() function no longer exists; instead, range() behaves the way xrange did. I’m pretty sure I’ve written something like “for i in xrange(a,b)” in every significant Python program I’ve ever written, causing all of them to break in 3.0 until I update them. Which is trivial; but there are dozens and dozens of changes like this. And many of them won’t cause easy-to-diagnose exceptions like the removal of xrange; some just cause subtle changes [...]


Aug 30 2008

Blocks/Closures For C!

Chris Lattner, of Apple’s compiler team, writes :

Until there is more real documentation, this is a basic idea of Blocks: it is closures for C. It lets you pass around units of computation that can be executed later. For example:

void call_a_block(void (^blockptr)(int)) {
blockptr(4);
}

void test() {
int X = …
call_a_block(^(int y){ print(X+y); }); // references stack var
snapshot

call_a_block(^(int y){ print(y*y); });
}

In this example, when the first block is formed, it snapshots the value of X into the block and builds a small structure on the stack. Passing the block pointer down to call_a_block passes a pointer to this stack object. Invoking a block (with function call syntax) loads the relevant info out of the struct and calls it. call_a_block can obviously be passed different blocks as long as they have the same type.

This is very exciting: it’s the kind of new abstraction the C family has needed for years. As you know if you’ve worked in Ruby or Python or Smalltalk or any functional language, the ability to declare an anonymous function inline, and pass it as a parameter to another function, opens the door to creating new and useful control structures. Blocks are to control structures as [...]


Jun 17 2008

JavaScript 2.0, aka ECMAScript 4

I just discovered that there is an ECMAScript 4—better known as JavaScript 2.0—in development. As a shameless language slut, I immediately dove into the language overview, and it’s pretty neat.

This turns JavaScript into a much more useable language, that I could see doing serious development in. I’m well aware that today’s JS isn’t a “toy”, that it’s got an interesting prototype-based object model under the hood; but I’ve found the language so loose as to be difficult to use. This new version adds a full class model, much better support for iteration, a form of generators/coroutines, and more.

Intriguingly, it also offers type-checking, which has been absent from most mainstream dynamic languages. I know it’s trendy to use “duck typing”, but I find that languages with no compile-time type-checking frustrate me because I make so damn many mistakes that aren’t caught until runtime; which means things I could have fixed in two minutes in C++ or Objective-C take half an hour to fix as I run the program over, and over, and over, discovering and fixing one problem at a time.

Given the concurrent developments in Apple’s JavaScript interpreter, I’m getting pretty excited for JavaScript. I hope that in addition to making [...]


Apr 30 2008

Coroutines in Objective-C

I’ve started using NSOperation in a few places in Cloudy, which means I’m backsliding into using threads and locking and so forth. It definitely makes writing network code easier than Cocoa’s asynchronous API, but I really don’t want to get into a morass of threads.

What I’d really like to use are Actors. In a nutshell, an Actor is an object that has its own [cooperative] thread and message queue. Actors interact by message-passing instead of shared state. The idea is to eliminate the need for standard synchronization primitives like semaphors and locks, and get rid of the race conditions and deadlocks that plague multi-threaded programs.

The page I linked to above is from Revactor, a new Actor implementation for Ruby 1.9; Actors are also built into languages like Erlang and Io.

The only hard part about implementing Actors in Obj-C appears to be the underlying dependency on coroutines. Steve Dekorte [author of Io] has a C coroutine implementation ; when I discovered that last year, I then found an Objective-C wrapper for it, but that relies on a HigherOrderMessaging library which is incompatible with OS X 10.5 and hasn’t yet been updated.

So I’ve gone DIY.

I started with Steve Dekorte’s coroutine library, but [...]


Mar 1 2008

MacRuby

MacRuby “is a version of Ruby that runs on top of Objective-C. More precisely, MacRuby is currently a port of the Ruby 1.9 implementation for the Objective-C runtime and garbage collector. The rationale behind this effort is to solve in a very efficient way all the bridging problems RubyCocoa, the Ruby bridge to the Objective-C runtime, has to work around.” (It’s still in development, and not ready for prime-time use yet.)

This is exciting news. Now, Mac OS X already has excellent Ruby support, with a complete Ruby 1.8 and Rails stack (including extras like Mongrel and Capistrano) included in the box. There’s also a glue library called RubyCocoa that bridges between the Ruby and Objective-C languages, making it easy to write all or part of a Cocoa app in Ruby (or to call useful Obj-C frameworks from a Ruby app.)

So why MacRuby? The big deal is performance. By re-implementing the Ruby object model on top of the Objective-C runtime — so all Ruby objects are bona fide Objective-C objects and vice versa — it will eliminate serious amounts of overhead:

Parameter marshalling whenever a Ruby method has to call into Objective-C or vice versa
Bookkeeping data structures that map between Ruby and [...]


Feb 6 2008

Network Barbie Says “Asynchrony Is Hard!”

You can’t avoid asynchrony when writing network code, since operations can take an arbitrary amount of time, and often do. To keep the app responsive it has to be able to get other things done while a slow operation is in progress.

My first exposure to network programming was in Java, whose approach to asynchrony is to use threads. Lots of ‘em. The API calls are [almost] all blocking, so you run them on background threads. This is good because it makes the way the API works more intuitive: you call a method, and it returns a value when it finishes. This makes your own code more intuitive, as it just performs the operations in order, like: open connection, send request, read response, parse response, close connection, return.

The downside is that making heavily threaded code work correctly can be very hard, and the problems are subtle, hard to understand and debug, and sometimes almost impossible to reproduce. Edward Lee’s paper The Trouble With Threads describes a complex Java server that was excruciatingly well-designed, code-reviewed and tested.

“No problems were observed until the code deadlocked in April 2004, four years later. Our relatively rigorous software engineering practice had identified and fixed many concurrency [...]


Jan 30 2008

96 Characters Ought To Be Enough For Anyone

Famous Hacker Paul Graham on his new LISP dialect, Arc:

“Arc only supports Ascii. MzScheme, which the current version of Arc compiles to, has some more advanced plan for dealing with characters. But it would probably have taken me a couple days to figure out how to interact with it, and I don’t want to spend even one day dealing with character sets. Character sets are a black hole. I realize that supporting only Ascii is uninternational to a point that’s almost offensive [...] But the kind of people who would be offended by that wouldn’t like Arc anyway.”

That last bit [emphasis mine] sort of flummoxed me. Is he saying that LISP only appeals to native English speakers?[1] Or that no one in their right mind would use LISP to write software for end-users?[2] Or maybe that internationalization is just some sort of abstract feel-good political-correctness issue, since none of those third-worlders even have computers anyway?[3]

He makes similarly eye-opening assertions about HTML, too. Arc has HTML-generating libraries, but they “just do everything with tables” instead of CSS. Why? Because apparently CSS-based Web designs are less agile than ones made out of tables. Somehow I don’t think most people who’ve done web [...]