(A small note: it's traditional to not capitalize the t in Smalltalk. Old-timers take that as a signal that text was written by a non-dev.)
thinking about the old tools they had: which were valuable, which were more trouble then they were worth?
A seasoned Smalltalker would have spent more time talking about the Debugger. I was teaching a Smalltalk class once, and this one student who was a quant from a New York financial firm just spontaneously exclaimed: "This debugger is from God!" It was very fast, responsive, and was "well integrated" with the environment. More on that...
EDIT: As I took the time to say elsewhere, there really isn't that much "integration." It's more that the environment is so minimalist that it lacks many barriers present in other environments. Just about every single instance of every object has the equivalent of a REPL, and finding a particular instance in the middle of runtime debugging typically takes just a second.
Even the "IDE" really isn't one. (And I should know, because I've written a good portion of a commercial Smalltalk browser.) Aside from the refactoring mechanisms, it's a pretty lightweight and basic browser on objects -- it just so happens they're the meta-level.
What mistakes did they make that they wish they had done differently?
A big mistake: exorbitant per-seat developer licenses, and positioning as the "secret weapon" of the Fortune 500. Another oft-cited one was the Parcplace/Digitalk merger and the ensuing conflicts. Most of the mistakes had to do with community and how the ecosystem did/didn't interact with the rest of the programming world. Technologically, there was a lot of goodness.
Even better is the interaction between the test runner and the debugger. Unit tests are orders of magnitude more useful when you can just open a debugger on a failing assertion.
Not to mention the integration between the debugger and Seaside...
I always get a few jaw drops when I fix code and the page comes up once I press "Proceed".
The thing is, that's not really "integration." That's just the Debugger doing what it usually does. There's no abstruse code supporting that. (Usually Smalltalk environment "integration" does require a few lines of pedestrian code.)
Well, Seaside does have explicit code to support the debug link. If you get an exception during rendering, the framework generates a 500 response with a "Debug" link. Clicking the link restarts the previous request, and when it hits the exception, it opens a debugger instead of generating the 500 response. If you fix the error and continue, the page is sent to the browser as usual.
Thanks for both the small note and the big suggestion. What did the debugger have that made it "well integrated"? In JavaScript, we have fairly good graphical tools in Chrome. One headache is debugging asynchronous code, and a good debugger could track not just the current call stack, but the deeper "reason" why this code is running, including timers, events, xhr callbacks, and let us jump between those levels as opposed to just the function calls.
What did the debugger have that made it "well integrated"?
It's more what the environment didn't have. Everything, including almost all of the meta-level (and by almost, I think it's just 3 Classes that are treated specially by the VM) was just an ordinary object. Even throwing an exception was just Smalltalk executing as usual. Basically, there were no barriers.
(EDIT: An example mentioned elsewhere -- the integration between the Debugger and Unit Tests. It's not rocket science. You just catch an exception and pass an object to the Debugger.)
One headache is debugging asynchronous code, and a good debugger could track not just the current call stack, but the deeper "reason" why this code is running, including timers, events, xhr callbacks, and let us jump between those levels as opposed to just the function calls.
It wasn't unusual in VisualWorks for us to have multiple call stack open at the same time. (In fact, some people would put code to evaluate in comments, which could be executed in the midst of another debug session.) Timers, events, Semaphores -- these are all just Objects, subject to the same kind of manipulation. This isn't to say there wasn't some pain around concurrency, because there was that. But a competent programmer felt confident about dealing with it, because she/he had such responsive tools and no barriers to what they could do and see.
All the usual ones. You could very well hose your image. The nice thing, though, is that you could just kill your process, restart the image, and recover all of your code changes.
You could also have a Smalltalk "Process" (or green thread) starve the other ones. Lots of Smalltalks are single-threaded. VisualWorks is too, but has tricks for calling out to DLLs with a separate thread.
Basically it boils down to the semantics of the language. Languages like Java and C# can be well supported by IDEs because the syntax is declarative. A class definition in Java isn't executable, it's just data that describes the class.
In Ruby, on the other hand, a class definition is executable. That makes meta-programming easy (eg. ActiveRecord's #has_many), but it makes tool support difficult. An IDE can't just parse the source code, it has to actually execute it find out what classes are defined.
But that's a huge can of worms! What if you wrap your class definition in "if Date.today.tuesday?" What if the script has side effects you don't want to trigger every time you open your IDE? On the other hand, once the metaprogram has executed, the program that actually executes at runtime isn't something the programmer wants to see. Imagine trying to work with a Rails app that had all the the metaprogramming flattened out of it? Tedious.
What's unique about Smalltalk is that it has both executable class definitions and an IDE. It works because the IDE only lets the programmer work with the runtime representation of the program, and not the on-disk representation. The whole ecosystem - language, libraries and tools - are designed around that paradigm.
An IDE can't just parse the source code, it has to actually execute it find out what classes are defined.
There have been a few -- I think more than 3 -- Smalltalk projects where the parser was modified so that Class definition and other code could be executed but only result in a "shadow" Class being instantiated, so that the code could be browsed before being committed to the actual image.
only lets the programmer work with the runtime representation of the program, and not the on-disk representation. The whole ecosystem - language, libraries and tools - are designed around that paradigm.
It should be possible to have it both ways with Ruby. ObjectStudio Smalltalk had declarative class files. You don't want the runtime changes to be written back to the declarative files, however. This caused lots of problems in ObjectStudio. A better approach would be to have some way of flagging the runtime change, perhaps by outputting another file, then let the user merge changes back.
From the blog post.
I'd much rather see a Smalltalk that let me create small, headless images, tens or hundreds of kilobytes in size, with just the little bits of functionality I need for a particular task. If they had good libraries for file I/O, processing text on stdin/stdout and executing other commandline programs, they'd fill the "scripting language" niche very well. If they could be created and edited by a larger IDE image, they'd have the Smalltalk tools advantages as well.
Apparently someone at Digitalk did exactly this years ago, with images as small as 45kB. I think the project was called "Firewall." This technology will never see the light of day, but it shows what is possible.
thinking about the old tools they had: which were valuable, which were more trouble then they were worth?
A seasoned Smalltalker would have spent more time talking about the Debugger. I was teaching a Smalltalk class once, and this one student who was a quant from a New York financial firm just spontaneously exclaimed: "This debugger is from God!" It was very fast, responsive, and was "well integrated" with the environment. More on that...
EDIT: As I took the time to say elsewhere, there really isn't that much "integration." It's more that the environment is so minimalist that it lacks many barriers present in other environments. Just about every single instance of every object has the equivalent of a REPL, and finding a particular instance in the middle of runtime debugging typically takes just a second.
Even the "IDE" really isn't one. (And I should know, because I've written a good portion of a commercial Smalltalk browser.) Aside from the refactoring mechanisms, it's a pretty lightweight and basic browser on objects -- it just so happens they're the meta-level.
What mistakes did they make that they wish they had done differently?
A big mistake: exorbitant per-seat developer licenses, and positioning as the "secret weapon" of the Fortune 500. Another oft-cited one was the Parcplace/Digitalk merger and the ensuing conflicts. Most of the mistakes had to do with community and how the ecosystem did/didn't interact with the rest of the programming world. Technologically, there was a lot of goodness.