Archive for the 'ruby' Category

14
Oct
06

Testing Ruby

I spent a fair bit of time over the last two months with Ruby. I actually started studying it about six months before, but I hadn’t really got to the point of writing anything non-trivial with it. At that point, it was more “theoretical”, than real. So two months ago I started doing some more complex stuff. For example, I wrote this little distributed abstract syntax tree interpreter. It’s nothing to brag about, and it’s probably completely useless, so I won’t bother explaining it, but the point was to understand Ruby a bit better.

As I expected, there were a number of areas where Ruby was beautifully brilliant and easy to work with. There were some disappointments however. That’s not really surprising either, since Ruby hasn’t been in the limelight all that long, and as a result many of the more expensive peripheral things like tools and libraries haven’t matured yet. And of course, like any language/platform, there are going to be room for improvement. There will be tradeoffs, things the community is working on, etc.

To be fair, I should probably start by listing all the great things about Ruby, but plenty of people who know a lot more about Ruby than me have already done that, so I doubt I’d really add much through that. Let’s just accept that I do believe there are great things.

That said I’m going to start taking potshots. Well, potshots is a bit harsh, but since I’m sure someone will feel like that’s what they are, we’ll just label them as such, and avoid all confusion.

IDEs

The first disappointment was IDEs. I started with Ruby in Steel, an add-in for Visual Studio .NET. The beginning was rocky as the first installers had some issues, but eventually I got it installed (and the newer installers are smoother). But I was immediately disappointed because I thought there was some rudimentary Intellisense support. There wasn’t however. The SapphireSteel guys are still working on that feature for their developer edition, and it sounds like it will be better than what I expected could be done, but we’ll have to wait and see. Oh, and the debugger was being troublesome.

The next up was RDT for Eclipse. Despite also advertising code completion, I found no signs of it. And once again the debugger was very troublesome.

I was about to give up on the idea of a debugger at all, when I found ArachnoRuby. It didn’t have or advertise Intellisense, but it did have a working debugger. Actually, it wasn’t just working, but designed for dynamic languages. For example, it allows you to attach a IRB console to a running program (after a breakpoint has occurred), and make modifications just like you had run your whole program in IRB.

Beyond that, another great thing was the Ruby Class Browser, which was far more useful than the standard documentation, or RDoc for finding classes and methods. Still however, there was no Intellisense, which I think would have been better because I got annoyed at having to swap windows to look something up.

So, it’s not all doom and gloom, but clearly, Ruby IDEs have a lot of room for improvement. And some features, like refactoring and Intellisense are much more difficult than they would be in a non-dynamic language. That’s one of those little tradeoffs. The smart dedicated Ruby people will probably just shrug their shoulders at those issues and move on about their work, accepting it for what it is, a tradeoff. The really brilliant and really dedicated Ruby people will find a way around 90% or 95% of the problem, although that will take time.

The idealists will probably respond that those features aren’t necessary, or are actually, despite common wisdom, are evil. Something along the lines of “Code Completion makes you stupid”, or “My Dual Core 3Ghz processor is too slow to run anything more complex than a text editor.” Oops, didn’t mean to start ranting like that… Moving on.

Unit Testing

Unit testing in Ruby is actually very good, despite the lack of any IDE support for it. Being dynamic is the biggest contributor to this. The array and hash primitives are also great for setting up test cases. But mostly it’s the dynamic nature of Ruby. Tests get virtually no benefits from static types.

Except the problem is, I found myself writing tests that would have been covered by a static type system. It’s not that the test cases would have been any easier to write with a static language, but there were plenty of them I wouldn’t have had to write at all. And even then, there were even more tests I didn’t write that would have been provided by default through a static language. And beyond this, in order to implement some tests, I had to put the equivalent of static typing into my code. It just ended up being a lot more verbose then simply declaring the type would have been.

For example, take this initializer:

def initialize(*exprList)
@exprList = exprList
@exprList = *@exprList if @exprList.is_a?(Array)
raise "Values must be interpretable" unless @exprList.all? {|value|
value.respond_to?(:interpret)}
end

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

