Archive for January, 2008

Ruby and WS

January 29th, 2008  |  Published in code generation, dynamic languages, productivity, Ruby, services, WS-*, WSDL  |  Bookmark on Pinboard.in

Via Stefan Tilkov: Assaf Arkin talks about his upcoming book, Ruby in Practice. I don’t know anything about the book, but it sounds interesting.

Assaf talks about having a nice Ruby interface for WS, and also talks about wrapping Websphere MQ with Ruby. It reminded me of some work I was doing about a year and a half ago, when I still worked for IONA: developing a Ruby wrapper for Artix. I left there before it ever saw the light of day, so I doubt anyone will ever see it, but it was pretty cool. It was implemented using only customer-visible C++ APIs, and it afforded at least an order of magnitude reduction in the number of lines of code required to get anything done. It used WSDL4R to interpret a WSDL definition at runtime and dynamically generate accessor functions for the service, i.e., there was no up-front static code generation. You could point the client at the service, and if the service supported access to its WSDL (typically via a ?wsdl query string added to the service URI), the client could download the WSDL and dynamically generate everything required to access that service. I wrote about how to develop such Ruby extensions in my Sep/Oct 2006 IC column.

I remember presenting an example of the system in an internal sales engineering meeting where the original C++ and Java code required 70-80 lines of code while the equivalent Ruby code was only 7 lines. It wasn’t 7 lines of obfuscated expert-only Ruby, either; it was quite easy to read and understand. The SEs, most of whom worked only in Java and C++, kept looking at it and scratching their heads. They’d say, “Hey, you forgot to do this!” and I’d say, no, that happens right here. And they’d say something similar about another required action, and the answer was always the same: no, it’s in there. Basically, Ruby allowed me to hide a bunch of crufty, verbose, uninteresting but required boilerplate and focus only on service interactions. Waaay nicer than the equivalent Java and C++, for sure.

On a related note, just prior to that project, I did some work with Apache CXF to develop a server-side JavaScript and E4X JAX-WS capability. Since I no longer work in the middleware or WS worlds, I haven’t kept track of that code, so I don’t know if CXF still supports it or not. But either way, given the fact that JRuby now exists, there’s no reason that someone couldn’t take that work and redo it in JRuby. It would be pretty straightforward.

Elisp

January 24th, 2008  |  Published in code, emacs, emacs-lisp  |  Bookmark on Pinboard.in

Today I saw two blog postings about emacs-lisp, which is unusual given the feeds I pay attention to. I’ve been using emacs since 1985, and so over the years I’ve written more than my share of elisp. I didn’t know anything about Lisp when I started, so I learned by doing, first by just reading other code, then experimenting and adopting more and more patterns and approaches as I came to understand them. Over the years I’ve studied Lisp here and there on my own and so have improved my elisp, I think, but I’d never call myself an expert. I’ve never worked closely with anyone who enjoyed writing elisp as much as I do, so with nobody to bounce ideas off of, I’m sure there’s still much I can learn.

The first posting I saw today is about the proper handling of association lists, or alists. An alist is a list of key/value pairs, and one critical way they’re used in emacs is for the auto-mode-alist, which indicates what editing mode a given file should be set into when it’s visited. The mode is chosen by attempting to matching each key in the alist against the name of the file being visited; when one matches, it treats the associated value as a function and executes it in the file’s buffer. Such functions usually set the editing mode of the buffer. The keys are typically regular expressions that match file suffixes.

The author of that post had been using the aput function to replace elements of the auto-mode-alist with the editing modes he preferred, but recent changes to emacs resulted in aput being moved to the assoc package, so it was no longer directly available for use in the author’s ~/.emacs startup file. The author’s search for a substitute function to use instead resulted in him getting some bad advice about how alists are handled, and his posting explains how things really work.

