The following is an extract from the imminent Pragmatic GP book. I’m posting it because it’s the first place I’ve managed to tie together something that’s been bugging me for years, about the failures so many Very Smart programmers and computer scientists have experienced, over and over in some cases, when trying to build useful, interesting, robust GP systems that solve complex problems. I suspected that part of the problem was in their programming style, but I realize here that collaboration habits are really the key to success in GP. More on that later; now I’m going to go publish the rest of this project.
This Cargo-bot project will be the first of a half-dozen we will work through together, so it seems important to say a bit about what I expect.
As I said, my intention for this effort is that you learn by doing, that is by building your own GP systems, bottom-up, more or less from scratch. But it’s the nature of computer programming that it’s surprisingly difficult to communicate, except by example. There are some abstruse mathematical ways, and some hand-wavey (but over-constrained) indirections like that awful pseudocode crap, but really in the end I think the only way for you to purely learn by doing would be to write code with me — in person.
Moreover, there are a lot of interesting and important subjective aspects to successfully building a GP project, that don’t come across in code as such. Why is that there? What does this do? How did you make that jump? Indeed, the lack of those subjective aspects in the other writing on GP are what’s sparked me sitting here typing today: they’re crucial; they’re the Language of the Project.
So at least for this first project, I’ve decided to write the code myself. There is still no obligation that you use the same programming language (Ruby) that I will — in fact, I hope you won’t. I hope you’ll re-write the code in some other language I’ve never heard of, and post it on GitHub, and share it with the other folks out there as more examples of how this can be done. But whatever you do, it had better still have all the same acceptance tests I’ll be describing myself, and demonstrate (automatically!) that all those features are present in your code, and the tests pass.
Beyond the fact that it will surface some of the important subjective aspects of the project that are normally elided in descriptions of GP, there’s a second (and more important) reason I’m going through this process of writing the code in plain sight.
People don’t like being surprised. Remember what I’ve said a few times already: GP (when it works) accelerates the process of discovery, which is to say you being surprised by some unexpected result or pattern.
I’ve found that many well-trained folks, young and old, who have learned and inarguably mastered computer science and programming to the point where they can squint real hard at a problem and smash-key their way into a text editor and in a few hours produce some exotic self-contained crystalline beauty of an algorithm… well, those people often react poorly to being surprised. They are so used to being right, to intuiting what they’re going to do, and then doing just that; they hammer out the code they envision (though maybe hitting the backspace key a lot) without ever having to speak to another person or do much more than rtfm now and then.
In my experience, those people have the most trouble building and using a GP system. This is nothing to do with their coding abilities, or their understanding of system design or syntax or parsers or any of that computery stuff. It has a lot to do with them seeing the thing they build — the GP software process — make the same sort of blue-sky, intuitive, often surprising design decisions that they make. Any well-made GP system will quickly spit out “design decisions” that may or may not make sense (it’s hard to tell sometimes), but which in any case are nothing like what the programmer expected. And in my experience Very Smart programmer folks are not often equipped to deal with that.
This is a problem of communication, not code-writing. I think it may be associated with a bundle of habits Very Smart programmers develop in our culture, which tend to keep them from having to discuss what and why they are writing all the individual little incremental bits of code they write. They’re often so smart, they need not have any help visualizing an entire start-to-finish solution in their heads, or do any explicit introspection, or spell out why they have made one decision versus another. But if anybody with some different vision of an equally effective start-to-finish solution starts changing their codebase, or changes the rules or goals in mid-project, or argues with them about their basic toolkit… well, it doesn’t go well. More often than not they freak out, as a matter of my experience. Sometimes there is slamming.
This is not a criticism, but rather a diagnosis: Very Smart programmers are, in my experience, easily thrown off track by having unexpected changes made to the project they’re working on. Or by coping with unexpected or emergent behavior that arises during a project. Or by having their fundamental assumptions about a domain questioned. Or by having to integrate or adapt to an alternative design approach.
Any well-built GP system, working on any interesting project, will most definitely do all those things.
I am not a Very Smart programmer. I’ve had to stumble my way through all the coding I’ve ever done, and I have very poor visualizing-everything-start-to-finish-in-my-head skills. So in the last decade or so, programming in my not-Very-Smart way, I’ve been obliged to speak with other people a lot, and explain what it is I’m doing in each iterative decision I make, and ask them what they meant by what they were doing, and all those other things Very Smart programmers are able to do automatically without consulting other people.
Along the way, I’ve discovered that there is a set of tools for that. Communication and collaboration tools. And I’ve found that those same tools, or at least very similar ones, help to deal with this weird “collaboration” thing one needs to do with a GP system. It’s not collaboration, and it’s not communication; but it is something a lot like the mutual mental modeling we do when we speak to one another (which, you may be amused to discover, is sometimes referred to as Pragmatics).
So as I go along, in my not-Very-Smart way, I am going to be building in some of those safeguards I’ve learned, and using tools that were originally designed to foster collaboration between human beings working together on code. You, since you may be Very Smart, might not have encountered these before; in my experience many programmers who work in the University or other uncollaborative settings may have missed them. Worse, you may have encountered them (for example as practices that form part of the methodology referred to as Agile by some folks), and dismissed them as being unimportant to you in your work-life.
They form a crucial buffering interface, one that will help you avoid being surprised into failure. Do not ignore them.
I’m curious if you’re aware of Push GP. If so, I’d love a post on what you think of it.
http://faculty.hampshire.edu/lspector/push.html
As I read this post I was reminded of http://www.rachelnabors.com/2012/04/of-github-and-pull-requests-and-comics. Perhaps sites like Github end up self-selecting for Very Smart programmers; they claim to ‘welcome’ pull requests, but the whole collaboration thing is just not on their priorities.
(I’ve been growing mindful of a feeling fostered in myself to find some fiddly feedback to post here, just to get my fix of funky Obliqua f’s.)
Most of the stack-based languages I use are derived from Lee and Maarten’s work in Push. I tend to prefer them because I find string manipulation simpler than trees or graphs (as in Cartesian GP), and also because iteration and recursion make actually interesting programs far more likely.
The first two or three of the six big projects will be stack-based languages. I’ll do Cartesian GP and a Grammatical Evolution setup in another. I might skip S-expressions entirely, since I’ll also be skipping Symbolic Regression. We’ll see how interested people are as we go.