Monday, February 02, 2015

Why Smalltalk is the productivity king

I've been thinking about why I'm so much more productive in Smalltalk than any other language. The reason is because I'm curious if you could bring some of it to other languages. So, what makes Smalltalk so special?

  • Incremental compilation. There is no cognitive drift. Compilation happens at the method level when one saves the code. It's automatically linked in and can be executed. Smalltalkers enjoy programming in the debugger and changing code in a running program. The concept of having to restart an entire application is foreign to a Smalltalker. The application is always alive and running. In other languages, you code while the application is not running. Programming a live application is an amazing experience. I'm shocked that it's hard to find a language that supports it. Java running the OSGi framework is the only example I can think of. But, one still has to compile a bundle (which is larger than a method).
  • Stored application state. Smalltalkers call it the image. At any point in time, you can save the entire state of the application even with a debugger open. I've saved my image at the end of the day so that I could be at that exact moment the next morning. I've also used it to share a problem that I'm having with another developer so they can see the exact state. It takes less than a second to bring up an image. It has the current running state and compiled code. One never spends time waiting for compiles or applications to start up.
  • Self contained. All of the source code is accessible inside the image. One can change any of it at any time. Every tool is written in Smalltalk. If one doesn't like how something works, one can change it. If one wants to add a feature, one is empowered to. Since everything is open, one can even change how the language works. It's programming without constraints. The original refactoring tools were written in Smalltalk.
  • Freedom from files. Allows Smalltalk to store the code in its own database. The shackles of the file system makes compilation and version control trickier. Smalltalk can incrementally index code to make searches quick and efficient. The structure of the code is not forced to fit into the file system mold.
Now, the question one has to ask is why don't we have these features in languages that we use now? Personally, I would love to be able to keep my application running and change the code as it runs. I just want to end productivity lost to application restarts and compilations.

3 comments:

Unknown said...

Seems like you have 3 independent points here:

1. Removing the long compile/link step prior to being able to run your code. Python has this (though not generally exercised at the function level).

2. I don't know what else to call it but "debug forward", meaning that you can continue the execution of the program after finding and fixing a bug. Rather than "debug backwards" where you must go back and restart the app.

3. Saved images. This sounds something like putting my laptop to sleep, and waking it later. That's a good thing. But Android likes to keep apps running indefinitely, which annoys me. That's a bad thing.

How do you imagine that these capabilities would be used in production environments? I develop on my laptop, copy the saved image to a production server, then hot fix bugs there? Add features there? Or add them on my laptop? Then how do those new features migrate to the production server?

Larry A. Brodahl said...

You sir are talking to a member of the choir. In my 30+ years of programming, across approximately 15 languages, Smalltalk was BY FAR the most productive.

Larry A. Brodahl said...

Bruce: The way we did it where I worked, we developed on our local boxes and merged code into a repository.

Then, assuming tests passed, we created a production image using the merged code and ported the image to production. (Actually to a test cycle, but let's ignore that for now.)

Then, if problems occurred, a stack trace was created and you could either: look through the trace to debug the problem OR....pull the stack trace information onto your local box, and step into the code WITH the data that existed in core at the time.

Then, depending on the severity of the error, you'd either bypass the problem by changing the incoming data......or load the source code from the repository that matches the image, make the code change (which was tested locally first), and then create a new version of the image and put it into production and restart the cycle.

Adding features, etc. only occurs on the local boxes and after all of the automated tests pass, and the customers sign off on the results do the changes get merged into the production image.

And being in the middle of a "procedure", let's call it, and being able to change the code and/or the data and go back to the top of the "procedure" without recompiling or rerunning anything is liberating.