Archive for the 'Object Oriented Languages: Java, C#, Ruby' Category

Jun 24 2008

Functional (Meta)?Programming Stunts for Ruby and Groovy (and a Little Perl)

After I learned OCaml, my coding mindset was totally distorted. I started writing Java code that looked like this:

  public Collection<Foo> getCertainFoos() {
    return
      CollectionUtils.select(getFoos(), new Predicate() { 
         public boolean evaluate(Object o) {
            return SOME_CONSTANT.equals(((Foo)o).getProperty());
         }
      });
  }

This is kinda ugly in Java, but it’s simply what comes out when I was thinking this in OCaml:

List.find_all (fun i -> SOME_CONSTANT = i#getProperty()) #getFoos()

I also started slapping final everywhere — see Yet Another Reason final Is Your Friend. A ubiquitous use of final actually gave some nice patterns (in the “macro” sense of patterns), but raised all kinds of eyebrows and made my code unmistakable. This lead up to a unique coding style which you can see in my most involved open source project, JConch. Meanwhile, my co-blogger was talking about “The Hole in the Middle” Pattern, which is also a lay-up within FP circles but required some backflips to implement in Java (functional interfaces) and C# (delegates).

It wasn’t until the advent of Ruby and Groovy, though, that functional programming skills really became easier to use. Basically, because of the inline closure’s succinct syntax (and ability to access non-final variables), I could suddenly do all kinds of really fun stuff. This “fun stuff” was exactly the kind of stunts I was pulling in Perl back in the day (see the BEGIN block in my Text::Shift code for a reasonably accessible example), and it was part of the reason I loved Perl so much at the time.

So, I thought I’d share some more of these cute stunts with you.
Continue Reading »

Popularity: 6% [?]

6 responses so far

Mar 24 2008

My Frustrations with REXML: Ruby’s Standard Library for Reading/Writing XML; or, Ruby’s Problem Is Its Type System, and Don’t Try to Tell Me Otherwise

Edit: Once you get the gist of this rant, jump to the comments for a slightly more reasoned approach. Or my follow-up post which attempts to re-open the dialog.


So, I’m trying to do a little bit of XML reading/writing. Nothing major — read in an XML, grab out some values, and then store the raw XML into the database. I’m doing pretty much the same thing in Groovy, and the XmlSlurper made that blissfully easy.

Since the core library comes with the REXML parser, I figured that it was a nice, stable library, and I’d roll with it. The interface wasn’t as nice as XmlSlurper, but it seems like it would do.

This was the start of the pain.

In fact, the pain pissed me off enough to share my frustrations with the world. Hopefully someone finds this useful, and they can avoid the pain and suffering I put up with. And yes, I could spend the time I’m griping going through and fixing up all the bugs, but I shouldn’t have to for a language as mature as Ruby. Core libraries are supposed to be stable, reliable beasties. If I wanted to spend all my time debugging half-baked implementations or rolling my own solutions, I’d never leave Ocaml — I come to Ruby for the community support. That’s supposed to be the big advantage.

Anyway, here we go:

Problem #1 came along when I tried to parse XML. First of all, the API documentation completely sucks — if you look at the top level REXML package, it’s totally worthless. If you manage to figure out that it’s REXML::Document that you probably want, you’re still not much better off. If you check out #new, which is really what you probably want, you’re rewarded with one word: “Constructor” You also have some “@param” tags that ran together and tell you things like the second argument, called “context”, should be a Hash of the context. That clears up a lot! And, seriously, if you’re telling me that it should be a Hash in the documentation, why aren’t we just doing implied static typing and being done with it?

Anyway, I retreated to Google, found the REXML tutorial, and managed to figure it out from there.

But then I kept having this annoying bug: when I called Element#text(), it was not only ignoring my instructions to leave entities alone (i.e. don’t turn “&lt;” into “<”), but it then seemed to go through and attempt to re-parse it, because it was complaining about unbalanced tags! Principle of Least Surprise my ass(1)! I’m not sure why the second part of that was happening, but the first part is apparently documented, so I stopped using the easy-to-read convenience method and went to Element#write.

This is where the real pain began. See, Element#write is broken. Deprecated and broken, actually. But the tutorial still tells you to use it. The solution is to use their Formatter approach. Except — ready for it? — that’s broken, too! No, I’m not kidding. In this language core library, both versions are broke! The solution is for me to reach in and make a change to the core library so that we avoid a null. In the standard Ruby deployment, using the standard core XML processing library, there is no way to write out XML. It is impossible because of bugs in the library.

The worst part?

THAT STUPID BUG IN THEIR CORE LIBRARY WOULD HAVE BEEN FIXED WITH STATIC TYPING. Even more if you have a type system which can check nulls for you. Null pointers/”nil when you didn’t expect it!” errors are totally solvable problems. The fact that our industry hasn’t moved past this painful left-over from C is driving me crazy. The next person who tries to tell me that dynamic typing is the best thing since sliced bread is going to get an earful. It is a flat-out wrong position, and I’m done hearing otherwise from anyone.

(1) As much as I’d love to claim that quote, it actually comes from Paul Cantrell’s excellent exploration of closures in Ruby.

Popularity: 20% [?]

19 responses so far

Mar 15 2008

JConch 1.0 Released

Bet you didn’t see that coming!

I’ve decided that I’m going to punt on the pipeline stuff and declare what I have for JConch to be the 1.0 version. I’m going to spend some quality time getting the system into Ivy, and then I’m going to declare JConch done until I hear otherwise. I’ve created a few issues over at the Google Code page — if there are other enhancements you’d like to see in JConch, that’s the place to put them.

This is the last post I’m going to do here about JConch — from here on out, I’m going to be posting all this stuff to the GoogleCode wiki or the mailing list. If you want to get updates, subscribe to the Google Group:

Google Groups
Subscribe to JConch Discussion Group
Email:
Visit this group

You can also subscribe to the RSS feed for the group here.

Popularity: 2% [?]

No responses yet

Mar 14 2008

Exercising Dynamic Web Frameworks, or, How Do I Test These Friggin’ Controllers Anyway?

One of the things that has always fascinated me about dynamic languages is how you go about testing them.

See, the trick is that when I write a closed implementation of some sort — whether it be a closed class or module — I’ve got some concept of the boundaries that my object’s state could be in. I’ve got a system which is locked in, probably with some state-machine-like semantics. So my unit tests wrap the flows that I understand, and verify that trying to violate those flows fails in some known way, and then I have reasonable confidence that things are good.

But dynamic languages that offer open implementations (like Perl, Groovy, and Ruby) really shoot that approach in the foot. Anything can be touched, and anything can be changed, and there’s nothing you (the original implementor) can do about it. This means that your unit test suite is going to be more incomplete, in the sense that your unit tests will exercise a much smaller portion of the field of possible ways in which your code might be used.

Worse, a common pattern in dynamic language development relies on external intervention in order to have it make sense. It’s extremely postmodern, actually: the code is gibberish without a context, making calls to methods and variables that simply don’t exist unless you have some kind of intervention. At this point, efforts to unit test are doomed to failure, because without the external intervention, there is nothing meaningful to test. With the external intervention, you’re really talking about an integration test.

Any interesting example of this is the particular case of controllers and views in Grails and Rails. Controllers are notoriously difficult to unit test, because they’re riddled with dynamically provided methods. Efforts to solve this via mocking are really treading on dangerous ground.

My solution right now is to not unit test them at all.
Continue Reading »

Popularity: 7% [?]

20 responses so far

Feb 17 2008

GroovyCacheMap

Since it was easy enough to do, I just created a GroovyCacheMap, which takes a Groovy Closure (see info at “Closures“).

Someone with a Groovy background wanna make sure that it’s sufficiently groovy-esque for users, and start fishing for those really horrible surprises?

I should really be working on the pipelines. But there’s a lot of annoyance there, and I miss being productive.

Popularity: 4% [?]

3 responses so far

Next »

Green Web Hosting! This site hosted by DreamHost.