6 ms·
You have two questions: 1. What's the advantage? 2. How do you manage the state of the environment? The advantage is programming-as-teaching, as opposed to p
by mikelevins 8y ago
You have two questions:
1. What's the advantage?
2. How do you manage the state of the environment?
The advantage is programming-as-teaching, as opposed to programming-as-carpentry. What I mean by "programming-as-teaching" is that old-fashioned Smalltalk (and Lisp) enviroments like Pharo are designed to support a style of development where you build a program by starting up the runtime and teaching it interactively, incrementally, how to be the program you want.
(What I mean by "programming-as-carpentry" is the more widespread and better-known model in which you are essentially working to build a planned artifact from a blueprint, and your development environment is analogous to a workbench or toolchest, rather than a student.)
If you don't like programming-as-teaching, then it's not an advantage. Most people don't work that way, but I think that's mostly because they don't even know it's an option. I'm not saying that everyone would prefer programming-as-teaching, but it gets so little exposure that I think it's a safe bet that more people would like it if they knew what it was.
I prefer programming-as-teaching over the alternative. I am dramatically more productive when I can work that way. I've been one of those fabled 10X programmers, as confirmed by VCS statistics, when working with such tools. It wasn't because I'm so brilliant or because I have amazing magical powers; it's because we were working with that kind of environment, and I knew how to use it and the other programmers didn't.
So, in brief, the advantage is that if you have such an environment and can use it effectively, you can be dramatically more productive. It changes the feel of programming from "let's build this variant and see how it turns out" to "reach over and correct that student's posture." The cycle of iterations becomes very fast, so fast that sometimes the duration of a cycle is imperceptible.
How do you manage the environment? First, let me acknowledge that modifying your working environment willy nilly is indeed a problem. The solution is that you don't do that.
Instead, you start from a known good system image. Environments like Pharo and other old-fashioned Smalltalk and Lisp environments offer a feature that can save the entire state of system memory to an "image" file. If you start the environment from an image, you get an in-memory state that is an exact duplicate of the state the environment was in when saved--right down to the positions and contents and activation states of all the windows. You start the image, and you're in the environment, exactly as it was when you saved it.
The way you manage incremental state changes is that you make a reference image that contains a known good state. A common choice for a reference image is a clean, unmodified release image. Then you make any site-specific modifications and customizations and save the result as a reference image as well. Then you save a working image based on that reference image and make your changes to the working image.
This practice enables you to easily recover if you get into a bad state. It's very fast to kill a bad session and restore a reference image. For example, a Pharo 6.1 image launches in under half a second on my older iMac. Clozure Common Lisp starts from an image in a similar amount of time.
When I've done ongoing serious work using this kind of system, we kept orderly collections of reference and working images--reference images that served as checkpoints in case of trouble; working images in which we had all the stuff we were working on loaded up and ready to go.
Besides making it quick and easy to resume yesterday's work, and to recover in cases where we messed up, images also served the useful purpose of enabling us to capture precise dynamic states of work in progress. For example, if a rare bug arises, I can save a working image with the problem on the screen, and give that image to my colleagues. They can start up the image and immediately see the problem state on their screens, and use the introspective capabilities of the development system to diagnose the problem.
But I guess that's more an advantage than a how-do-you-manage-it observation.
- greggyb 8y agoThis is a really great explanation, and I appreciate you taking time to share in such depth. One question I have is on version control. I understand the value of reference images and release images and debugging images (with a rare bug front and center) and so on. Would this play well with diffing as I am familiar with it from a carpentry perspective, e.g git diff? Would you serialize and dump a set of source code from an image? Would you build the reference image from a source code project and manually handle the consistency between source files and images? I know it's a vague multi-question, but I hope you understand what I'm getting at, and I would really appreciate learning more about this style of development.
- Y_Y 8y agoExactly the same question ocurred to me as I was reading. In a lisp the is certainly possible, the environment exists as a giant sexp (possibly with some small compiled components). No idea how smalltalk works though. I've tried something like this with ipython, since you can save the session's input as a .py file. As long as you don't depend on the outside world you can recreate your image by using the bare repl as your "base image" and just load the (gittable) previous sessions input (which itself possibly loads older and older sessions).
- mikelevins 8y agoA Smalltalk system has data structures that record a comprehensive inventory of every memory object. If anything, Smalltalk makes it even easier than Lisp to keep track of all the objects in memory.
- tonyg 8y agoMost Squeak/Pharo Smalltalk development takes place these days in the context of either git itself or a git-like DVCS called Monticello. Use of git/monticello within the image directly mirrors use of git at the command-line in Unix. You use git/monticello to clone a remote repo, installing the code it contains into the live image. Because of other aspects of the Smalltalk design, this has an additional effect of being a bit like package installation - the code isn't just present, it's installed and ready to run. Unlike Unix, the lack of an explicit system-compilation step in Smalltalk means it's also ready to edit in-place, which means, if you've started some service instances, ready to edit live. It's very much like Docker or working with a Unix VM: you start from a known image, like a Docker FROM command or a Debian ISO, and install files/code/packages from there, using version control tools or not as you like.