Posted by Skrud at Saturday, December 10th 2005 at 8:20pm
It seems there’s been some debating in the Software Engineering world about whether or not a Minimal Interface is perferable to a Humane Interface. It looks like it all started with Martin Fowler’s discussion of Humane Interfaces, comparing Java’s List interface with Ruby’s Array class. Java’s List interface has a mere 25 methods, whereas Ruby’s Array (which is really a List) has a whopping 78 methods. Many of these are so-called “convenience” methods that do simple things that may be often used:
For example, to receive the first and last elements in an Array you can simply do:
This is an example of a Humane Interface, where there are a host of methods that you may need to use, but shouldn’t need to reimplement every time.
Compared with Java, an example of a Minimal Interface:
aList.get(0);
aList.get( aList.size() - 1 );
(Arguably, Java’s LinkedList class has a getFirst() and getLast() method, both of which are inaccessible when you are using the comment List interface as a declared type… which may speak to the organisation of Java’s libraries…)
There is an interseting rebuttal by Elliotte Harold, who has written plenty of Java books. It’s no wonder where he stands. This seemed to spawn a lot of discussion, and there’s a great response to Elliotte by James Robertson on his blog. The comments are also a good read and many bring up some intresting points. I also like the comments on Cee’s Blog.
Personally I think the strongest argument in support of a Humane Interface is the fact that it’s intention revealing. That is, if you’re reading someone’s code, even if you’re not familiar with the programming language or its implementation, and see something like aList.first, you’ll probably have a pretty good idea of what it does. Now, what if you didn’t know anything about Lists are implemented using indexing and you see aList.get(0) or aList.get( aList.size() - 1 )? You might have to think about it for a bit, first.
Now that I think about it, that method call is really saying: “Give me the element at the position that is one less than your total size,” which is a really round-a-bout way of doing things. I certainly prefer the simplicity of “Give me your last element”.
I particularly liked Fowler’s comment on using length or size to get the number of elements in a list:
Another interesting consequence of ruby’s humane interface philosophy is the aliasing method names. When you want the length of a list, should you use length or size? Some libraries use one, some the other, Ruby’s Array has both, marked as aliases so that either name calls the same code. The rubyist view being that it’s easier for the library to have both than to ask the users of a library to remember which one it is.
I also agree with Jim Weirich who points out that the Humane Interface approach, even if it might mean that you’ll never use half the methods in a given API, you’ll know where to look when you _do_ need a particular method:
As a result, methods tend to migrate to the classes they belong to, rather than put in a utility method somewhere. Although I might never use assoc, if I were to look for it, I would start in the Array class, or one of its included modules.
In fact, I did need assoc recently. Guess where I found it.
I love thinking about this kind of stuff. Coincidentally, I had a Software Design final exam this morning. :D
Tags: code, geek | 13 comments
Posted by Skrud at Wednesday, November 30th 2005 at 1:03pm
Isabelle makes no sense. Isabelle isn’t a person (though I can only assume that, if she were human she’d be a female, and would still make no sense), it’s a “generic theorem proving environment”. It’s built on top of EMACS, and I’m a vi(m) man, and the two are opposites to the point of holy war. EMACS is bloated. The introductory tutorial for Isabelle is 235 pages. It’s written for mathematicians, not for programmers. All the documentation is written with LaTeX and makes extensive use of the greek alphabet which is not available to use in the syntax for the proofing language. In other words, a measure function uses the greek character lambda (λ) as an argument, however one cannot input λ as such into an emacs document. So instead the % character substitutes for λ. Why not just use the ‘%’ symbol in the documentation and save us all the trouble???!!! This goes on for many symbols. And it gets worse…
A “simple” factorial function would look something like this:
consts
factorial :: "nat => nat"
recdef measure(%n.n)
"factorial 0 = 1"
"factorial n = n * factorial(pred n)"
Which is probably wrong, the prof erased and rewrote it about 3 times, and I still have no idea how it works. By comparison, in C:
int factorial( int n ) {
return ( n <= 0 ) ? 1 : factorial( n - 1 ) * n;
}
You know something is wrong if it’s simpler to do in C.
Ah, enough ranting. I feel a little better now.
Tags: code, rants, school | 9 comments
Posted by Skrud at Sunday, October 23rd 2005 at 4:49am
I saw Ed’s post about last.fm and started checking it out … It turns out I had an AudioScrobbler account from a while ago … so I cleared out whatever data was in there and started letting it record tracks. I also wrote a little script that uses AudioScrobbler’s Web Services to read my most recently played tracks. (You can see it on the side). I actually just took the del.icio.us script that I use on the sidebar, replaced all occurences of ‘Delicious’ with ‘Scrobbler’, removed some excess functions (for tags that I’m not using with AudioScrobbler) and reworked the namespaces, so it’s not like I wrote the RSS parser from scratch … (otherwise I would’ve just used the plaintext feed from AudioScrobbler instead of the RSS one).
Tags: code, geek, metablogging, music | 2 comments
Posted by Skrud at Wednesday, October 19th 2005 at 2:23am
When it rains, it pours. Learning the Ruby Programming Language is something I’ve intended to do for a long time. My summer reading list from last year included two Ruby books… unfortunately I think I only managed to skim through the first couple of chapters of Programming Ruby. (I did manage to read some seven or eight novels that summer. Ah… recreational reading….)
I remember over the summer hearing about how Matt intended to learn Ruby. Last week, Dave asked about finding some space to host the Montreal Ruby User’s Group, which is small but itching to have it’s first meeting. This reminded me that I wanted to learn Ruby and I think I brought it up to Harley later that day. On Saturday (I think it was Saturday, but I kept owl’s hours all weekend so it might have been Sunday) Harley called me to tell me about the ridiculously hilarious Why’s (Poignant) Guide to Ruby.
This guide is incredibly funny. And I don’t mean funny in a Learning Perl kind of way, I mean funny in a chunky bacon, elf with a pet ham kind of way. Why’s (Poignant) Guide to Ruby is loaded with comics containing cartoon foxes, the afformentioned elf, Dr. Cham the Grannybomber who travels to the planet Endertromb, a movie-watching goat, a ghost girl, and the list goes on. Throughout the guide, the reader will be confronted with bizarre tales of distant travels and unusual otherworldly systems, which are used to create scenarios that need to be solved through Ruby coding. On top of that, WhyTheLuckyStiff (his blog is almost as bizarre as the guide itself), has the most interesting and unusual way of describing programming constructs and concepts to the reader, advanced in programming or not. I even found myself describing parantheses to the students in my System Software tutorial as inner tubes, and the arguments are riding along with the comma representing their legs hanging over the edge of the tube… (this is straight out of the Ruby guide). I’ve never been so attuned to learning and reading so much in so little time, and it’s never been so much fun.
One of the great things about the guide is that not only does it teach you practical Ruby very quickly, with great mnemonics to remember some details, but it also shows you how to use the Ruby tools available to you, such as irb (the interactive Ruby prompt) and the ri tool to get information from any of Ruby’s standard classes. After reading the guide you’ll not only have a good idea of how to program in Ruby but you’ll have enough pointers and resources to be able to figure out the rest on your own! (You’ll also be able to construct a StarMonkey out of a coffee mug, an apple, and car keys).
I’ve also learned that Ruby programmers are for more insane than Perl programmers could hope to be. This is proven by Hobix, a Ruby-based blogging system that calls itself “the white pantsuit of weblahhing”. One needs only to visit their website to traumatize their children and their children’s children for 10 generations to come.
After spending a day or so reading the guide (I think this was Sunday), I realized that I had an assignment due for my Information System Security class on Monday. Then I remembered that sometime on Friday, after having pulled an allnighter working on two other assignments, I accidently deleted everyting my ‘Documents’ directory on my laptop. Not only that, but I also accidently emptied the trash. What’s worse is that I have a clear memory of doing this, deleting some 4,000 useful files, and then thinking “Hrmm… that’s a lot of files”. It wasn’t until two days later though that I actually noticed what I had done. (This proves that no user interface can match my stupidity, not even Mac OS X’s). This meant that I would have to re-implement my RSA-breaking program, from scratch. I figured I would do it in Ruby. So I did. You can view my source code if you’re so inclined. It takes up a good deal less code than it’s (lost) C++ counterpart.
So far, I really love Ruby. It’s like Perl, without the mess. It’s like C++ without the mess, too. :D
Tags: code, concordia, geek, school | 3 comments
Posted by Skrud at Monday, October 17th 2005 at 5:38pm
I can just imagine everyone seeing the title of post and shaking their heads, shriveling their brows and frowning. I bet they’re thinking “Skrud, you should be writing in Java. It’s cross platform.” Well, I haven’t even begun to tell you about my nightmare yet.
It’s a complete myth that the cross-platformability of any code is dependent upon the programming language it’s written in. It drives me crazy when people tell me that Java is wonderfully cross platform. That’s just marketing. In case you don’t believe me, take a look at the platforms that Sun releases Java for: Solaris Sparc (Sun’s own platform), Intel i586, AMD64. What about Java on Alpha? Well there are builds by HP. Java on PowerPC? Apple has its own builds. So you see, Java is as portable as the VM, and Sun only releases the VM for their own Sparcs and the popular Intel platform. All the other platform builds are released by third parties. How exactly is this different from having a C compiler on different platforms? Or even just telling gcc to cross-compile. How many platforms is GCC released for? I don’t know, why don’t you count.
But this isn’t about any language being better than any other, and this also isn’t about the JVM. Again, being cross-platform means writing portable code. You can write portable code in any language. (Java included). You can also not write portable code in any language, Java included. Portable code has no platform-dependent aspects and will run smoothly with a negligible effort of porting. Portable code has a limit, and it has to be able to adapt to different platform specific properties. This means that for each target you’ll have some source code files that need to be reimplemented, changed, etc. In the case of operating systems, this is unavoidable. By nature, an operating system needs to interface with hardware. You must have processor-dependent source code for the parts that need to be processor-dependent. Take a look at the Linux kernel. A lot of the processor dependent features are handled through macros that automatically replace certain snippets of code with the processor-dependent feature that is needed. There are also different source trees for different platforms. These separate source code files are not portable, which means that your entire product can only run on as many platforms as you’ve manually configured it for. In the case of Java, you have standard implementations of awt, swing, and swt that make your life easier. Because these are environments that exist on virtually every platform that Java does.
But I’m not talking about operating systems either. What I’m talking about is Java3D. Java3D is supposed to be a development platform for 3D graphics and “Advanced Imaging” for Java. It is not cross platform. A program is certainly not cross-platform if it can only be built on Sparc, i586 or AMD64. i586 and AMD64 are both versions of the i386 platform anyway. So they’re really the same thing. If you want them to run on a different platform, you’ll need to build the libraries yourself. If the code is written portably, you should have no problems compiling the source code, linking against your own system’s libraries, and having a nice custom version that will work on your PC. Unfortunately Java3D isn’t written like that.
You know something is wrong if the build instructions look like:
- Add this to the j3d-core/build.xml file:
<condition property="isMacOSXOnPPC">
<os family="mac" arch="ppc"/>
</condition>
- Add a build target for Mac OS X, too:
<target name="setupMacOSX" if="isMacOSXOnPPC">
<property name="ostype" value="macosx"/>
<property name="platform" value="macosx-ppc"/>
</target>
- Re-implement
javax.media.j3d.J3DGraphicsConfig, javax.media.j3d.NativeScreenInfo, javax.media.j3d.NativeWSInfo to use MacDrawingSurface.
And to boot these aren’t official build instructions, I found them on a forum. There are no official build instructions for OS X. You know, there actually _is_ a sun.awt.MacDrawingSurface class that they could’ve used. There’s also an X11 implementation for OS X that they could’ve used, since the Linux version of Java3D uses X11 it shouldn’t be too difficult to port. But a better question would be: why are they not using portable windowing code to begin with? Probably for speed/performance reasons, but still - what’s the point of a Java API that only works on 2 different platforms? (And seriously, how many people use Sparcs?)
This comes as I’m trying to get more involved with the UGENE project, and while talking with Jon Benn this afternoon I was trying to get Java3D to build on my PowerBook. Since Mac OS X is one of our target platforms, if it really does prove to be infeasable to build on OS X we’ll have to move to a platform other than Java3D. He suggested OGRE 3D, which is a C++ API. Looks like the foray into Java has come to a grinding halt.
Tags: code, geek, linux, mac, tech | 5 comments