(I know I probably screwed up a dozen things, so it’s worthless to nitpick my code quality. I’m an admitted Ruby Nuby) That last line is really the crux of the issue here. I expect some will feel it’s simply not necessary, but the truth is, it helped solve more than one bug when I combined it with unit testing. But that line is really just a really verbose form of List<Interpretable>.

So what we have here, is just another tradeoff right? Dynamic languages make unit tests much easier to write, but require more of them. But what if we started to treat static type information as a compact, concise and expressive form of unit tests, rather than as a straitjacket. Maybe if we did this, by making static languages that support dynamic capabilities, we could make unit testing easy, and avoid rolling our own static typing. Just an idea.

Summary

There is more to all of this then simply potshots at Ruby. The real point, is that we all have a lot to learn from each other. Here I’ve shown how the Ruby tool developers are learning from the Java/.NET tool developers, though obviously they have their own unique challenges AND opportunities as well. But likely, all of the hard work put into Ruby Intellisense will have some real value to static language tool designers as well, especially those working with type inference.

I’ve also shown how static language unit test tool developers can learn from Ruby unit testing. I’m going to assume there is probably a way to make the Ruby side of things more palatable as well, though I don’t know what it is yet. When you get criticism, look at it as an opportunity to grow, not an attack, even if it actually is an attack (this wasn’t).

07
Jul
06

The JavaScript VM?

There’s an interesting trend going on these days, where many languages are adding features to compile their code into Javascript. For example Ruby, Java, C# are all doing it. Supposedly, the original idea came from a company called Morfik, but I know very little about that.

What I find interesting about this is that JavaScript is essentially being abandoned as a language and converted into an IL. Not having much respect for JavaScript myself, it feels very much like a first class hack, and I wonder how long it will live on. It’s easy to see why it is happening, JavaScript is already everywhere, so why not repurpose it?

But thinking longer term, clearly there must be better alternatives (CLR and JVM) than JavaScript.

12
May
06

Ruby.. BOO! CLR LISP JavaSchools.. and a total lack of focus

I finished the Ruby book I was reading online, but unfortunately, it ended before the continuations, so it looks like I will need to find another resource to finish up. I suppose I could start writing a program, but I would rather keep digging. If anyone has a good recommendation for an advanced Ruby resource (and by advanced I mean high end features, not written in gibberish), send it on.

So instead of following up on Ruby, I instead started looking at Boo. Someone suggested it and I have to admit, I am impressed. I do not care for some of the syntax, but I really like the type inference system, which goes a bit farther than var in C# 3.0. I do however wonder if making inference the default, instead of explicit through var is the right thing to do, but I’m not really sure one way or the other yet.

As far as syntax goes, one thing I do not understand is def. Why is that there? However, ignoring some oddities like this, it is a beautiful achievement. Beyond the language itself, the site is really interesting because of how well it demonstrates the not well know cross platform capabilities of .NET. See.

I knew about Mono before, but I had never heard of GTK# before. Boo has an Eclipse plug-in as well. Oddly, there is no VS.NET plug-in for boo. The whole project is an interesting mash-up of many different technologies that people generally assume do not fit together.

Boo also has some cool language features.

On a related note, I also read a set of articles that I found interesting. Sriram seems to be in the same mode as I am, trying to soak up the juice from languages like LISP. I would totally agree that I have failed to fall in love with LISP, or even Ruby. There are some cool things there, but I am driven away by others. LISP is far worse in this way. Despite that, I am still very happy that I spent the time on it. I may never write a single line of LISP code, but that was not the point was it?

Sriram, pointed to an article on teaching Computer Science. While Joel may be right that his tried and true tests do not work as well on someone who has not studied LISP or something similar, I wonder if he is not making the same mistake he criticizes others for. That is that he is using “grep” to evaluate resumes. He is looking for LISP experience however instead of Java experience. What he should really be looking for is a way to test his candidates that does not rely upon prior knowledge that is unrelated to the job.

