tag:blogger.com,1999:blog-60604582206317874712024-02-21T03:22:44.638-06:00GobbledegunkMarkhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.comBlogger57125tag:blogger.com,1999:blog-6060458220631787471.post-87999888748865982172020-06-21T04:58:00.000-05:002020-06-21T04:58:02.848-05:00800 words on 800 wordsIt has been over a week now since I finished the series 800 Words on Acorn. It’s fair to say that it has made an impression on me. Certainly, there’s the incredibly beautiful surroundings that New Zealand is well known for – leafy waterfalls and forest cheek-by-jowl with perfect beaches – but there is more than setting to it, and more than rounded characters who actually grow and change in mostly believable ways over the course of the episodes. 800 Words is a homage to communication, to words of every kind (spoken, written, unspoken) and their ability to provoke and to heal, to bear witness to what is sacred, to grow and to explore. <br /><br />We begin, for example, with the posing of the problem: the silence of an absent partner, the riddle of a move made seemingly with little justification to a place whose ties to the family are at best tangential. It is easier to believe that what drives George is the desire to get away, to remove himself from the reminders of place and people that tie him to Laura than to believe in his stated goal of starting over. His move relocates him from large city to small town; from family to strangers; from a comfortable, modern home to a fixer-upper with a dodgy septic tank; from memories of Weld as a childhood vacation paradise to the adult reality of trying to fit in a gossipy small town dominated by a single family. <br /><br />The one thread George retains is his column. Exactly 800 words, non-negotiable – a rule, in the chaos, to live by. The column becomes a character, a public-private interlocutor, patiently listening as George probes for meaning, untangling the knot of aspiration, hurt and self-doubt inside him, and at the same time pushing that expression forward, demanding something from him when others are not in a position to do so. It communicates George to George, and through his eyes, communicates Weld to Weld, bridging George into the community in a way that his actions otherwise would not. Through it, he becomes the “real author” talking to the book club about everything except his writing, and the dignified though understandably heart-broken husband dealing with his grief without the need to collapse emotionally or throw furniture. In honest communication, George finds catharsis. The kinds of hurts that are and remain too deep to express fully nevertheless are eased one spec at a time, one wave after another, though the solace of repeated pattern. <br /><br />Moreover, what is true in the grand scheme is also true in the everyday turn of events. Communication, even done badly, even done intentionally badly, is better than no communication at all, for where there is communication, this is potential for improvement. George’s house, egregiously misrepresented by Monty, becomes an anchor point in the friendship George builds with Woody, and a safe place for people in transition. George’s misguided challenge to “the Orca,” issued out of pride, becomes a community celebration. Jan’s openness about the multiple possible fathers for her twins allows the three men to come together in a mutually supportive way when they might well have been adversaries. <br /><br />Conversely, in the world of 800 words, lack of communication is always a source of problems. The silence after George’s first date with Katie; Woody’s use of the invoice as a proxy for his jealousy over George and Tracey’s friendship; the hidden details of the plans to turn Weld into a space port; and Shay stealing her mother’s ashes (among many examples) are all signs of something broken that requires dialogue to resolve. <br /><br />From this point of view, it was obvious from the first few episodes that George ought to end up with Katie. While Fiona is more impressive and driven, Tracey is more witty and adventurous, and Hannah is more fun-loving and free-spirited, Katie is the most willing to engage at a deep level, naturally empathetic, self-expressive, creative and nurturing. Nonetheless, all four women as well as Woody, Big Mac, George’s children, and others contribute something important to George’s progression, the sum of their collective influences pushing George in the different directions of discomfort he needs to go, and supporting him when he falters. <br /><br />This last point is, perhaps, why I will miss this series the most: communication is best in community. As 800 Words progresses, George’s column becomes less important as an emotional reflection as its role is transferred to the friends around him. What begins in estrangement, even from his own children, ends in a chorus. The triumph of 800 Words is not the existentialist portrait of a lone individual coming to know himself, but rather a man finding self-knowledge and recovery through belonging, integrated and woven into the self-knowledge of others. In a time of so much isolation, this is a hopeful truth. <br />Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-77798814998459116602015-07-20T17:03:00.002-05:002015-07-20T17:03:47.164-05:00Bash and eternal sleepI was trying to write a script to run a couple of background processes then wait for an interrupt signal from the keyboard. There's a nice way to do this with waits, but an even shorter way (if you have GNU -- i.e. almost all Linux machines) is:<br />
<br />
function shutdown() {<br />
# do stuff<br />
}<br />
<br />
trap shutdown INT<br />
sleep infMarkhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-76314878127256650482013-11-27T01:03:00.001-06:002013-11-27T01:03:46.215-06:00Stoic Week Day 2: Radical ModerationIt was inevitable that self-discipline should come up, I suppose. But the Stoic twist on this is different than I expected, though consistent with the idea that only character matters. The materials for today had this lovely description of Cato:<br />
<blockquote class="tr_bq">
This was the character and this the unswerving creed<br />of austere Cato: to observe moderation, to hold to the goal,<br />to follow nature, to devote his life to his country,<br />to believe that he was born not for himself but for all the world.</blockquote>
This idea of unswervingly observing moderation appeals to me -- not the ascetic path of radical self-denial, but rather something like a combination of the idea of balance in all things that I associate with the Greek, with tenacity and strength of purpose. I admire this way of thinking, the prudence of counting the cost before beginning, the steely eye that wants to know the truth of what is before contemplating what might be. This is a mindset very compatible with engineering, where there is little choice but to follow nature, since nature assuredly will not follow you. It brings to mind words like "solid," "dependable," "salt of the earth."<br />
<br />
I wonder, though, about the other aspects of life, about inspiration, surprise and wonder. I wonder if there is Stoic art, and if so, what it is like. Yesterday, I read about one Stoic who started each day by rising at dawn and meditating while staring at the sun beginning to rise into the starry sky. At the time I thought of this along the lines of Kant's concept of the sublime: something quietly vast, and awe-inspiring beyond our ability to take in. But I wonder whether that is correct. It could also be that the Stoic wishes to begin the day this way because it puts the self into practical perspective, pushing the hopefulness of waking back into an everyday frame. Inspiration and sublimity become problems, since their tendency is not to hold to the goal, but to transcend it; not to follow nature, but to rise above it.<br />
<br />
In this connection, I thought about Luther's comment about pagans trembling at the rustling of a leaf, because the supernatural is so intertwined with the natural that one can never be sure when wind is wind, and when it is the harbinger of divine wrath. [Oddly, when I Googled the phrase, I found a mixture of conservative Christian sites quoting Luther with approval, and pagan sites talking about the loveliness of rustling leaves!] What I fear from the Stoics is the same thing I fear from the modern scientific reductionists, namely (to reverse Arthur C. Clarke's maxim) that any sufficiently reduced form of magic is indistinguishable from technology -- from know-how and mechanism. I am just Stoic enough to believe that if this is the case, we must face it, while at the same time hoping it is not entirely true. As I type this, there is a large fluffy cat resting his head on me, and it is wonderful in a way that is hard to describe. If this is mechanism, then the wonder serves to point out that mechanism has more to it than appears at first glance.<br />
<br />
But I digress. I am trying something different with diet that might or might not lead somewhere; we shall see. For that purpose, holding to the plan certainly beats the faddishness of the latest weight-loss schemeMarkhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-88342745596503822912013-11-26T00:15:00.000-06:002013-11-26T00:15:23.428-06:00Living like a StoicToday begins "Stoic Week 2013" (material <a href="http://blogs.exeter.ac.uk/stoicismtoday/stoic-week-2013/">here</a>). It's an interesting idea to try out thinking about life from another paradigm. But, actually, looking at what the Stoics believed, I see a lot of points of contact with my own beliefs. The materials present 3 central ideas of Stoicism.<br />
<br />
<ul>
<li>The idea that value, or the "good life" lies within the self, and is defined by character.</li>
<li>The importance of recognizing what we do and don't have control over -- essentially we control only ourselves, and not even all of that. The most important thing we can control are our judgments. Feelings like anger or sadness result from the perspective we adopt, and that perspective can be altered.</li>
<li>The understanding of Nature (and society) as an interconnected and cooperative system, rather than a Darwinian competitive mass of individuals struggling individually for existence.</li>
</ul>
<div>
The Stoic prescription is a little improvement every day, guided by reflection on the day's events in the evening, and the formation of improvements in the morning. The meditative aspects remind me very much of what we called "devotions" when I was an Evangelical Christian. It's interesting to find another tradition of the same vintage as Christianity that contains this reflective aspect. I'm not sure about daily improvement -- it's sounds good, but my last experience of this is that it becomes exhausting and leads to frustration.</div>
<div>
<br /></div>
<div>
Today's meditation focused on what we can control, and trying to be aware of feelings and desires and from whence they originate. Today, being just an ordinary sort of work day, it's not as though I have big dramatic examples.</div>
<div>
<ul>
<li>I realize the desire to work on fun, easy stuff first rather than more difficult, longer-term tasks. This is in part a judgment about "low-hanging fruit," partly about wanting to complete a task before I start another one, and partly just doing what I like. So it's not all one way, but perhaps partly this is the kind of thing the Stoics might classify as "wrong desires"</li>
<li>I was annoyed with my wife for interrupting me during work. This is the kind of thing the Stoics would say is pointless, since the annoyance comes from outside myself, and I can't change it.</li>
</ul>
<div>
The question is whether I can really not be annoyed by interruptions. I think this is somewhat possible. I am not annoyed when work colleagues interrupt me to ask questions, for example, so the annoyance is contextual, rather than about the act of being interrupted. I also think that I am more impatient than I used to be, and there is no reason to believe that I could not be so again. In a way, this is a good test case, because interruptions are bound to happen, and my schedule is such that they will often be at inconvenient times.</div>
</div>
<div>
<br /></div>
<div>
Thinking more about the actual event, the annoyance had as much to do with frustration at not being able to solve a coding problem -- a background level of annoyance, leaving me more prone to reacting to small stimuli. The background annoyance is not all bad. Sometimes, it gives me an edge that keeps me alert and focused on the problem. The feeling of being sharply focused and on the cusp of discovering a solution makes interruptions all the more annoying. </div>
<div>
<br /></div>
<div>
As a practical matter, I don't think I would want to lose this drive. From a Stoic point of view, I don't know how to classify it. What is it that makes the Stoic try to make each better than the last? Surely it is some kind of drive, some form of energy derived from the sense of accomplishment in improving the self; the Stoic way is not the Buddhist way of detachment from the illusion of personhood. If so, then Stoicism is about channeling that energy where it matters. So does solving these coding problems matter for the development of my "rational character"? And if not, or if there is only a weak correlation, to what else should the energy be directed?</div>
Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-40546407932110226952012-01-29T18:34:00.001-06:002016-10-28T11:17:36.749-05:00Unit test only?How far can unit tests take you? There's a very interesting presentation here: http://www.infoq.com/presentations/integration-tests-scam. I've been of the opinion that you can't get around doing higher-level tests, however this is somewhat based on the way I've learned software development. The typical setup I've worked in is hierarchical. At the bottom you have unit tests, usually specific to a single object. Then you have unit integration tests, usually specific to a small set of closely related objects providing a significant chunk of capability. Above that, there's application-level tests, which verify that the capabilities integrate nicely. Above that, there's system level tests of various types, which ensure that all system requirements are met. Above that are systems integration tests, testing communications between systems.<br />
<br />
In principle, though, at any given point in time an interface/communication/message consists of two objects -- a sender and a receiver. If the system is highly modular, these objects will likely be small and fairly simple. Certainly in a system of any size there will be differences in level of abstraction, but the basic idea of sender and receiver is fundamental. If this is granted, then in principle it ought to be provable that if all possible inputs and outputs to objects are known, then unit testing is sufficient.<br />
<br />
I have two questions regarding this position. The first has to do with emergent behavior. The second is about the feasibility of determining the complete mapping between inputs and outputs. It may be that the two questions are connected, and are really two sides of the same coin, but let start with emergent behavior. My question here is not clear yet; it's more of an uneasiness. Consider the firing of neurons in a neural network simulating a brain, say, or perhaps some much simpler neural network but large enough to be non-trivial, so that the behavior of the system relies on complex interactions between the neurons. Each neuron has a set of inputs and a set of outputs. Each neuron is, in itself, simple. Complex behavior arises not from individual neurons, but from patterns of neuron firing. Now let us suppose that we wanted to test that our network is working properly using the unit test method. Testing each neuron is simple enough. Take a neuron. Construct a set of input values. Test that the outputs follow the neuron activation function. Easy!<br />
<br />
However, there is a big gap between what these unit tests tell us about the system, and what the user or higher-level programmer wants to know about the system. True, the neurons may be coded perfectly, but what we care about is at a level that is difficult to relate to the unit tests. I am not talking here about the difference between user tests and programmer tests. A programmer looking at this network from a higher level has the same issue -- what do the unit tests say about the overall network behavior? Or, put another way, where does the confidence come from that the system works correctly? Tests at the neuron level are not sufficient to determine this.<br />
<br />
I believe a similar kind of problem is envisioned by one of the commentators to the video who noted that a Mars Rover failed to land correctly because the parachute system deployed with a jerk that the (separately tested) detachment system interpreted as a landing. In principle, this problem could be caught if the characteristic for each system are known and the specs are consistent -- the sensor inputs from the parachute deployment need to be well-characterized through parachute testing, and those characteristics can then be fed to the detachment system independently. If the sensor readings for a landing are very similar to those generated by a parachute jerk, then there is an engineering problem to solve.<br />
<br />
In practice, however, though it might be straightforward to test each sensor, this may not determine the overall behavior of the system. System complexity is especially likely when interacting with hardware with many design parameters, working in unpredictable environments. A parachute detachment might be triggered by the combined results from a hundred different sensors, with the value from each sensor variable according to wind, temperature, deterioration due to aging and other factors changing over time. What is needed is to know the overall system behavior, given the component behaviors. Effectively, what needs to be tested is not the design of each component, but the system design model. If the design is wrong -- if the detachment system detaches the parachute early because of a flaw -- then it could still be the case that each individual sensor is working correctly.<br />
<br />
The question is: is unit testing sufficient to catch a system-level design flaw? This in part depends on whether "units" are allowed to occur at different levels of abstraction. Let's suppose they can, otherwise unit tests are going to be very limited in scope. So now we have a "decision maker" object somewhere in the detachment system that periodically takes inputs from the sensors and makes a decision on whether or not to detach the parachute.<br />
<br />
Off the bat, it seems to me that a unit test for the decision maker object is really an integration test by another name. Granted, there may be time advantages in being able to mock up sensors rather than interact with the hardware. But from the perspective of what the test needs to accomplish, from a design point of view, the unit test takes results from a lower level of abstraction and processes them. The coder for the unit test needs to know about the different possible input values from those sensors and what the appropriate outcomes should be. In terms of the thinking behind the test design, that is de facto integration.<br />
<br />
Is the new and cool unit-test-only method, then, really that different from the old-and-crusty unit + unit integration + ... method? I am beginning to think it is less different than I imagined at first. All that appears to be missing is a top-level integration object that, in the traditional view, would represent the system. If we envision the system as an object with a given set of inputs and outputs, and everything at a lower level substituted by mocks, then the unit test for this system object is just an end-to-end test. The same idea applies one level higher up for systems of systems.<br />
<br />
Broadening unit testing in this way, we can get a reasonable correspondence between old-style and unit-only testing. Old-style reflects likely changes in responsibility as code is looked at from a higher and higher level. Unit-only emphasizes that, regardless of the level, the same thing is happening -- there are input and outputs.<br />
<br />
This correspondence suggests to me that old-style and unit-only testing ultimately share the same strengths and weaknesses. You may conduct a traditional interface test with the parachute and detachment systems, even bring in the hardware if you like, but this does not guarantee that integration problems will be found if the set of inputs and outputs have very complex relations, and the problem rarely occurs. If it is possible to break the complex input-output relations into something simpler, that is all to the good, regardless of test style. The real gains from unit-test only style are not from demanding "unit tests only!" They come from making a system where the objects are cohesive and loosely coupled, and from having test structures such as mocks that support testing objects individually. Credit to the agile guys for coming up with methodologies that push that issue front and center where it belongs.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-24232800818273875302012-01-26T17:42:00.002-06:002012-01-26T17:44:17.461-06:00TDD does something usefulThinking through what I need to do for the plot capability I'm writing, I've had a realization. I thought I was writing a library. That might, in fact, still be the form that the plot stuff takes. But thinking about how plot might be used, there's a bifurcation. On the one hand, I might want to construct a plot instance for each cycle, do the drawing, and throw it away. On the other hand, I might want a plot instance that persists and can be updated. I realized that if I take the first route, plot doesn't have a state -- it's really a function, not an object. How did I get to this conclusion? Because writing tests forced me to construct a plot, and think about how it is used rather than just focusing on the object capabilities.<br /><br />Of course, it's impossible to tell whether I would have arrived at the same conclusion without doing TDD. But even if I had arrived there, I'm not sure it would have happened so early on.<br /><br />I've been revising my specifications for the plot capability. I'm not sure about format, but here's the current version.<br /><br />Top-level story: A user wants to add a plot to an display for a sim variable.<br />Constraints: Existing architecture provides a data source abstraction and a user interface. The user interface will need to change to use plotlib to request a plot drawing. UI will provide plot specifications including an image to draw into. Plot must construct the image using the primitive drawing functions provided by the image interface, according to the specifications.<br /><br />Specifications include:<br />1) axes<br />2) titles (are these user-specifiable?)<br />3) legends<br />4) one or more variable to plot<br />5) styles (color, line style, fonts etc.)<br />6) a data source, provided as a data river instance<br /><br />Desirable:<br />- Plots should be cross-platform<br /><br />The specifications might not all be relevant to plot. For example, perhaps font needs to be handled at a different level, leaving plot with simply a writeText(string) function, or a setFontSize(int), or even setFontSize(FontSizes) using an enum such as normal, large, small etc. I'm not going to worry about this for now. That's down the road for sure.<br /><br />I think once I get used to the "run and see the tests pass" I might actually like it. What's surprising me at the moment is that the tests are driving the design to some degree. Based on the great advice I received on the TDD board, I'm feeling free to think about design on both large and small scales, while always coming back to "OK, but what's the next test?", and "how does that spec translate into a test?" One of the advantages of not looking ahead is that I'm not having to carry everything around in my head all the time. I don't have to think "I'm going to write the Plot constructor, and it will have a Spec, and the Spec will need to have an Image, and the Image will need to be constructed, and the Spec will also have Axes which might be an concrete instantiation of some abstract PlotObject abstract class, oh, and ..." If I want to throw up some test balloons like this to help me see where I might be going, I do. But I also realize that I need to get to them via the tests, because the tests show what's necessary on a practical level to get the objects working.<br /><br />So I suppose that this means I am starting to see the tests playing a positive role in developing the design, and also in refactoring. I've done a bit of the latter already, to reflect my updated specs, and yes, it was nice being able to run the unit tests and see them pass even though at this stage they are fairly trivial. It reminds me of why I prefer using static rather than dynamic languages. Just as the C++ compiler catches all sorts of type errors that might make it though in a dynamic language, so the tests catch all sorts of logic errors that might make it through a compilation without them. Writing the unit tests is like building a customized "logic compiler" for my code.<br /><br />One big remaining question is the amount of time spent refactoring tests and the quality of the tests that I end up with. TDD advocates tend to minimize this issue, but I don't believe them. There's actually a book on this subject (xUnit Test Patterns: Refactoring Test Code) where the author writes the following:<br /><br /><span style="font-style: italic;">We started doing eXtreme Programming "by the book" using pretty much all of the practices it recommended, including pair programming, collective ownership, and test-driven development. Of course, we encountered a few challenges in figuring out how to test some aspects of the behavior of the application, but we still managed to write tests for most of the code. Then, as the project progressed, I started to notice a disturbing trend: It was taking longer and longer to implement seemingly similar tasks.</span><br style="font-style: italic;"> <span style="font-style: italic;"> </span><br style="font-style: italic;"> <span style="font-style: italic;">I explained the problem to the developers and asked them to record on each task card how much time had been spent writing new tests, modifying existing tests, and writing the production code. Very quickly, a trend emerged. While the time spent writing new tests and writing the production code seemed to be staying more or less constant, the amount of time spent modifying existing tests was increasing and the developers' estimates were going up as a result. When a developer asked me to pair on a task and we spent 90% of the time modifying existing tests to accommodate a relatively minor change.</span><br style="font-style: italic;"><br />The problem is that the people who invent methods use a lot of tacit knowledge as they develop. This is noticeable in the books they write. When I was reading Kent Beck's "Test-Driven Development by Example," there were several occasions when I thought "OK, I can see that the way he goes is a legitimate way to go, but it's not the way I would have gone. I wonder why he chose it?" It's one of those Alistair Cockburn things where we don't know what we know, and therefore can't tell whether or not everything that needs to be expressed has been expressed. even if we could express it.<br /><br />I will probably need to get that book on xUnit refactoring at some point. But elsewhere on a forum I saw someone else say something to the effect of "if the team doesn't use this book, they <span style="font-weight: bold;">will</span> get into trouble." Of course, that individual could be wrong, and certainly he is speaking in a context. But the fact remains: there's no royal road to "clean and working code" developed quickly that's easy to maintain. TDD might start with two sentences worth of rules, but the outworking of the rules is still many books worth of material and experience and that's no bad thing; it implies to me that TDD has enough to it to stand a chance of working across a range of projects.<br /><br />Enough for now. Off to write some tests.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-37032937580724615912012-01-26T17:31:00.002-06:002012-01-26T17:42:04.155-06:00TDD with QtCreatorI'm feeling better about TDD. I might even be seeing some real benefits even though there's hardly any code yet.<br /><br />To begin with, let's get some setup out of the way. One challenge was to get gtest working with QtCreator. A question I've had is whether to have one executable containing all my tests, or whether to split tests into multiple executables. This is somewhat significant, since my goal is to type CTRL-R in QtCreator and have the tests build and run -- since the TDD methodology means running tests often, it has to be easy and fast. On the other hand, it seems logical to split tests up into separate executables in case I only want to run one set (e.g. the image tests). I came up with the following solution.<br />1) Have the makefile produce multiple executables.<br />2) Have the makefile produce a run_test.sh script that runs all the executables, stopping if there's a breakage and echoing "ALL TESTS PASS" if not. This makes it easy to see when all the tests pass (hopefully the majority of the time). The rule to make the script is quite simple:<br /><br />make_exec_script: $(TESTS)<br /> echo '#!/bin/sh' > $(EXEC_SCRIPT)<br /> for i in $(TESTS); do \<br /> echo "./$$i && \\" >> $(EXEC_SCRIPT); \<br /> done<br /> echo 'echo " " && \\' >> $(EXEC_SCRIPT); \<br /> echo 'echo \* \* \* ALL TESTS PASSED \* \* \*' >> $(EXEC_SCRIPT)<br /> chmod 755 $(EXEC_SCRIPT)<br /><br />Now I just set the project up to execute the script, and I'm done. Granted, this won't work on Windows. Poor Windows. Always the oddball.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-66326801295988059322012-01-21T17:25:00.001-06:002012-01-21T17:28:54.651-06:00Shu-ha-ri and the art of learningI have waited too long to write this entry.<br />I thought that I needed time for ideas to sink in, and since I'd posted a question on the GOOS board, I thought it would be a good idea to give time for other people to answer. Then, looking over what I've written as a summary of GOOS so far, I felt I had not done a good job of summarizing the GOOS approach, but possibly lacked the background to understand what they were after. This is always an issue with getting into something new, of course: where there is a community, there is a community language and assumed background which is not always easy for the outsider to pick up on.<br /><br />To get some background, I've started reading "Agile Software Development: The Cooperative Game" (CG) by Alistair Cockburn. I've always like Cockburn's stuff -- it was his view of the human side of software development that drew me to Agile methods in the first place. I was initially going to look at a different book of his, referenced in GOOS, but I think CG is a book that I need to read. In short, it is a discussion of theories of programming, and more broadly of epistemology and communication in a programming setting.<br /><br />Cockburn begins with a familiar couple of epistemic problems. Can we know what we are experiencing? And (taking other minds for granted), can we express what we know? Cockburn answers both questions in the negative. I found his discussion interesting, but not always coherent. At some level, if it is not possible to know what we experience, it is hard to see how we can then express it to ourselves. And if we cannot express it to ourselves, and cannot express it to others, then why write a book about it? The method employed is not that of philosophical discussion, building cases from axioms, or syllogisms, for example, but rather attempting to convince through stories and reflections on what he takes from those stories.<br /><br />In his first story, for example, the author turns up at a party with a bottle of red wine, which the hostess insists is white, even though the label clearly says it is red. Later on, when he points out the mistake, the hostess again insists the wine is white and even points to the label, finding out only when she reads it out loud that it says "red." From this, Cockburn argues that we are subject to making mistakes when we think we know something that we don't know, and therefore we can end up producing requirements that contain observational errors. Fair enough. But this does not really address whether we can express what we know, or whether we can know what we experience. Rather, it argues that we may be mistaken about what we think we know, and may therefore end up conveying mistakes to others. One could argue that, on the contrary, it is precisely the fact that we can communicate and can understand our experiences that allows the hostess to realize a mistake has been made, and to laugh together with the author about it.<br /><br />I don't think that Cockburn had a epistemological treatise in mind, though, when he drafted this book. His audience is programmers, and pragmatic ones at that. He encourages those who do not like "abstract" discussion to skip the first chapter altogether. His advice, then, should probably be seen as practical rather than theoretical, even in "abstract" chapters. Looked at this way, there is a lot to like.<br /><br />Practically, our communication suffers from a lot of problems.<br />1) Our comprehension of our own experiences is limited by our ability to interpret those experiences.<br />2) Our ability to interpret is limited by many factors including language, presuppositions, eager interpretation (judging too early), and level of mastery.<br />3) In communicating with others, we need to establish a common vocabulary. This is impossible to do perfectly since understanding is layered in terms of learning and experience and everyone is unique in that regard. At best, we look for sufficiently similar experiences, which might involve the equivalent of an experience English speaker adopting a very simple vocabulary to talk to a child.<br /><br />Expanding on point 3, Cockburn brings in an idea of learning mastery built on Aikido's concept Shu-Ha-Ri. Mastery occurs in three stages. In Shu (learn), we start from the beginning and learn one particular path or technique. Trying to learn different techniques at this stage of mastery leads only to confusion. In Ha (detach), we come to see that our technique does not always work well, and that there are other techniques that work better in certain circumstances. We look for boundaries that define when to use one technique rather than another. In Ri (transcend), we come to see techniques as means to an end, not an end in themselves, and roll our own ways of getting there specific to the task, using the knowledge of the techniques without being restricted to them.<br /><br />According to Cockburn, this causes problems with a level 3 (Ri) person talks to a newbie. Ri people say things like "do what works," by which they mean something like "there's no perfect answer, but there is a multiplicity of good ones so there's no need to be prescriptive." What a newbie might hear, though, is "it doesn't matter how you code, so long as it works," or "I'm not going to help you figure out how to do it" (I'm interpolating here -- these are my words, not Cockburn's). Beginners need to know that they are getting something right.<br /><br />There's an obvious parallel to my experience with GOOS and TDD so far. I may (or may not) have written this explicitly in a previous post, but what I'm looking for is ONE way to get into TDD. Looking around the web, there are plenty of people arguing for their interpretations of TDD. That's fine, but I need context first. I recognize the danger of seeing GOOS as "the one, authentic, right method." I think I have enough experience to avoid making that mistake. But I do want to understand GOOS at a deep level, deeper than just "make a slice, code a test, code the initial behavior then fill out from there." I sense that there is more to GOOS than this -- assumptions that are more or less tacit that make GOOS a good fit for Mocks rather than Mocks simply being one technology the authors have decided to employ.<br /><br />Clearly, what I was doing in my post to the GOOS message board was an attempt to draw on common background, to phrase GOOS ideas in terminology I have seen before. This is good. The first step towards communication is trying to find what is in common, like two modems negotiating a baud rate. But unlike a modem, whose limitations are inherent in the hardware, I can work my way up from my current 300baud state to 56k, and who knows, maybe to T1 some day.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-63067655069450716892012-01-04T17:19:00.003-06:002012-01-04T17:28:08.931-06:00Starting TDDLast night and this morning, I've been doing some reading in <a href="http://http//www.growing-object-oriented-software.com/">"Growing Object Oriented Software, Guided by Tests,"</a> by Steve Freeman and Nat Pryce (hereafter referred to as GOOS). I really like it and I think it's clearing up some of the conceptual problems I had as a newbie with Test-Driven Development (TDD). I'll just list a few here, and maybe in future entries discuss how I'm going to try to do thpoints oute new plot library implementation using TDD. I'm hoping this could be a series on what I'm learning by doing TDD, or, if nothing else, a cheap way to document the design I'm working on :)<br /><br />First off, I should say that, as with most methodologies, there isn't one normative approach to doing TDD, so I'll try to say "GOOS" when what I'm discussing comes from the book, and "TDD" when it appears to be generic. In the foreword to the book, Kent Beck says, in effect, "this is a good book. It's not how I would do it, but I learned from it." At first, I thought this was a case of what you might call "dissing with faint praise." Perhaps this is because TDDers are so often dogmatic: "TDD IS GOOD FOR YOU. DO IT NOW! BECAUSE I SAID SO," or "you can't call yourself a professional if you don't use it." Then if someone raises objections, the answer is too often "well, there are some hopeless ideologues you just can't convince." Good grief! Why not just say "it made me a more effective professional," a statement that should be perfectly capable of making other professional take notice without all the acrimony? But in any case, I think it is healthy that there are different views of TDD because differences help to drive out what is meaningful. I admit it -- I'm a bit of a Hegelian at heart.<br /><br />What is missing in the discussions I've seen of TDD, and what the GOOS book tries to answer, is the rationale behind doing it. I'm not looking for "it's X% more effective." I want to understand why it is more effective -- what makes it work? This is a fundamental difference, and it's not academic either. The fact is, when you take on a new project, you have to take on an approach to that project. Saying "I'll use TDD" doesn't get you far, any more than saying "I'll use OO." TDD needs to be applied. Understanding how to apply TDD comes from understanding what TDD is good for, how it works, what sort of things in the project setup to look for. This is not so easy -- the TDD guys are right to argue that you can't give canned answers. But that's precisely why it is important to have a philosophy of TDD as well as a methodology.<br /><br />OK, so to the beginnings of clearing up my conceptual misunderstandings with TDD. In the following points, I'll list the misconception first, then discuss why it's a misconception.<br /><br /><ol><li><span style="font-style: italic;">TDD = no design up front.</span> If GOOS is right, this is nonsense. There's plenty of design up front. There are meetings with stakeholders, rough designs drawn on whiteboards, state diagrams, CRC cards, discussions of what constitutes the first "slice," discussions of what test technologies to use, and likely more. It was surprising to me, actually, to see how many times the authors of GOOS used the phrase "after discussions" or some similar idea. It's irrelevant to me whether design is documented in some fancy 150k tool or on a napkin. The point is, someone has thought about it. Someone has worked through a preliminary version of what needs to happen -- there is a direction. Perhaps anti-design-up-front TDDers prefer to call this "planning." Fine. I don't care.</li><li><span style="font-style: italic;">TDD = writing unit tests</span>. I am sure I have read TDD folks saying something to the effect that "unit tests are all you need." That's such a bizarre statement, I can't believe I would have randomly made it up. In fact, having worked on some decent-sized systems, "unit test only" is one of the biggest problems I had with TDD. How on earth can you say that's sufficient to unit test a system with a million lines of code? Rubbish! All the interesting problems are integration problems; unit testing is trivial by comparison. The same goes for working with external libraries or applications. GOOS takes the sensible perspective that tests need to exist at multiple levels, with "end-to-end" tests at the highest level, just as the conventional development methodologies I've used would indicate, though done via a different approach. Sanity! Thank goodness for that!</li><li><span style="font-style: italic;">TDD = start by writing test cases</span>. One of my problems with TDD has been where to start. In the past when I've tried TDD, I thought "OK, so I need to write tests first. What do I start with?" Then, typically, I picked an object I thought I understood (usually a low-level object) and wrote tests for it. Then, after exhaustively testing all the operators, assignment possibilities etc. I'd end up with a nice unit test which needed extensively rewritten when I tried to fit the object in with other objects. GOOS is quite clear on this point: doing this is a bad idea. More than that, it's fundamentally a misconception of what TDD is supposed to accomplish. In the GOOS way of thinking, tests are intended to drive the design of the system by pushing development from areas of knowledge into areas where knowledge is insufficient. This implies you must start from knowledge. But at the beginning where does the knowledge come from? It must come from constraints like client requirements, available technologies and preliminary design team discussions, and in the beginning, that means you have only high-level details. So "beginning" means gathering requirements and priorities, holding preliminary design discussions, and working out a plan which includes identifying a first "slice" of capability from which the application can grow. Only then can you start with the first test.</li><li><span style="font-style: italic;">TDD = bottom-up</span>. Given that the first word of their title is "growing," you might think that GOOS advocates starting at the bottom with a seed of code, and adding more bits of code until the project is done. What this fails to take into account, however, are the different levels at which TDD operates. As mentioned in point 3), GOOS begins with a slice of capability. This is at the application level, and the first test is an end-to-end test which I think is intended to test the life of the application and its interfaces, though in minimal way -- it might just instantiate an object, connect to a database, retrieve one thing, and shut down, for example. Adding capability involves driving down into the support classes by adding tests that require those supports, then making those tests pass. Thus, if I am understanding this correctly, GOOS is inherently top-down, setting up the application framework first then pushing down to lower levels.</li><li><span style="font-style: italic;">TDD = getting good code coverage</span>. Code coverage is certainly likely to be a benefit of a TDD approach, but it's not the point of TDD. Rather, TDD is a model of programming that proceeds by placing constraints on the solution space, and increasing those constraints until all requirements are satisfied. This is really the fundamental difference between a TDD approach (or in principle any test-first approach), and a conventional test-last approach. In a test-last approach, there are, of course, constraints; they are simply implicit and embedded in the code. Testing is done at the end to ensure that the implicit constraints meet the requirements. In a test-first approach, constraints are explicit, and are themselves developed as part of the design as the software grows. A potential problem with test-first is that you might spend a lot of time formally expressing and revising those constraints in test cases. A potential problem with test-last is that implicit constraints might be hard to test. And yes, I'm calling these "potential" problems. I'm in no position yet to say whether the effort to do TDD is justified, or gets better results than well-designed test-last code.<br /></li></ol>Well, that's just a beginning. Hopefully I haven't slandered the GOOS guys too much. In future entries, I'll try to elaborate more on what I'm encountering as I try out TDD.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-68009977122920364072011-06-07T16:17:00.002-05:002011-06-07T19:57:40.848-05:00Courting AbsurdityI have jury duty next week. This has led to me spending time thinking about the model of justice we use. Let's suppose you want to figure out the true circumstances of, say, a robbery. The police have a suspect and evidence. The case comes to trial. This is the big moment where guilt or innocence will be judged -- likely a life-changing decision for the accused. To make this life-changing decision, you bring in 12 individuals from the general population with no particular experience of law or robbery. You disallow them access to any external resources they could use to educate themselves. You forbid them from considering anything not mentioned during the trial. You pass them through a screening process which serves in principle to ensure impartiality, but in practice to eliminate individuals the attorneys think they won't be able to sway, that is, those intelligent enough to see through rhetorical tricks and those more likely to make decisions based on fact and logic rather than emotion. Then you start the trial.<br /><br />On one side, you have the prosecution team, representing the office of an elected official with a vested interest in looking tough on crime and successful in putting offenders away. On the other side is a defence team, paid to ensure the best outcome for their client, regardless of justice. In the middle is a judge, often also elected and tied in to party politics and thus with a vested interest in taking a certain stance towards crime. Although the jury is charged with determining guilt or innocence, they have no opportunity to ask questions of witnesses, no opportunity to witness the scene of the crime, and no opportunity to examine evidence or background information that might well be relevant but which is considered "inadmissible" based on an arcane set of rules interpreted by the judge. Every attempt is made to control the jury's view of the case.<br /><br />When the arguments have been completed, the jury retires to consider a verdict, but not before receiving instructions from the judge, who thus has the opportunity to frame the case as he/she sees fit and may even direct a guilty or not guilty verdict. Once the jury does retire, it must decide the case based on one of three standards: "on the preponderance of the evidence"; "on clear and convincing evidence"; or "beyond all reasonable doubt." All of these standards are subjective, especially when the evidence itself is only available through the lenses of prosecuting and defence attorneys. Although in principle the jury is to weigh only the evidence presented in the courtroom, in fact each jury member will bring in their own pre-formed biases and judgements, as well as subjective impressions of the defendent and the attorneys. The very principle that jurors be "peers" of the defendent reduces their ability to dispassionately decide on the evidence.<br /><br />The system is clearly not about justice or truth. The purpose of the lower courts is not, in any case, either of these. Rather, the court is there to apply the law, regardless of whether that law is just, or whether the determinations made through the court are true.<br /><br />Jury systems differ significantly from country to country, with some countries not having such a system at all, and others limiting jury trials to only the most serious offences. The history of jury trials in English law goes back a long way. In the beginning (10th century), "jurors" were not picked from among the people. Instead, they were picked from among the minor nobles, who likely had some experience with settling disputes. They did not sit passively as facts were recited by attorneys. Rather, they were responsible for going out and determining what happened themselves, then reporting back. Then, as now, they were required to swear to investigate without bias, and indeed the purpose of the jury seems to have been to stop those in power from arbitrarily getting their own way. While the composition of the jury changed over time, the idea that jurors ought to investigate the case themselves persisted until the 17th century. Even if we decide jury trials are worthwhile, then, there is no reason that we must have the system we do now.<br /><br />Historically, jury trials functioned in an environment without full-fledged police forces with trained detectives and forensic labs. Coming from this background, it makes sense that jury trials focused on witnesses. Witnesses, however, are unreliable even when not directly biased. Properly applied forensics does not have this problem. Forensic evidence does, however, need to be carefully considered both for what it does and does not show. Forensics-focused TV programs give a false impression -- their goal, after all, is an interesting plot, not accuracy. But where else in life does the average person encounter forensics? A jury taken from society in general is in no position to evaluate expert scientific testimony, especially when both sides can produce experts supporting their position. Judges are likely in no position to do this either.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com2tag:blogger.com,1999:blog-6060458220631787471.post-91328313128056441492010-05-29T15:24:00.001-05:002010-05-29T15:48:35.149-05:00RrrrrrrrrrrrrOver three months since my last post, and I'm feeling that sense of inner conflict that says "need to post to express things; can't post because there's too much to express." Since my last post, my life has felt very busy. It's not that I've been working excessively. The class I took required a lot of work, then right at the end of the semester when I was working hard on the semester project, I landed in a research project with an imminent deadline. Fortunately, the research project was enjoyable, and re-emphasized to me how good R is for statistical analysis. Somewhere around 40 lines of R was enough to:<br />1) Import a csv data matrix<br />2) Fix missing values<br />3) Cull out features that don't agree with a target feature<br />4) Iteratively perform full hierarchical cluster analyses, including calculating quality statistics and graphing results<br /><br />That's a lot for 40 lines to do! I also used R for the semester project, combining mixture models and boosting, and had a similarly good experience there. So this post has become dedicated to the praise of R in the process of writing it. R, I'm glad you exist. <br /><br />Using open source projects like R and OpenSceneGraph (which I'm currently looking at for work) has made me want to get involved in one. With what time, I don't know, but I'm going to put that as an objective. Surely there's something I could do!Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-83777822130352498952009-12-27T03:58:00.002-06:002009-12-27T04:01:49.301-06:00Me+Cougar<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhknmBCfLXWZDn1VZqX5bcQmlF5FJ8r8NbouFwJgb06SsKGewrOIXdtxsgLSTj19aX3eowZf_x0gn2-WRGab7HoT4-tIlZ1dc6MxBRmwPig_BMePXKnXRrflj83nll1tHniUJ-fWI0XiBk/s1600-h/PICT1482.JPG"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhknmBCfLXWZDn1VZqX5bcQmlF5FJ8r8NbouFwJgb06SsKGewrOIXdtxsgLSTj19aX3eowZf_x0gn2-WRGab7HoT4-tIlZ1dc6MxBRmwPig_BMePXKnXRrflj83nll1tHniUJ-fWI0XiBk/s320/PICT1482.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5419853956052051106" /></a>Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-41820270361193440642009-12-27T03:04:00.002-06:002009-12-27T03:58:08.438-06:00The next stepPerhaps it's the post-graduation euphoria talking, but I think I know the next step. It is the piece of unfinished business that has been tracking me since my 20's. I think I am finally ready to do a Ph.D. It will be part-time, while I work at my full-time job, as I did for my Master's. There is a small potential technical issue with timespans that might prevent it, but beyond that, everything seems in alignment. I have a supportive advisor, who is well aware of my situation and is very patient. I have a job with flexible hours that allows me to take classes. I have a research area that I am really interested in. And, the really crucial piece that I didn't find out until last week, all of my Master's classes will carry over, which means I need only 4 more classes, an exam and a dissertation. This last bit is really important. I just couldn't see going back and taking 36 hours worth of course work. But 12 hours is doable. That's only a year, or maybe a year-and-a-half if I take it easy. <br /><br />Still, even though it feels right, there's a good chance I might not make it. I couldn't do it in my 20's in Math. But I think my motivations now are different. Back then, I wanted to do a doctorate, then go into Academia like my dad, without really knowing what that meant. Back then, I couldn't get past the idea of GPA and getting the right answer on a test. Now, I'm less interested in that. This degree would be much more personal, much more about proving something to myself. I understand the academic mentality and system far better. Doing this thesis has taught me a lot, and so has my work experience. I am better now, I think, about battering away at a problem, at not being overwhelmed by a long-term project. Though it may take some time, I think I could make a contribution, even if only a small one. Well, we shall see.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com1tag:blogger.com,1999:blog-6060458220631787471.post-41047248458689877092009-11-26T05:34:00.003-06:002009-11-26T06:01:29.680-06:00Done and Printed<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0kU7KTHiWJdZXAa3eHNpuyEnTS3y7B8eP2qp8iXeVx-6XtQlYhksMWxBICy0QF5PHmgkSAw3tNqx6e36uwXVKnzPmctdguNlbJdbfQ-FlW7O96kx_jHIkVqQfx_hbMpfpekgGq_IAfg/s1600/adaciouspod.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 130px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX0kU7KTHiWJdZXAa3eHNpuyEnTS3y7B8eP2qp8iXeVx-6XtQlYhksMWxBICy0QF5PHmgkSAw3tNqx6e36uwXVKnzPmctdguNlbJdbfQ-FlW7O96kx_jHIkVqQfx_hbMpfpekgGq_IAfg/s320/adaciouspod.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5408381212225199858" /></a><br />Just got done printing the final copies of the thesis on nice cotton paper. Printed on Thanksgiving morning (early hours) 2009. So that's it then. No more changes. Nothing more to do than turn it in to the Dean's Office on Tuesday. And I am thankful to be done. And also thankful to have something meaningful to celebrate for my 50th post. If it were not for the pressure to produce a paper from this, I think I would feel a tremendous sense of release. As it is, were it not for a sense of obligation to my advisor, I would be quite happy to drop the paper altogether. But for right now, I'm going to forget about it, drink Apricot Ale, and eat turkey (or shrimp fajitas).Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-89241199359686927542009-11-22T00:45:00.004-06:002009-11-26T12:29:19.331-06:00Loose endsHmmm... well...<br />So the last time I posted, I had just turned in the first draft to my advisor. Now I've already defended, and made the few changes recommended by the committee, and got that back to the dean for their perusal. <br /><br />The defense was quite a shock. For my first master's, I did a project, so there was no defense. For my second, the defense was great -- like having a conversation with a couple of friends who really liked something I'd done. This defense was quite different. I had to prepare a 35 min presentation, and the idea was that I'd present then answer questions. But about 10 minutes in, one of the committee members asked about something I'd said, and from then on it rained questions and criticism: "well, have you considered this case? why not?", "the point you're making is obvious -- it's well known", "let me tell you how you should have gone about this." It was pretty rough. And I realized that from the beginning, the project I'd been assigned was a bad fit for a defense. I was simply trying to provide a known capability. They were expecting a research project. So while for me, all I had to do was test that the capability worked properly, they cared nothing at all about how robustly it was implemented, only whether it was superior to other techniques, and if so, under what circumstances. And the one piece that we added on at the end that did have a research angle they found completely uninteresting.<br /><br />Really, I shouldn't have been so surprised. I knew that they would be more interested in results and research than in all the time I had taken to understand and express the statistics behind the formulas. I don't even think they read those sections of the thesis -- the only comments I got were on the abstract and the results sections. And oddly, after all the questions and enough suggestions for things I should have done to do a dissertation on, they didn't require me to do anything beyond a few minor changes. It was a big reminder to me, though, of what the research life is like, and why I didn't do the Math Ph.D. You have to give your life to the subject. You do one thing, and do it to the exclusion of everything else. You become an expert in one little narrow area by studying everything ever written on it, and then you help push the boundary. You go out and seek grant money, fund graduate students, spend your life promoting your research, and in the end, perhaps, you have a result named after you, or a well-known paper, or a set of disciples carrying on the torch. And compared to that investment, the time I've spent writing code, testing, compiling sources, and trying to express it all in words the best way I can seems like nothing, and the results of my labors feel amateurish, which, in reality, they are. I have yet to find the thing worth devoting my life to. My passions at this point are reactive rather than creative. I wonder if perhaps I ought to be content with being a skillful workman. Ultimately I do not want to, but that too is a reactive passion, a cry against meaninglessness. Already I am looking for my next educational experience -- already the void is stirring inside me. Part of it is about boredom. Another part is just hearing someone say, "you have done measurably well." That is why it stings when I realize that all the A's on coursework and words of praise from my advisor, and even my own feeling of satisfaction amount to a mere forgery. I want to say, "you can't possibly expect me to take it *that* seriously -- I'm only doing this for fun. It's just not that important. I get just as much pleasure from laying laminate well." Then again, maybe all these thoughts right now are the post-defense emptiness talking. So either way, here I am recording, so I can look back later and think either "at one point, he really got it," or "how could he have thought that?"Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com2tag:blogger.com,1999:blog-6060458220631787471.post-8204564864767200892009-10-30T03:10:00.002-05:002009-10-30T03:35:18.659-05:00Fully Drafty<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjofNGv_ajUPbqn6WKhC6embJW8BhCQ0m3-Q2SOI-HC4Xe6_HopHB0yoSDLqmenZOJoy9sxHGNVPYNzlAFoXiSMjhIJNrkd965OebqWHgsU-WdcvH0URQ8kyrrWPufx2aWkOANjTZU7DXk/s1600-h/CIMG0064.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 239px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjofNGv_ajUPbqn6WKhC6embJW8BhCQ0m3-Q2SOI-HC4Xe6_HopHB0yoSDLqmenZOJoy9sxHGNVPYNzlAFoXiSMjhIJNrkd965OebqWHgsU-WdcvH0URQ8kyrrWPufx2aWkOANjTZU7DXk/s320/CIMG0064.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5398308744826010306" /></a><br />Just sent in my first full draft of my thesis. I'm tired, and disappointed with the latest results. But I also can't quite believe that on my hard drive (and now on Google's hard drive) there is a complete document, be it ever so humble. Alas, that it has so many shortcomings. But hoorah that it exists. I'm not nearly as proud of this as I was of my last thesis. That was real thought, real ideas, earned step by step over months of processing. This has its moments, I suppose, but I don't feel like I've broken through the barrier to being a co-creator of knowledge rather than a tweaker. I still look at those theoretical papers and wonder "how could someone be genius enough to come up with that?" There's a bone ceiling -- my skull -- and I can't get past it. Still, I'm glad to have a draft done before leaving tomorrow to come back to Houston. I expect I'll be wiped tomorrow night. Especially after the bottle or two of beer I'm planning to celebrate with :)<br /><br />I really enjoyed being in Baton Rouge today. I guess I had low expectations, but the campus and the area around it is just how I imagine a college should be. I wondered if this is how Austin used to feel before it got big (not culturally, obviously, but there's a certain feel about a big university in a state capital where it's a big deal, but there is other stuff). Baton Rouge feels the right size, somehow. I walked down the main road through the campus and took a couple of pics. I saw three good-sized buildings belonging to religious groups. The Episcopal one was a lovely chapel with its doors thrown open in welcome, but no one in sight. The Catholic one was magnificent with stained glass, and absolutely huge. Its doors were closed, but there was one person around -- inside. The Baptist one was less impressive -- neat and practical with large rectangular glass windows, through which you could see students and staff interacting. Seemed like a metaphor for something.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-25798445587323742182009-10-22T05:27:00.002-05:002009-10-22T05:56:35.991-05:00Forestalling the MorningI'm lying in bed working on the thesis, listening to a Russian Orthodox choir sing a chant called "Forestalling the Morning." It's 5:30am, dark and drizzly. But I feel good about getting stuff written up, even though I haven't made the breakthrough discovery tonight that I hoped for. And the music is fantastic, no -- that's the wrong word -- it just <span style="font-style:italic;">is</span>. I mean, it is fantastic, and beautiful, and thoughtful, but those are qualities of the music. The music itself is more than that. More even than its connotations of drafty monasteries in the frigid Russian winter, and monks gathered to forestall daybreak even earlier than 5:30, kept warm by the smell of incense and the singing of the chant. Why forestall the morning? Why not let the sun rise, and bring at least a little warmth? I don't know about them, but I do understand the desire to stretch the current moment, to stave off even good things because the now is so great for whatever reason: inspiration, productivity, enlightenment. Right now, I'm in a place of thinking "when the morning comes, there will be time to enjoy it then." <br /><br />I don't often think like that. More often it's "what's the next thing I have to get done," the next duty, the next problem, the next interruption. I wish I could keep this perspective. Focusing only on the tasks and problems is dispiriting -- there are always more problems and more tasks. One more bug fixed? Great -- now fix this one. To begin a day before the day even begins just feels good. If I could, I would probably start each day really early. Usually that never works for me, but at the moment I seem to be on a weird schedule: work, come home, make dinner, go upstairs, work on thesis for a couple of hours, then sleep for 4-5 hrs, wake up around 2 or 3 or 4 or 5, work on thesis, then sleep a bit more before work. Why not just work more on thesis in the evenings and sleep normally? I don't know. This is just what my body seems to want to do. Sleep for me is like Keith's arms. Some positions are comfortable for him, others are intensely painful, and which ones are which is unpredictable. I don't think I'll work this way forever, but for now it feels comfortable. And I get to email my advisor at weird times in the morning, so he knows I'm working hard (which I am in reality anyway).Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-42434143617990550232009-08-11T20:38:00.004-05:002009-08-11T21:33:00.569-05:00RecipeI don't usually publish recipes, but Kathryn really liked this. I was going for a soup that would have a creamy flavor without being too heavy. I cheated by basing this on a can :) Baxter's soup is made in Scotland, not too far where I grew up. But I found cans in our local HEB. This recipe is heretical since vichyssoise is supposed to be served cold. But I don't really care so long as it tastes good.<br /><br /><span style="font-weight:bold;">Salmon and Mushroom Vichyssoise</span><br /><br /><span style="font-style:italic;">1 lb of salmon, cut into 1" cubes (with or without skin -- your preference)<br />2 medium red or white potatoes cut into 1/2" cubes<br />6-8 oz of mushrooms (button, cremini or portabella), coarsely chopped<br />1 can of Baxter's Vichyssoise soup<br />14-16 oz of chicken broth (either a can or bouillon is fine; fat-free/low fat is fine)<br />1 yellow (crookneck) squash, sliced<br />1 carrot, sliced (optional) <br />1 small onion, chopped (optional)<br />1 tsp turmeric<br />1/2 tsp dill<br />1/2 tsp garlic powder<br />salt and pepper to taste</span><br /><br />Place all ingredients in a 3 qt pot. Bring to a boil then simmer, covered, for 40 mins.<br />Makes 5 large bowls.<br /><br />Serving suggestions: I served this as an entrée with Indian flatbread (roti) because it's quick to make and uses ingredients I have on hand. You could also add rice to the soup, or serve with another type of bread.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-20194212749166227152009-08-02T17:19:00.004-05:002009-08-02T18:41:36.801-05:00Fun with beams<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinIzWtlOQfDw5pT9aipX3G6ua41wtybui2fdodLHAPfQzY23dfBaTweybiZPAYQvF34KpCJEVeIE1rXe5UqlITTlJso6yPZVmHOB1_8WgOfW8oT5Kq2AGh9fvqzLqLUwMBxQs__qcKfDU/s1600-h/newbeam.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 239px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinIzWtlOQfDw5pT9aipX3G6ua41wtybui2fdodLHAPfQzY23dfBaTweybiZPAYQvF34KpCJEVeIE1rXe5UqlITTlJso6yPZVmHOB1_8WgOfW8oT5Kq2AGh9fvqzLqLUwMBxQs__qcKfDU/s320/newbeam.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5365495106043328642" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidWv_VLeovrWtRT4-1mYtGfpOU1ZoE9V4UuF5HsXMc7MSOUxMqT48B88PuLExJiFMVhsBb7wk85IiirATuzey_Pn8WQIm2dK4Fz8qdZIWIBTvoGEkmn6KduOaASqADxeO-5iVW9mrRzCk/s1600-h/rot.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 239px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidWv_VLeovrWtRT4-1mYtGfpOU1ZoE9V4UuF5HsXMc7MSOUxMqT48B88PuLExJiFMVhsBb7wk85IiirATuzey_Pn8WQIm2dK4Fz8qdZIWIBTvoGEkmn6KduOaASqADxeO-5iVW9mrRzCk/s320/rot.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5365494869232699666" /></a><br /><br /><br />It's really nice to see the house as repairs progress. First, the scary bit -- seeing the facade torn off to reveal what is underneath - good or bad. Then the approach gets hashed out. Then the bad stuff gets cut out, representing perhaps years of neglect, and replaced with good, new stuff. And hopefully the replacement process doesn't lead to other things like drywall cracks or plumbing problems. It's so like coding that it makes me wonder when I (or some other poor person) will look at code I wrote, rip off the nice facade presented to users, and declare something rotten. <br />That's related to something I haven't quite decided in high versus low process systems. Assuming that you neglect the extremes of ridiculous process (analysis paralysis, for example, or where there are process guardians like the gatekeeper of the law in Kafka), and just hacking, where does the point of maximal utility lie, where you get excellent quality of code produced efficiently? That, I assume, is what everyone is looking for, and it is probably unanswerable outside a context: <span style="font-style:italic;">this</span> project, <span style="font-style:italic;">this</span> group of people, <span style="font-style:italic;">this</span> set of time/budget constraints, <span style="font-style:italic;">this</span> set of customers and stakeholders. So, then, does it come down to gut feeling -- "I'm not comfortable with the amount of test time," "I'm constantly bogged down in useless process activities." The process world is full of frameworks, but frameworks need interpreters, customizers, domain specialists. And even then, the results are not always good, and need to be revised. The process specialists have thought of this. Their mantra is "continual process improvement." But in practice, it seems to be far too much costly and disruptive to thoroughly revise processes, and it's embarrassing to admit you've been spending on money on process that's wasted effort, so what you get is process ossification followed by patches to address new cases. And since the goal is to develop sets of processes that can be passed down to future projects, you get process megaliths carted by forklift from one project to another long after the reason for their existence has been forgotten. <br />Compared to this, hacking seems attractive. But it seems that even better would be to learn what is useful from the process folks, to take the time to understand why certain processes are good and work well. Occasionally, process saves the day, and, having experienced this myself, it doesn't take too many "day savings" to become convinced that there is value in process. But the value is only there a small percentage of the time. And the thing is that the value is often precisely where the developer doesn't want it to be -- in the stubborn anal retentiveness of process, in some ridiculous process that's useless 99.9% of the time. The process that forces you to write down exactly what is on the screen. The process that forces you to put a second and third and fourth pair of eyes on something that obviously works (well, almost). The process that makes you spend hours documenting details that no one will ever look at again. 99.9% of the time you spend doing this is wasted. BUT, there's the 0.1%. And, actually, it's not about understanding the 0.1% process, or believing in it, or thinking of it as worthwhile; only <span style="font-style:italic;">doing</span> it matters, refusing to follow your gut instinct that this is a waste of time, and following it like a slave with as good an attitude as you can muster. Is 0.1% enough to justify this?<br />If 0.1% is not acceptable, then what number would be enough -- 1% useful? 10% useful? 50% useful? And how would you know -- process metrics never seem to measure these sorts of issues; maybe they can't be measured. <br />If 0.1% is acceptable, then where does the limit lie? Should we layer on enough process that we code only one line per week, because somewhere at some point there's a 0.0000001% chance that the process will turn up something important? It seems reasonable that there is some level of process that is too much; process at any cost is not justifiable. So, then, there's a need for a metaprocess to decide which processes are worthwhile. But I don't know that I've seen a complete metaprocess of this kind, merely some broad brushstrokes in this direction (e.g. <a href="http://www.amazon.com/gp/product/0321186125/qid=1134500692/sr=2-1/ref=pd_bbs_b_2_1/104-3609087-1823927?s=books&v=glance&n=283155">here</a>) and even these are disputed (<a href="http://www.davenicolette.net/articles/when_2b_agile.html">see here</a>).Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-91675670947218930862009-06-02T22:22:00.003-05:002009-06-02T22:27:57.484-05:00Fence Day 3Busy day yesterday. Drove up to Bryan and back, then decided to do more fence. Sure enough, another post was needed, so time to get a PHD, like Keith recommended. Home Depot only had one with wooden handles. It worked pretty well up to around 30", then there wasn't enough space to really pry the dirt loose with the wooden handles bent. Got down to 32 with a fair bit of effort, then gave up. It's not perfect, but that section of fence is up :) I have to make a decision on whether to try to salvage the next post or not, but that should be the last one. If I'm careful with recycling old fence, I should have enough new fence to finish it. Otherwise, it'll be another trip to the fence place.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-36520255876154431302009-05-25T22:23:00.002-05:002009-05-25T22:36:15.049-05:00Fence Day 2Thought today was going to be my first shot at laminate flooring, but after trying out the laminate we got from Home Depot on the kitchen floor, the color just wasn't right. So, we returned it, and Kathryn found a much better alternative. So now I have two boxes coming from Amazon. Found out that laminate at Home Depot is largely exclusive to Home Depot -- they do a deal with the manufacturers. However, the manufacturers sometimes make similar laminate for regular flooring stores, just with a different line name. The alternate branding is usually a much better deal because companies are competing on price. In my case, I got the same laminate with the same warranty, but with a built-in underlay for cheaper than Home Depot was charging for their laminate with no underlay.<br /><br />Instead of laminate, I decided to do fencing. Dang, putting in a fence post is a lot of work, especially without a post hole digger. I broke a shovel doing it, but the post is up, and I was able to roll the table saw to the bottom of the garden to cut the pickets to length. That was nice! Looking forward to doing more tomorrow -- and hoping I don't have another post to do!Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com1tag:blogger.com,1999:blog-6060458220631787471.post-47513541151868913862009-04-27T12:28:00.002-05:002009-04-27T12:31:34.346-05:00Last ThingWrote a poem while not being able to sleep. Tried to capture some of that mushy overlapping thinking that goes on when I'm really tired. It's not a great poem, but I'm glad to express something. Figure I'll post it before I overthink.<br /><br /> <span style="font-style: italic;">Last Thing</span><br /><br />The last thing I want to do right now is write a poem.<br />Can't sleep no sleep under the fan's<br />too cold quilt's too hot and thick<br />blades keep turning sheet's too thin<br />five thirty-nine the Y is open<br />up on yesterday's caffeine<br />do a treadmill in my blue shorts<br />driving in a fog and hope<br />no one hits me<br />thinking carpet, laminate gotta<br />fix the kitchen focus on the fog<br />blurry tiredness baseboards<br />stainless steel sound of air<br />but indistinctly sink into a<br />sinking feeling for the crash.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com2tag:blogger.com,1999:blog-6060458220631787471.post-88741578562087110842009-04-18T15:21:00.003-05:002009-04-18T15:25:24.534-05:00Can you see me now?<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpgSkiS_boQ99DXw6ZyiIj_DoxqGXrMI8ncLBcW0y2Ukwvlw5Zkg3ONKv1saqWT46SBTkOIY1UyECrVPKSw5lNJzgmlgzBOHpLe7bsX2UsCWNb8oJOQqDKZKgZMbMAyIZD0JWNUuUoJwg/s1600-h/rain.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpgSkiS_boQ99DXw6ZyiIj_DoxqGXrMI8ncLBcW0y2Ukwvlw5Zkg3ONKv1saqWT46SBTkOIY1UyECrVPKSw5lNJzgmlgzBOHpLe7bsX2UsCWNb8oJOQqDKZKgZMbMAyIZD0JWNUuUoJwg/s320/rain.jpg" alt="" id="BLOGGER_PHOTO_ID_5326129692595024946" border="0" /></a><br />Last Saturday: beautiful weather, Brazos Bend park, looking at trees.<br />This Saturday: torrential rain, Clear Lake parking lot, looking at stranded cars.<br />I'm so glad we took the truck today -- I've done the car in high water thing before and it wasn't fun. Still, I guess it gives me time to try to fix the OpenGL rotations.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0tag:blogger.com,1999:blog-6060458220631787471.post-67201742680022864382009-04-17T19:08:00.003-05:002009-04-17T19:18:41.777-05:00MacPort Day<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBLcnvkOWP3csFXN__dlX2fu-rEPyG6ckm6cB42lsx8i8gf6mbdlTdCvma_4KMyJvGWvJ-PmRZp-40SdnI_qvAHBGzTqfJQukNuc-3vJUL7q-L9JoP_nNgzawuJY32KXLdmLcV4O7oF4/s1600-h/macday.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBLcnvkOWP3csFXN__dlX2fu-rEPyG6ckm6cB42lsx8i8gf6mbdlTdCvma_4KMyJvGWvJ-PmRZp-40SdnI_qvAHBGzTqfJQukNuc-3vJUL7q-L9JoP_nNgzawuJY32KXLdmLcV4O7oF4/s320/macday.jpg" alt="" id="BLOGGER_PHOTO_ID_5325817817280427506" border="0" /></a><br />This is what the weather looked like the day we delivered the first beta of the Mac port of the graphics software we've been working on. Yep. Overcast with thunderstorms later in the day. Real Seattle weather -- guess Microsoft has influence upstairs. Maybe if the sun were shining we'd get more frames per second :)<br />But still, this is a big achievement (mostly of Keith's)<br /><br />Before the big storm, Kim showed me all the stuff going on in her garden including the budding blueberries and the tomato plant that almost ate Texas (and still might). I was inspired, so I went to Houston Garden Center in the rain and picked out a couple of ajuga to fill up the empty spots left in the ajuga area. Or maybe I'll plant them under the strawberry bush. Possibilities ... hmmm....Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com2tag:blogger.com,1999:blog-6060458220631787471.post-75411795285653722082009-04-12T22:00:00.003-05:002009-04-12T22:17:04.309-05:00Brazos Bend :)<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU_9xZHAnT8h4_zbixVzuv2CNKb8VV2_DTymPHWb91l2zYCAn4jYjJoJOYaIHU2BTRoeRKeQ_5AiWmb6stuWoi7Qs1GdNabnpWLMDSqQbsbPFISFe6S79uribv2AQGzQeCXdWIwD3Cc4s/s1600-h/kattakingpicture.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 240px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU_9xZHAnT8h4_zbixVzuv2CNKb8VV2_DTymPHWb91l2zYCAn4jYjJoJOYaIHU2BTRoeRKeQ_5AiWmb6stuWoi7Qs1GdNabnpWLMDSqQbsbPFISFe6S79uribv2AQGzQeCXdWIwD3Cc4s/s320/kattakingpicture.jpg" alt="" id="BLOGGER_PHOTO_ID_5324008506370715234" border="0" /></a><br />Had a great day yesterday. Persuaded Kathryn to go to Brazos Bend with me. Actually, it wasn't hard. Apparently all I have to do is prefix a request by "would you like to go in the truck to X" and the answer will be "yes." Kathryn calls this "the truck novelty." I'm trying not to only use this information only for important things. We had a great time walking the trails and I got a rare shot of Kathryn taking pictures. I like this picture because it shows her intensity and focus on getting the shot she wants. Naturally, she will hate this picture, because she hates all picture of herself.<br /><br />After walking around, we headed briefly down to Bryan Beach, then ate at our favorite German restaurant in Lake Jackson. Had my first Samuel Smith's Imperial Stout. Delicious! All in all, a wonderful day, and a very welcome change from work/school. It made me want to visit other state parks. I feel an Austin trip coming on... Kathryn's never been there and is interested.Markhttp://www.blogger.com/profile/03379623071859963866noreply@blogger.com0