Posts filed under 'ruby'

How Tim Burks and Nu Stole the Show at C4[1]

Edit: Fixed some factual inaccuracies about the language itself.

Tim Burks, noted contributor to RubyCocoa and creator of RubyObjC, gave a talk at C4[1] about his experiences with creating a Ruby <-> ObjectiveC bridge, and the problems he overcame in doing so. It was an interesting presentation, and we were all suitably appreciative when he showed his custom visual chip-design software written in Ruby with a Cocoa interface.

And then he dropped a bombshell.

For the past year, Tim’s been working on a new dialect of Lisp - written in Objective-C - called Nu. Here are its features (more precisely, here are the ones that I remember; I was so awestruck that many went over my head):

  • Interpreted, running on top of Objective-C.
  • Scheme-y syntax. Everything is an s-expression (data is code, code is data). Variable assignment was done without let-clauses (which are a pain in the ass) - all one has to do was (set varname value).
  • Variable sigils to indicate variable scope.
  • True object-orientation - everything is an object.
  • True closures with the do-statement - which, incidentally, is how Ruby should have done it.
  • Macros. HOLY CRAP, MACROS! When Tim showed us an example of using define-macro for syntactical abstraction, Wolf Rentzsch and I started spontaneously applauding. His example even contained an example of absolutely beautiful exception handling that should be familiar to anyone with any ObjC or Ruby experience.
  • Symbol generation (__) to make macros hygenic and prevent variable name conflicts.
  • Nu data objects are Cocoa classes - the strings are NSStrings, the arrays NSArrays, etc.
  • Ability to create new Obj-C classes from inside Nu.
  • Interfaces with Cocoa libraries - you can access Core Data stores from within Nu in a much easier fashion than pure ObjC, thanks to Tim’s very clever idea of using a $session global to store the NSManagedObjectModel, NSManagedObjectContext, and NSPersistentStoreCoordinator.
  • Ruby-style string interpolation with #{}.
  • Regular expressions.
  • Positively drool-inducing metaprogramming, including a simulation of Ruby’s method_missing functionality.
  • A web-based templating system similar to ERb in 80 lines of Nu code - compare that with the 422 lines of code in erb.rb.

Tim showed us a MarsEdit-like blog editor written entirely in Nu, using Core Data as its backend - and then showed us the built-in Nu web server inside that program, complete with beautiful CSS/HTML/Ajax.

As F-Script is to Smalltalk, so Nu is to Lisp. Tim said that he hopes someday to open-source Nu; if he does, he will introduce what is quite possibly the most exciting development in the Lisp-related community in a long time. I don’t think I speak for just myself when I say I cannot wait to get my hands on it.


3 comments August 12, 2007

Ruby + ActiveSupport + Facets - Cruft = Awesome

Libraries are the soul of a programming language. If your pet language doesn’t have any useful prebuilt libraries for web/game/media/network development, it will never have an audience beyond the world of theory and academia.

Though Ruby’s standard libraries are - and this is purely my opinion - not as well-developed or extensive as those of Python (see: sqlite3, wsgiref, tabnanny, etc.), they nonetheless serve the majority of developers well. However, Ruby has a unique advantage in the area of libraries in its support for metaprogramming.

Since Ruby code can modify built-in classes such as NilClass, Ruby coders are given a degree of freedom that I haven’t found in any other language. Need to change the behavior of a method inside the String class? Simply write the method, send two alias_method messages to the String module, and boom! You’ve modified the Ruby language temporarily to fit your needs. Awesome, huh? And if you write a library that includes these changes to the base classes, you can seamlessly change the language and pass your changes onto your friends: no mucking about with compiler code here, my friends! This is metaprogramming!

The most notable sources for extensions to the Ruby language are the Facets of Ruby project and the Ruby on Rails ActiveSupport extensions. Take a gander through err the blog’s ActiveSupport Advent Calendar - look at how many useful methods there are! String.at(), String.each_char, the Numeric bytes methods, attr_accessor_with_default, Symbol.to_proc - for the love of Dijkstra, why isn’t this stuff in Ruby? It goes beyond pragmatics into the realm of principles - if, as Matz asserts, Ruby is based on the Principle of Least Surprise, then why am I so surprised that all of this stuff isn’t in there? :) Why does String.each by default iterate through substrings separated by spaces instead of doing the unsurprising thing and iterate through each of the characters (as a string, not a byte)?

And then there’s the silly, crufty things in the Ruby stdlib, the modules which, though they are neat and illustrative of Ruby’s power, don’t deserve to be bundled and packaged along with every Ruby installation. Sure, Abbrev is neat, but does it really merit that spot right alongside Array? Abbrev is the kind of thing you keep on CPAN, not inside the standard library. What, exactly, does this lovely yet undocumented Foo class do, and why is it in my Ruby installation? Shouldn’t an RSS parsing library be stored on rubygems instead of in the main libraries? It seems as though Ruby is leaving out vital ingredients and adding superfluous ones.