Joel compares the ability of developers to grapple with recursion and pointers with the ability to create architecture, because they require a similar skill of breaking down problems to properly solve. However, why not use a test that only requires that skill, but only requires commonplace knowledge. Even better might be to actually test their ability to create architecture, but I suppose Joel feels that either this would take too long, or that he does not expect his candidates to come to the job with that knowledge.

However, if what you are looking for is problem solving skills and architecture knowledge, why look for LISP knowledge, or pointer knowledge, etc. which may never come up for the average developer?

11
May
06

Static/Dynamic? Why not both?

So.. it’s been quiet here. I decided, a bit more than a week ago to learn LISP. I have been hearing things about LISP every so often, how great it was, so I got this feeling that I should give it a look. Somehow, in the middle of this project I decided to study Ruby as well. To add to all this I’m trying to compare both of them to C# 3.0.

It’s been an interesting journey (which is not done yet). Both languages are of the dynamic variety, which I have a personal bent against. I see the value of dynamic typing for some situations, and it certainly made a number of interesting features of both languages easier.

For example, dynamic typing is very useful for interpreters (like IRB or REPL), and it is easier to include metaprogramming, or LISP style macro capabilities in a dynamic language.

On the other hand, static typing has immense benefits too. The obvious one is the ability of the compiler to protect you from yourself. Most dynamic typing advocates tend to dismiss this as the argument of a “newbie”, but the truth is that it is not as simple even as protecting you from yourself, but perhaps protecting you from your neighbor, etc.

It is naive to assume that experienced developers don’t make mistakes. In fact, the most experienced developers probably make more mistakes than average because unless they are lazy they are working on harder problems.

But.. I am starting to rehash a common debate, which is totally unnecessary. It is unnecessary because I don’t believe that dynamic and static typing are wholly incompatible. Maybe if the two camps would bury the hatchet we’d see better alternatives.

Dynamic languages for example, can easily include psuedo-static typing, and quite a few do to a very limited degree. But why is it so limited? Take LISP as an example. LISP includes support for declaration of types, but it is very rarely used, except for performance gains. I could be wrong here, but I think the main reason is LISP implementations never included type checking. Most dynamic languages actually tend to eschew the concept of compilation entirely.

I think it is great to be able to quickly test your code in an interpreter (or JIT as is the general case), but why aren’t there systems to check your code when preparing a release? Actually, preparing a release is too late. Really, it should be like Visual Studio, where it is checking your code as you write it, but I see how this might be a bit difficult, so I would settle for having basic code validation tools.

However, good validation tools require support from within the language, and from the developers. It is obvious that with runtime metaprogramming you can break things a validation tool would think was ok, or vice versa, so languages would need a way for you to suppress validation on specific sections, or the false positives could be a big problem.

On the static side, I actually see the trend developing already. C# 3.0 (and C# 2.0) are excellent examples of how static languages are working to bring features traditionally associated with dynamic languages to the static world. C# 3.0 also introduces some pseudo-dynamic capabilities. “var” is an example of this. Technically everything is still static, but it does not always feel that way, and when combined with anonymous types, methods, and lambdas it does more than just feel different.

There is still plenty left to do here though. I think it might be very interesting to introduce an almost totally dynamic option to C#. I was thinking of the ability to take a try/catch block and append mode options to the try. For example:

try runtime
{

x.IHopeThisMethodExists();
}
catch (RuntimeCompileException e)

Of course code like above would be treated with about the same level of regard as unsafe {} but it could be very useful for testing some changes quickly, or for building mini-languages into applications.

Duck typing is another option, approachable from either side. Dynamic languages can do some duck-type code validation, and static languages can use it as well with the proper restrictions. I static language should have little difficulty in generating “anonymous” interfaces at compile time if that is how the developer designs things. You could just as well reuse the try runtime metaphor as try ducktime… or maybe something a little less silly.

Anyhow, that is about my limit for the night.




Pages

Top Clicks

  • None

a


Follow

Get every new post delivered to your Inbox.