One obvious way to fix the problem is to simply (require 'assoc), which would load the assoc package and make aput available. The author didn’t to want to do that, probably to avoid dragging in everything else the package defines. So, he instead resorted to using the push function to prepend elements to the auto-mode-alist to indicate his preferred editing modes. As he explains, file loading always searches the alist from head to tail, and so will always find his settings first, even if the same key patterns occur later in the list.

Another way to do it — a more fun way, perhaps — is to write your own version of aput. The code is interesting because it requires you to pass the alist essentially by reference to the function so it can modify it. The second elisp posting I saw today was Steve Yegge’s “Emergency Elisp” tutorial, and he mentions pass-by-reference but doesn’t really say how to do it, so let’s look at a way to do that. Here’s my version of aput:

(defun my-aput (alist key value)
  (let ((al (symbol-value alist))
        cell)
    (cond ((null al) (set alist (list (cons key value))))
          ((setq cell (assoc key al)) (setcdr cell value))
          (t (set alist (cons (cons key value) al))))))

This doesn’t do exactly what the real aput does, since it doesn’t handle the case where a key with a nil value is passed, but that’s not needed for the auto-mode-alist case. The function expects the alist, the key, and the value. As the three cases of the cond statement show:

  1. if the alist is empty, set it to a list consisting only of the new key/value pair;
  2. if we find the key, replace its associated value with the value passed in;
  3. otherwise prepend the new key/value pair to the front of the alist.

The key to making this work, though, is that we don’t really pass the alist. Instead, we pass the symbol for the alist. The symbol is kind of like a reference, in that it lets us get at the value of the alist, which we do in the first line of the function via the symbol-value function. Our first condition tests the alist to see if it’s nil; if so, we set a new alist value for the symbol. Our third condition (which always runs if the first two don’t, since it tests the value of t, which is always true) also sets a new value for the symbol by prepending a new key/value pair onto the current alist value.

To call it, we do this:

(my-aput 'auto-mode-alist "\\.erl\\'" 'erlang-mode)

Note how we quote the auto-mode-alist, so rather than evaluating it and passing its value, we pass just its name, or symbol, effectively giving us pass-by-reference.

Elisp is the primary reason I keep using emacs. It’s amazingly powerful. You can make it do all kinds of editing chores for you. A lot of people today tend to rely on their IDEs, and I even tried to move to Eclipse a few years ago, but I just don’t think there’s any IDE that can match the power and extensibility that elisp gives you. I’m sure I’ll get a few disagreeable comments for that remark, but they’ll almost certainly be from people who don’t know elisp.

Since I’m not an elisp expert, though, my explanation might be off in some way, and it’s probably possible to improve my code. All constructive criticism is welcomed!

Internet Computing Call for Special Issue Proposals

January 22nd, 2008  |  Published in distributed systems, integration, performance, publishing, REST, reuse, scalability, services  |  Bookmark on Pinboard.in

As you may know, I’m a columnist for IEEE Internet Computing (IC), and I’m also on their editorial board. Our annual board meeting is coming up, so to help with planning, we’ve issued a call for special issue proposals.

The topics that typically come up in this blog and others it connects to are pretty much all fair game as special issue topics: REST and the programmatic web, service definition languages, scalability issues, intermediation, tools, reuse, development languages, back-end integration, etc. Putting together a special issue doesn’t take a lot of work, either. It requires you to find 3-4 authors each willing to contribute an article, reviewers to review those articles (and IC can help with that), and a couple others to work with you as editors. As editors you also have to write a brief introduction for the special issue. I’ve done a few special issues over the years and if you enlist the right authors, it’s a lot less work than you might think.

As far as technical magazines go, IC is typically one of the most cited, usually second only to IEEE Software, as measured by independent firms. I think one reason for this is that it has a nice balance of industry and academic articles, so its pages provide information relevant to both the practitioner and the researcher.

More REST and IDL

January 20th, 2008  |  Published in CORBA, HTTP, IDL, REST, services, WSDL  |  Bookmark on Pinboard.in

Regarding the REST and IDL discussion, Joe Gregorio already wrote an excellent explanation six months ago. Perhaps the rest of us should have just linked to it to begin with and avoided wasting our time rehashing it all.

But then again, rehashing is fun! :-) On the same topic, I agree with much of what Dare said, except for this:

When building services with WS-*, you have a WSDL to describe your methods & expected inputs/outputs and XSD schema(s) to describe the schemas for said inputs/outputs. When building a RESTful Web Service, the need for both of these documents does not go away regardless of how often you repeat the phrase “uniform interface”.

I still disagree. The HTTP verb set defines a RESTful uniform interface. When comparing CORBA IDL or WSDL to HTTP web services, that verb set must be considered because it’s the only thing that you can directly relate to IDL and WSDL interfaces. Otherwise, you’re talking apples and oranges. The uniform HTTP interface is the only way for applications to interact with web resources in the same sense that CORBA applications interact with CORBA objects, and WSDL applications interact with WSDL services.

Much of the typical IDL and WSDL definition is devoted to defining one or more specialized interfaces consisting of specialized methods/operations and specialized data types to pass across them. For web resources that use the uniform interface, however, there’s simply no need whatsoever to define interfaces like that. What are you going to do, define GET again and again for each of your resources, each time with exactly the same semantics already specified in RFC 2616? Obviously not.

It’s easy to see that Joe’s OpenSearch document bears no semantic resemblance to a CORBA IDL or WSDL definition. Similarly, an AtomPub service document is nothing like IDL or WSDL either. Both of those documents essentially inform you of service URIs and media types, but they don’t define methods or operations. They don’t have to, because of the HTTP uniform interface. That’s important, and it’s why I disagree with Dare’s point quoted above.

Consider the mindset of the CORBA and WS-* developer. They use systems that force them to always think about all their service endpoints in terms of specialized interfaces. Given how much time I’ve spent in that world (and don’t forget, I still use CORBA too), I know for certain that the concept of the uniform interface is one of the big items that trips these developers up when they try to figure out what REST is about. It’s therefore important to keep the uniform interface as part of the conversation.

Many Thanks, Mark

January 19th, 2008  |  Published in commentary, REST  |  Bookmark on Pinboard.in

Mark Baker:

I’ve had enough. I’m not participating in any more “REST vs. SOAP” discussions. When I started on this mission to educate those who didn’t understand how the Web could help them, I figured it would be pretty straightforward; I’d explain it, they’d understand, and then we’d all skip away hand-in-hand whistling show tunes. Of course, it didn’t quite work out that way. Instead, I ended up spending on the order of $100K of my own money on travel, as well as the opportunity cost of many hundreds of otherwise billable hours, for what is working out to be essentially nothing in return. If that weren’t enough, my health has suffered the past year or so, in ways I won’t get into here, but that I’m confident are in part attributable to the despair I’ve felt over this extended period of frustration.

Mark, I’m sorry to hear about your situation, and I certainly can’t blame you for your decision. As you say, the war really has been won, and you’ve more than earned a break. I saw you take many arrows — and I mean many arrows — over the years as you patiently explained REST to the world and worked hard to keep the wrong technical things from happening in the standards committees. For whatever it’s worth, I greatly admire and applaud your strength and your perseverance, and congratulate you on your achievements.

I also want to sincerely thank you for personally bringing REST to my attention in an email exchange way back around 2000-2001. Over the years REST has helped transform and improve the way I view and develop distributed systems, so much so that it played a big part in my decision to leave a long and well-established career in middleware development about a year ago and switch to developing software for an entirely different industry. In my current position, I’m thankfully free to use REST when and where it makes sense without having to fight all the stupid battles that you’ve understandably grown weary of.

An aside: the personal toll that Mark is suffering is most unfortunate. There’s simply no room in technical discussions for the negativity and hate that causes situations like that. Yet, despite the fact that the war is indeed over, and even though most of us now try to boringly proceed with useful logical discussions, there are still a few hostile jerks out there who didn’t get the memo. For example, I recently had to completely ban one such jackass from commenting here due to his continued personal attacks and insults, not only against me but against Mark, Tim Bray, and anyone else who supports REST. (Thankfully he adds no technical insight or knowledge whatsoever to either side of the discussion, so it’s no loss.) It saddens me that the destructive voices of hate like his can sometimes drive the bright, insightful and truly useful voices like Mark’s out of a technical conversation. It’s up to all of us to continuously try to prevent such situations, whether we’re discussing REST or some other topic.

Mark, thanks again for all your efforts. If there’s any way you think I can help, don’t hesitate to let me know.