<< Previous | Home | Next >>

Crazy Sensible Smalltalk

Recently I've had the good fortune to be exposed to Blain Buxton, a long time Smalltalker. Initial exposure to Smalltalkers can be rather confusing. At first you think you understand them, after all they are speaking of an object oriented language. Then utter confusion, they are not talking about a language so much as a whole world. Stange talk of 'messages' and 'images' and crazy talk of changing objects on the fly without restarting anything. In fact, not even having the concept of an application to restart. Not saving files. Files? They don't even exist!

A whole parallel computing universe that I, having been on a C/C++/Java path, would not have been exposed to. After some digging and reading, and after a nice demonstration using Squeak, I am starting to understand things and want to be in this lively Smalltalk world. I also see how terminology has been misused. The very word 'method' is too often spoken of as something 'like a function but in an object'. Odd that the meaning could become so twisted: method, aka, process, plan, system, strategy ... algorithm! The misused phrase 'calling a method' when it really is 'executing a method'. Small and perhaps trivial things to some, but for me, my perception has changed. How nice after years of programming to have a few small ideas force a huge paradigm shift.

A while back when I used Python, the dynamic nature was very nice. And now that I am enjoying Groovy, I am enjoying crafting code more than ever. But the feeling that something is missing has always been with me. I created various hacks to auto reload code as I created it. I even started on a hack to have a magic metaclass reload objects on the fly. But hacks are hacks. Not matter what the hack is, the environment is still dead. And when debugging Groovy, it is rare when I can get away with changing a bit of code without having to restart my application. Countless hours and days lost due to restarting applications and having to get back in the flow of things.

What to do? For one learn more - Design Principles Behind Smalltalk is a very easy but thought provoking read. What else is to be done? Well, Java is now open source ... anyone for hacking 250k lines of C++ ?

Type inferred completions and more

The code completion is now approaching a level where I won't miss the Java editor too much. In fact, some of the code was implemented in Groovy. So what's new? Simple type inferred completions and category completions, including the special case of DefaultGroovyMethods.

Here is what it looks like:
A type inferred field:
Type inferred field
Type inferred locals work in a similar way.

Return types of methods are also inferred, and in this case the type trickles down into the local variable.
Inferred method returns

Where would we Groovy coders be without our DGM?
Default Groovy Methods completions

And of course, completions on the categories we so love to use.
A Java category Completing a category method

Now it's time to fix little glitches (some are visible in the images above) and to keep adding test cases as I find missing completions here and there, as well as get the docs finished. I chased my tail a little too long with odd but show stopping bugs. One involved a bug that disappeared when running in debug mode! The other, a long standing class loader issue that I finally understand (thanks blackdrag).

I am quite pleased with what is working so far, but at the same time I am beginning to fully realize how much this is just the tip of the iceberg. But it is a nice tip - code browsing should be much easier to implement now, as well as proper help popups along side the completions.

GroovyEclipse code completion

I finally have stable code completion on typed data. And finally there is something to see! It's been working for a while, but getting it stable required many more test cases for interesting fringe cases. Then again, it is not just completion, but a framework to be able to add completion into text fields, consoles, and whatever else is required. And also extension points to add custom completions for features only found in Groovy, such as categories and the default Groovy methods. The same extension points can be used to add domain specific completions such as for methods injected into Grails domain classes.

The best part however is that all extension points participate in far more than code completion. Once the type inference code is completed, APIs to retrieve type data will be usable for all sorts of analysis. It will be interesting to see what people come up with.

On to the completions. This first one shows an instance variable being completed.

Completion

Here is a typed local variable.

Completion

Here is what happens when completion is used with duck types. Good old java.lang.Object completions. Once type inference is in place, this will be a far more useful completion list.

Completion

Here is a 'isActive' method being completed as a Groovy property:

Completion

And finally, a more complex completion.

Completion

A type evaluator is used to evaluate completion expressions, so eventually the evaluator will be able to evaluate complex expressions such as [1, 2, 3].collect { it.toString() } . jo_ where the underscore is the completion location. Yes, it needs to add type to the contents of the list. No it won't be happening soon :)

I am very glad I decided to avoid any hacks which would have saved time at the expense of everything going forward. A little parser extracts completion expressions. There is little it can't extract now. The previous hacky completion implementation simply looked for '.' but of course balked at any expression that was even slightly complex. And the type evaluator, while used in completion, will be extended as it is used extensively in evaluating types in the inference engine.

And onto type inference and error recovering parsers I go ...