Embryology and Programming Languages

Embryology and Programming Languages

If you’ve never thought that the way molars develop in mammalian fetuses is way cool, you should read this article by PZ Mhieares at Pharyngula. It’s all about one substance in the environment of the developing jaw saying “you are going to become a bit of enamel”, and then that turns on another substance that tells neighboring cells, “cancel that: you don’t want to become enamel after all”, and stuff like that.

One fascinating thing about embryology is that the way living bodies develop is completely different from the way you’d build a house, or a credenza, or a sewing machine. It involves working in different media, with different tools, and that affects the way you do things, sometimes radically.

To me, the shift in thinking about building furniture to thinking about embryology is like learning a new programming language.


Most good hackers will tell you that you should learn a lot of different programming languages, because they all offer a different tool set, and make you think differently about programming. You can look at a piece of Perl code and see that whoever wrote it is accustomed to thinking in terms of C’s tools. For instance, a C programmer is used to thinking of strings as arrays of characters, of stepping through a string one character at a time. Perl, on the other hand, is very good at regular expressions, which C doesn’t natively support, so C programmers tend to overlook them, even though they can often accomplish the same thing faster and more easily.

Languages like C and Pascal are procedural, meaning that you tend to think in terms of verbs. For instance, if you’re writing a word processor, you might make a list of all the things you want to be able to do: open a file, print a page, underline a word, and so on. In an object-oriented language like C++, you tend to concentrate more on things, and the sorts of things you can do to them: files (which can be opened, printed, etc.), paragraphs (which can be justified, selected, deleted, etc.), words (which can be underlined, spell-checked, etc).

Then there are languages like Scheme and JavaScript, in which you can manipulate instructions as if they were variables. This allows you to do things like write a function that’ll sort a list of values, without knowing what kinds of values you’ll be dealing with, or how to tell whether one is “larger” than another, because those details will be given at run-time.

And learning about embryology is like learning a new programming language. If you’re thinking about how to build a dining room table, you might think about how to make two pieces of wood fit together: you could prepare the two pieces separately, then drill a pilot hole and screw them together; or drill two partial holes and use a dowel and glue; or use a saw and router to make a join, depending on which tools and materials you have available.

Developing embryos are not tables, and the process of building them involves quite different tools and constraints. Arms and legs aren’t built separately, then glued to the spine. And all of the cells are doing something all the time; there’s no need to finish the heart and liver before getting started on the skin: these things can happen together.

You can’t glue two pieces of wood together, then insert a dowel between them. But you can tell a group of cells in a bit of tissue to differentiate and specialize into something different from their neighbors. And since all of this stuff is going on in parallel, communication between cells is important: you don’t want hair growing out of every cell on a patch of skin, so a cell that “decides” to become a follicle will sent a suppressor signal, saying in effect, “if you’re within earshot, don’t become a follicle! I’ve got that covered for this area”.

It’s a completely different set of tools and constraints, and that affects how a given problem can best be solved. What appears difficult or complicated if you think about it one way turns out to be simple and elegant if you use a different approach. When trying to solve a problem in a new programming language, there’s often an “aha!” moment, in which you realize that instead of doing it your usual way, you can combine features of the new language in a certain way, and do in five lines of code what you were previously doing in thirty.

And even if you end up never using the new language, or building technique, or whatever, it can still give you some perspective from which to examine the strengths and weaknesses of your chosen way of doing things.