Organizing code is an instance of organizing knowledge. Concepts like being clear, and putting things in sections, apply to programming and philosophy both.
DRY and YAGNI aren't just programming principles. They also apply to thinking and knowledge in general. It's better to recognize a general case, then think of several cases in separate, repetitive ways. And it's better to come up with solutions for actual problems and not create a bunch of over-engineered theory that may never have a purpose.
The programming methodology of starting with the minimum thing that will work, and then making lots of little improvements to it until its awesome -- based in part on actual feedback and experience with the early versions -- is also a good general method of thinking connected to gradualist, evolutionary epistemology. It's also how, say, political change should be done: don't design a utopia and then try to implement it (like the French Revolution), instead look for smaller steps so it's possible to change course mid way once you learn more about it, so you get some immediate benefit and to reduce risk.
Programmers sometimes write articles about how evil rewrites are, and how they lead to vaporware. Nothing is ever perfect, but existing products have a lot of useful work put into them, so don't start over (you'll inevitably run into new, unforeseen problems) but instead try to improve what you have. Similarly, philosophically, there are three broad schools of thought:
1) the conservative approach where you try to prevent any changes.
2) the liberal approach where you try to improve what you have.
3) the radical approach, where you say existing ideas/knowledge/traditions are broken and worthless, and should be tossed out and recreated from scratch.
The liberal, non-revolutionary approach is the right one not just for code rewrites but also in philosophy in general (and in politics).
Consider two black boxes which take input and give output according to some unknown code inside. You try them out, and both boxes give identical output for all possible inputs. You wonder: are the boxes identical? Are they the same, for all practical intents and purposes? Must they even be similar?
Programmers, although they don't usually think about it this way, already know the answer. Code can be messy, disorganized, and unreadable, or not. Code can have helpful comments, or not. One can spend a day refactoring or deleting code, and make sure all the tests pass, so it does exactly the same thing as before, but now it's better. Some code can be reused in other projects, and some isn't set up for that. Some code has tests, and some doesn't. One box could be written in C, and another in lisp.
None of these things matter if you only treat code as a black box and just want to use it. But if you ever have to change the code, like adding new features, doing maintenance or doing bug fixes, then all these differences which don't affect the code's output are important.
I call what the code actually does its "denotation" and the other aspects its "structure", and I call this field structural epistemology. Programming is the best example of where it comes up, but it also has more philosophical relevance. One interesting question is if/how/why evolution creates good structure in genetic code (I think it does, but I'm not so clear on what selection pressure caused it). Another example is that factories have knowledge structure issues: you can have two factories both making toys, with the same daily output, but one is designed so it's easier to convert it to a car factory later.
You've put into words some stuff that I've been trying to explore and articulate for about a year now :-)
Re selection pressure. Isn't it just stuff like: genetic code with good structure can adapt more quickly? Like how good code with clear structures can have new features added more quickly than a big ball of mud.
Adapting more quickly over the course of many generations does not make you replicate more now, and therefore doesn't give you a selective advantage now. There's no selection for being better in general, only for replicating more. That's the problem.
Ah, I see.
Maybe there are some structures that make it less likely that a species would develop features that give it a selective advantage in one generation?
For example: say there's some feature that is suboptimal, and if adapted would make for a much better replicator, but the genes for it are duplicated all over the place, and they all have to match for a creature to be viable. Like maybe we need to change how cell walls work to better handle the pH of our environment, but the genes for them are duplicated all over the place, and if two neighbouring cells aren't similar enough then they won't be able to interface.
If the creature needs to adapt that feature to become a better replicator, then all the instances of the genes need to mutate in the same way, in a single child, *and* they all need to mutate in the way that produces the right adaptation.
If the genes were only in one place, then they'd only have to mutate the right adaptation once, instead of a bunch of times.
Does that work?
> Maybe there are some structures that make it less likely that a species would develop features that give it a selective advantage in one generation?
Yes. But a child doesn't just get an arbitrary structure, he gets a slight variant of what his parents had, and you can't go from, say, C to lisp in one little change. Or in other words, while a big structural change certainly can have short term valuable effects, evolution needs some kind of gradual path for improving structure which is harder to come up with (plus deprecating existing features is a much bigger hassle for evolution than for human programmers -- it's more in danger of getting stuck.)
Would the different steps on that gradual path effectively be the 'refactorings' for genetic code?
Refactoring is reorganizing code. That's part of it, but too limited. Evolution doesn't just have good code within a language, but a good language too (as far as we can tell from indirect evidence like the amount of functionality compared with the amount of bits of data the code fits into).
There's something about the language that genetic code is stored in that lends itself particularly well to refactorings that are minor *but* still give a (small) selective advantage to the offspring in one generation - is it what that 'something' is that's the mystery?
There exists similarity in "how we go about making decisions in daily life?" and "how we program decisions to take place?". One of the most significant scheme of thinking in classification (at the ground level). We try to classify objects on the basis of utility (*at least at some point of time*) and we program such utilities in the a "system" to help it make another decision (or not based on what we are trying to achieve).
> One of the most significant scheme of thinking in classification (at the ground level).
I don't understand this sentence.
You're overreaching. You are trying to say complex stuff when you should be trying to get simple stuff right and build up to complex stuff later. The result is it's the wrong complex stuff, and it's nonsense because the complexity wasn't created from layers of well-designed simplicity.