The Tao of Programming
mit.edu
mit.edu
"What are you doing?", asked Minsky.
"I am training a randomly wired neural net to play Tic-tac-toe", Sussman replied.
"Why is the net wired randomly?", asked Minsky.
"I do not want it to have any preconceptions of how to play", Sussman said.
Minsky then shut his eyes.
"Why do you close your eyes?" Sussman asked his teacher.
"So that the room will be empty."
At that moment, Sussman was enlightened.
Hacker Koans: http://en.wikipedia.org/wiki/Hacker_koan
A novice was trying to fix a broken Lisp machine by turning the power off and on.
Knight, seeing what the student was doing, spoke sternly: "You cannot fix a machine by just power-cycling it with no understanding of what is going wrong."
Knight turned the machine off and on.
The machine worked.
It's often not this dramatic but I see this happen all the time, when someone doesn't know the source of a problem and tries to solve it by brute force (with C, it's usually "adding and removing * and & until it works") when stopping to understand what's going wrong would have lead them to the issue directly.I understand it this way: intelligence in our activities is this kind of explicit cleverness that is usually visible and smells its freshly graduated student eager to use whatever he learnt recently. Look, I can use metabrogramming to avoid duplicating these two lines of code!
Most very annoying landmines I find in refactoring code code are just side effects of this kind of intelligence. And usually "dumb code" work faster, better, is easier to maintain, and, well, requires more (real) intelligence and experience to write.
Please note that this is a point of view from seasoned coders. From the first time php-scripter, using intelligence and moderate factorisation is obviously advised.
So, to this nice list, I'd add a
Vomit your intelligence, bro!A manager asked a programmer how long it would take him to finish the program on which he was working. "I will be finished tomorrow," the programmer promptly replied.
"I think you are being unrealistic," said the manager, "Truthfully, how long will it take?"
The programmer thought for a moment. "I have some features that I wish to add. This will take at least two weeks," he finally said.
"Even that is too much to expect," insisted the manager, "I will be satisfied if you simply tell me when the program is complete."
The programmer agreed to this.
Several years later, the manager retired. On the way to his retirement luncheon, he discovered the programmer asleep at his terminal. He had been programming all night.
> 56. Software is under a constant tension. Being symbolic it is arbitrarily perfectible; but also it is arbitrarily changeable.
It's a bit more contemporary and is still being added to. I can't figure out who the author is though. All I know is they go by the name of Qi https://github.com/QilessQi
Also, all the koans are on Github and translations can be submitted via PRs https://github.com/alessandro1997/the-codeless-code
You have a finite amount of time in a day. You can allocate it between careful study and practice of programming, or retweeting today's tech groupthink so you can stay relevant.
I disagree with this.
Programming is a means to an end, not an end in and of itself. Coding in the shade of a great tree might be all well and good, but how will you ever see the world if you stay in the shade of the greatest of trees?
"I don't know whether I am Turing dreaming that I am a machine, or a machine dreaming that I am Turing!"
"Now I do not know whether I was then a man dreaming I was a butterfly, or whether I am now a butterfly, dreaming I am a man."
...so I'm guessing that was not a real Turing quote, but possibly a reference to the Turing Test.
Thus spake the Master Programmer:
"After three days without programming, life becomes
meaningless."
Sounds like the Master Programmer has never worked at a company
that crunched you for 80 hour weeks, for weeks. 8.4
Hardware met Software on the road to Changtse. Software said:
"You are Yin and I am Yang. If we travel together, we will become
famous and earn vast sums of money." And so they set forth
together, thinking to conquer the world.
Presently, they met Firmware, who was dressed in tattered rags
and hobbled along propped on a thorny stick. Firmware said to
them: "The Tao lies beyond Yin and Yang. It is silent and still
as a pool of water. It does not seek fame; therefore, nobody
knows its presence. It does not seek fortune, for it is complete
within itself. It exists beyond space and time."
Software and Hardware, ashamed, returned to their homes.
I don't understand this one. Apple seems like the
embodiment of hardware and software earning vast sums of money. It's worked out well for them.Maybe they're saying that firmware is an important design consideration that requires careful attention.
Nor has the master programmer worked for a company populated by utter morons who leave a large minefield in every task where all one-day estimates turn into one week ones the moment you start sharpening your tools...
(that's reality in corporate land)
Too bad I'm sitting here reading HN and playing my piano for a bit between emails...
The point is, it's not a good idea to take our freedom for granted. We're kind of spoiled right now, because the job market is literally figuratively on fire. Once the job market saturates within a decade, people will hopefully realize how rare it was for us to have such freedom of choice in where we were able to choose to work.
I'd suggest instead of thinking of it like a job, think of it like it is: a business arrangement exchanging time and effort for a certain set of compensation. If you wish to avoid working with a bad arrangement on one end, find another vendor you an barter with. If you feel trapped by bills or something, that's a separate problem but still one largely set up by your mind.
Obviously lots of nuances to this exist and there are a large number of factors we don't control, but make no mistake, you do control where you work. If you want to maintain the "spoiled freedom" I would suggest you become more valuable in your trade.
HR Clerk> Why should I pay you [for a full time position] more than what you are currently making [at your current, unsustainable, part time gig].
Crpatino> Because I'd rather scrub toilets and sell potatoes by the road before giving away my skills for nothing.
HR Clerk> I am sorry, I did not intend to offend you, but you must realize this is a question every employer is going to ask...
The interview went more or less uphill from there, though I did not end up getting the position. But what I want to point out is that you are not required to just take whatever X employer is offering you. You must remember that this is a game with asymmetric information. They are trained to low-ball you every time they have a chance, expecting that you will push back and negotiate. And if you do not negotiate, they just shrug their shoulders and pocket the difference.
I am aware that it is different when you already have a job. But it is not the only way to "put food on the table", no matter how much it looks like. There are other jobs, and there are other industries. And you always have the option to create a job for yourself if all else fails.
You may need to take it as it is for some limited time while you put your ducks in line, but you don't have to do that forever.
Sounds like the Master Programmer has never worked
at a company that crunched you for 80 hour weeks, for weeks.
No, that's just a separate problem: Why are programmers non-productive? Because their time is wasted in meetings.
Why are programmers rebellious? Because the management interferes too much.
Why are the programmers resigning one by one? Because they are burnt out.
Having worked for poor management, they no longer value their jobs.To make a hard distinction between hardware and software, and thinking that all problems can be solved by using strictly one or the other, is a mistake. Master Joel wrote¹ that all abstractions are leaky, and so it is with any working system – any system needs to be a meld between hardware and software, where neither can keep its identity wholly intact. (Writers of) Firmware know this well. Therefore, the Tao cannot exist in either hardware or software, purely by themselves.
1) http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...
Sadly, there are relatively few well-known examples of this nowadays. I struggle to build such systems every day, but I think I fail most of the time :-).
For example, there was this driver that could do pattern-matching on button presses, written by an ex-colleague of mine. The way this is done by most developers is to hardcode some state machines (there's a limited set of patterns that have to be matched anyway) and populate an array of callbacks for each. This one did something rather different (hopefully, I can remember what; it's been a few years since I've seen that code).
The patterns it had to recognize were arbitrary combinations of short and long button press or hold sequence, double presses and triple presses. Instead of having the state machines hardcoded, the programmer would define a state machine by defining an array of press patterns (e.g. button_event_t events[] = {BTN_CLICK, BTN_HOLD, BTN_DBL_CLICK, BTN_SEQ_END}) and register it with the driver, which added it into a list of patterns to match against. Each pattern could also have as many callbacks to be launched as needed.
The button driver itself had absolutely no idea about all this pattern crap, all it did was receive interrupts from GPIO ports and place them in a queue. An "event" matcher would munch on that queue, interpret elementary events (like button was pressed, button was depressed, button was held etc.) and put these in another queue that was pushed to the "action" matcher. Each time there was an interaction with it, it would start a new pattern matching drill; it would walk the list of events it knew about, "add" those whose first step matched the current one to a temporarily-used list (it was only adding pointers, of course, not copying the actual event) and "remove" the first press pattern (it would actually increment an index counter so as not to start copying bytes around). If nothing happened before a certain amount of time passed, the list would be disposed of. If it did, however, the temporary list would be walked again, removing those elements whose new first step didn't match the current one, and so on until the list would be brought down to one element. The callbacks would then be scheduled to run (these were actually delayed jobs, not blocking function calls), the one-element list disposed of and so on.
This was beautifully structured in every possible way:
1. The button driver, that did the GPIO magic, only worked with GPIO interrupts.
2. Recognizing specific user presses was done by another subsystem, and
3. Recognizing specific sequences of user presses was done by another subsystem
None of these had to do anything foreign to them: the button driver (which encompassed roughly #1 and #2 with nice separation between them) only did button stuff. Matching sequences of button actions superficially sounds like "button stuff" which is why it's routinely mashed in the same soup, with horrible results, but this one wasn't.
It had the further advantage that now automatic testing of anything was blatantly trivial (background: each sequence of presses would trigger actions that could potentially take up to one hour), since events like BUTTON_PRESSED or BUTTON_HOLD didn't have to come from actual interaction, they could be pushed in there by a test routine communicating with a PC through a serial port. Extending the range of possible actions or redefining them was trivial, since all that had to be done was edit arrays. It was also trivial to allow customization of these sequences by end-users.
But this is also aesthetically pleasing: there's no conflict of abstraction between "software"and "hardware". There is one module that abstracts only what is relevantly abstracted in hardware, and produces purely software-abstractions, that are meaningful only to humans, not silicon, such as BUTTON_HOLD events (silicon only knows about signals it translates into a bit flip which we like to call an interrupt). It didn't push non-silicon stuff into software that spoke to silicon, nor did it push silicon stuff high up there where there should only be software stuff.
Oh yeah: this was on a microcontroller that had 4K of RAM, and the software also included a communication stack for some weird-ass protocol, a flash driver, a temperature sensor, energy metering, LED signaling, toggling an array of relays, driving a buzzer, a firmware upgrade mechanism, a sort of application settings manager, a clock (the kind that shows the hour) with multiple alarms and the rest of the OS, pretty much all of it written by us. This guy was a guru though. The parts written by me sucked.
Clearly never used HyperCard.
The only mention of a woman I found was a hostess (!!) in 2.1.
You'd like it to be re-written with inclusive language. It's OK to want that, I guess, but... when faced with a pre-inclusive-language text, what will you do? Accept it for what it is (old, written by people not yet aware of this issue)? Or will you reject it because of what it is not?
Perhaps the best answer is to find the author and gently suggest an inclusive re-write. (And perhaps that's what you were trying to do, but I suspect that the poster is not the author. Finding the author may unfortunately take a bit more digging.)