I call upon you, all you designers of Ruby - especially Rubinous, YARV, and JRuby - take a step back and look at your standard library. Cut out parts you don’t need, add parts you do, make a few organizational changes and soon people won’t need to follow “Ruby is better and purer than #{competing_language}” with “but its library support is sorely lacking.” Everybody wins.


2 comments January 29, 2007

Web Framework Nirvana

Let’s say you came up to me and said “Patrick, I want to start a Web 2.0 company. I have some great ideas, good web developers, a firm grip on the quagmire that is public relations; in short, I have everything except a web development framework. Which one would you recommend?”

My answer would be this: Though Turbogears is worse than Pylons, it is nonetheless the best web framework.

You would probably inquire what the hell I was talking about. Well, let me elucidate:

I believe that one of the reasons for the massive success of Ruby on Rails is David Heinemeier Hansson’s damn-the-torpedoes attitude towards Rails’s scope. DHH, being an extremely opinionated person, refuses to incorporate things he doesn’t like into his framework - but he incorporates everything he does like into it.

ORM? Check. Database migrations for aforementioned ORM? Check. Embed Ruby arbitrarily into your views? Check. Built-in script.aculo.us integration? Check. Single-minded, near-zombielike focus on unit testing? Check. A bunch of nifty code generators? Check. Regular-expression-powered routing system? Check. Vastly needed improvements to the Ruby language? Check. (Whether ActiveSupport should be incorporated into the main Ruby code base is another blog post. Sneak preview: Yes.)

The list goes on and on - in short, Rails has a bunch of functionality built in, but just as much functionality left out. There’s no easy system for template inheritance, no userauth system, no multithreading support. Rails is a monolith - don’t like the ORM? Too bad. Don’t like ERb? No one’s making you use Rails; go back to Perl::Mason. Don’t like feature X? Here’s what DHH has to say.

And many people love the fact that Rails is a full-stack framework, that they don’t have to juggle dependencies between templating systems and ORM’s, that they don’t need to worry that easy_install or gem will break everything. Rails has that market covered.

But true web framework nirvana comes from freedom of choice. I should be able to say OK, for this next web application I need a really powerful ORM - SQLAlchemy should be fine. I like Mako, let’s use that. Routes is nice, we’ll take it. Oh, and I want an authorization system, and I’ll whip up some slick Javascript widgets while I’m at it.

I’ve been spending time in the #pylons chat room, and I feel that the people working on Pylons are close to realizing that goal - that a web framework should come in parts, like Legos, and that you should just plug components into as minimal of a base as possible until you get exactly what you want. WSGI can allow us to build interchangable parts - at least I think so, as I’m still not 100% positive what WSGI actually is.

But Pylons, ToscaWidgets, Migrate, AuthKit, Mako - they’re all very young projects, still struggling under the scarlet letter ß for Beta. The pieces aren’t ready to be put together yet - like Legos, you can’t build elaborate structures with misshapen blocks.

Pylons is representative of the freedom of choice that I want. But it’s not ready. Turbogears has echoes of Rails in its inability to use anything for the controller except CherryPy, but on the whole, it allows you to make some choices as to ORM, templating system, and what have you. And even the incomplete measure of choice which Turbogears offers allows it to dominate over Rails for all but the simplest CRUD apps. Pylons should win on principle, but when companies and jobs hang in the balance you can’t entrust all you have to principle.

When Pylons and all its corresponding pieces are ready, it will be a sight to behold. Until then, use Turbogears.


2 comments January 29, 2007

Blocks != Functional Programming

Joel Spolsky is one of my heroes. He has a vast amount of insightful articles that rank among the clearest and most relevant software writing today, and his blog gets more hits in a day than mine ever will. (Speaking of which, I hit 2000 visitors yesterday - around 10x more than I ever thought I’d get.) He’s a very smart cookie, and when he speaks, people listen. But last week, while browsing the top Reddit articles of all time, I was surprised to see his article Can Your Programming Language Do This? at #4. While it’s a good primer on Javascript abstraction, I don’t think it deserves as many points as it recieved. I spent the next few days thinking about why this article bothered me so much - Joel certainly didn’t say anything untrue, attack any favorite language of mine, or make some outlandish claim. But then I realized that Joel’s article fit together in a pattern of recent articles, all of which bothered me slightly.

Here’s what I realized: it seems that every language under the sun is being evangelized as an excellent functional programming language simply because it supports a few paradigms from FP.

Or, restated: Anonymous functions do not a functional language make.

The most egregious example of a pundit claiming a language is functional when it’s clearly not is Eric Kidd’s well-known Why Ruby is an acceptable Lisp. Kidd tells us explicitly that Ruby is a denser functional language than Lisp - and I’ll be the first one to admit that if I were to debate the “denser” part of that sentence, I wouldn’t know what I was talking about.

But Ruby is not functional - Wikipedia calls it a reflective, object-oriented programming language, and I agree with them. Yes, you can have block arguments to methods, continuations, generators, reflection, and metaprogramming - but it isn’t functional, for two reasons.

1. It’s hard to carry around functions as objects.

I really don’t know why Ruby hates parentheses so much - it’s probably part of its Perl heritage. In Ruby, you can call methods without sticking superfluous parentheses in there - take a look at this Python code:

” I’ll write about Cocoa soon; disaster struck the app I was writing “.strip().lower().split()

Now take a look at the equivalent Ruby code:

” Apple’s releasing a tool
with XCode 3 which completely supersedes my Cocoa app - so I'm very depressed right now ".strip.downcase.split

Though you could put parentheses in front of strip, downcase, and split, Ruby will work just fine without them. Now, this feature makes for far fewer parentheses, thereby making code significantly more readable. But what if I want a previously-declared function as an argument? If I type in the name, Ruby will just evaluate the function. Sure, I could use the kludge that is Symbol.to_proc, but that’s ugly - and it wraps the function inside a Proc object, which has to be called with the call(*args) method. And that’s just ugly. In Python, all you need to do is type the function’s name to use it as an object, and append a pair of parentheses if you need to call it.

2. Variables are.

A purely functional language only has immutable variables. Ruby doesn’t. (Yes, I know LISP isn’t purely functional. But it adheres to so many other FP paradigms that we can overlook that.)

But I’m getting distracted, so I’ll cut the above point short.

Anyway, what I wanted to say was this - just because your pet language has support for anonymous functions/closures doesn’t make it a functional language. Sure, Python has lambda and list comprehensions (which are taken from Haskell, a purely functional language) - but it’s not functional, it’s object-oriented. Yes, Ruby has blocks (even if you do have to wrap them in Procs), but it’s not functional. Javascript may have support for anonymous functions, but its syntax can be traced back to Algol and the birth of imperative programming language. Hell, even Objective-C has blocks if you include the F-Script framework, and it’s the farthest thing from functional there is.

In conclusion, don’t say your language is a functional one just because you borrowed a few ideas from Lisp. If you want a real functional language, try OCaml, Haskell, ML, or Scheme. Calling imperative/OOP languages functional just makes the term meaningless.


10 comments January 2, 2007

How to Beat Rails

(Note: I really, really like Ruby and Rails. Anything disparaging that I say about either of them should be taken with several grains of salt. If I seem to be encouraging Pythoneers to crush Rails, it’s simply because I love both, and want all frameworks to be constantly innovating.)

Everybody with the slightest interest in web development has heard of Ruby on Rails. It thrust Ruby into the spotlight, created a hype machine that stubbornly refuses to go away, and made David Heinemeier Hansson a celebrity. I adore Rails - it’s by far the best web framework for simple CRUD apps. However, as a Python devotee, it hurt me deeply to see Ruby stealing the spotlight. As such, I embarked on a quest to find out why Rails is winning; I looked at Django, Turbogears, Pylons and web.py. After months of building the same simple CRUD app, I came to the following conclusion:

Python can beat Rails. It can grind it into a pulp in every way concievable - speed, elegance, coolness, extensiblity, organization, AJAXness, beauty, and flexibility. It can send Rails crying home to David while Guido basks in the Web 2.0 spotlight. But right now, Rails is thoroughly torching all of the Python web frameworks. The following is a list of recommendations that, if applied to a Python framework, could dislodge Rails from the position of King of the Web Frameworks.

(more…)


26 comments December 31, 2006

Worse is Better: Python templating systems vs. Rails ERb

(Disclaimer: Python is my favorite programming language; however, I do criticize it in this article. Please redirect flames to /dev/null.)

I’ve been comparing web frameworks lately, developing a relatively simple CRUD database-backed application that can support a few bells and whistles. I’ve checked out Ruby on Rails (who hasn’t?) Django, and Turbogears in my search, and realized something as I was hacking together some templates in Kid:

Python, a far more restrictive and inflexible language - one that would seem, on the surface, to be worse for web application development than Ruby - is better for programmers, designers and security by nature of its inflexibility.

Let me explain what I mean. When designing ‘views’ - the web pages that users will see - that need to be updated with data from a given database, it is natural to break the Model-View-Controller paradigm and embed some controller logic into the application. After all, it’s so much less effort to embed

<% found_books = Book.find_all(”title = ?”, given_title) %>

into your .rhtml files then to go back into the controller file, change the return types, and make sure everything works correctly. However, Python is whitespace-sensitive, and therefore is much more difficult to embed into HTML. As such, you can’t write the mixture of Ruby and HTML that makes Rails so easy to use.

This is a good thing. I am a strong advocate of separating the model, view, and controller; by the very fact that I can’t write a combination of Python and HTML, I am forced to go back into the CherryPy/Django controller codebase and write a properly formed, secure, and elegant SQL query. Normally laxity wouldn’t bother me, but I believe that any large web application will grow into a hideous, Nylartothepic tangle if the MVC rules are not followed to the letter.

I still love Rails, but I love the templating systems in Python even more. Because Python is so restrictive, people had to write templating systems the Right Way - and that’s a good thing for everybody.


1 comment December 3, 2006


About Me



I'm a college freshman, passionate about technology, programming (especially Cocoa and Python), and Apple.

By the way, 'important shock' is an anagram for 'Patrick Thomson'.

Meta

Links

Categories

Top Posts

Blog Stats