I really do spend too much time being a philosopher of programming and not enough time actually programming. On the plus side, I view this with some derision as a fault.
I realized last year or so that all the functional programming in the world wasn't going to make me adequate at OO design, and I really haven't advanced at that skill since the middle of college. I got really into Ruby in about 2003, but by 2005 I was more-or-less in the FP camp. Well, now I'm in the delightful position, thanks to doing Java professionally and Haskell amateurly, of having not advanced at OO design or FP design.
I maintain that Smalltalk is the only OO language that can really teach OO design. This is not a new opinion to the world, but fairly new to me. I see the breeze with which Smalltalk APIs seem to become clear and easy, and I have to say there's something sublime going on that I can appreciate but not yet perform. I would like to be able to perform it, though, because my attempts at designing nice OO interfaces at work are very poor. My boss does much better, although he has the benefit of having been an early adopter of OO and of Java, and he never was distracted by FP or any other development in the annals of CS, whereas I'm usually distracted.
None of this is getting me any closer to a reasonable point.
Illustrations of the Power of Smalltalk
Procedural Code in Seaside
All of Seaside is fairly impressive, but one thing that caught my attention has been the ability to port scanf/printf-type C code over to Seaside without much change in flow control. My wife is taking CSE 113 at NMT, and for fun I have been doing my own versions of her lab assignments in my weird languages like Smalltalk and Prolog. I scratched my head for a good several minutes before realizing that it would likely be fruitless to try and implement console I/O from Pharo, it would be far simpler to implement a simple Seaside web-app instead. And indeed, this kind of code:
int guess; printf("Enter a number between 1 and 100: "); scanf("%d", &guess); if (guess < generated) printf("Too low!\n"); else if (guess > generated) printf("Too high!\n"); else printf("You got it!\n");
ports quite easily to Seaside:
| guess | guess := self request: 'Enter a number between 1 and 100: '. (guess < generated) ifTrue: [ self inform: 'Too low!' ]. ifFalse: [ (guess > generated) ifTrue: [ self inform: 'Too high!' ] ifFalse: [ self inform: 'You got it!' ] ].
Apart from my inability to know the right way to do a case/switch type thing in Smalltalk, it's a fairly straight-across port, except now it's displaying form entries and data on a web page and reading from them.
Interactive Debugging Like No Other
Having a bug in your Seaside code is quite fun to debug, at least initially. If you see the traceback in the browser, you can hit "Debug" and find yourself in the Smalltalk debugger sitting on the line of code that blew up. This is like most any other debugger in other languages; you can move around in the stack, inspecting objects. Unlike other languages, you can also change the code in the debugger, hit save and hit proceed or restart, and possibly get further in running your code without having to restart the servlet or even begin a new request, necessarily.
Crazy as this sounds, it's not the limit. I ran the Magma server from a workspace and accidentally closed the workspace, losing my variable with the reference to the server controller. I ran the Process Inspector to see what threads were running. Found a bunch of Magma processes but not a reference to the server controller. I learned at that point, though, that you can actually inspect the whole stack of any running thread, anytime you want.
Next I discovered you can send
allInstances to any Smalltalk class, and it gives you an OrderedCollection of instances of that class. I inspected that and was able to inspect my way to the server controller I had instantiated, and I could click in the little message window and send it messages. This it crazy and hot, and I don't know of any other system with this kind of power, apart from Ruby with ObjectSpace, but it's not even this cool.