03 November 2011

"Discoveries" in the Vulgate

It was preschool mom's night out last night, so the obvious thing for me to do was spend some quality time with online versions of the Vulgate Bible. It was shocking and thought-provoking to see the word "holocaust" (and its Latin equivalents) used all over Vayikra (Leviticus). Part of me now wants to start using "Shoah" instead, at least in contexts where people would know what I'm talking about. Or maybe "Nazi genocide"?

On a lighter note (well, almost anything would be lighter than that), I really enjoyed the Vulgate (well, Duoay-Rheims) translation of Kohelet (Ecclesiastes) 1:15:
The perverse are hard to be corrected, and the number of fools is infinite.
As opposed to, for example, the King James:
That which is crooked cannot be made straight: and that which is wanting cannot be numbered.

30 October 2011

All you need is partial application


I've been struggling to program in the functional style for many years now. Part of the struggle was I didn't really have a good sense of what others had done, so I was fumbling around in the dark. Though reinventing the wheel has its advantages and pleasures, it is best done by choice rather than through ignorance. Google is great, but imperative brainwashing is greater: in the beginning I didn't even know what words to search for to find that I was far from alone. And this was even with the benefit of an expensive education that included an introduction to LISP as an undergrad and a grad class on semantics that used Scheme for its exercises!

The other part of the struggle was that, as with most people, at work I didn't have the luxury of using languages intended to support the functional style.

That brings me to what I want to share here, which is that I've come to a tentative, and, to me, surprising conclusion about some language features that are not needed to support functional programming.

The following features are associated with functional programming.

  • Anonymous functions.
  • Nested functions with lexical scope (NFLS).
  • Partial application. 

There are certainly others (pattern matching?) but they're not my concern here.

My tentative conclusion is that you can get by just fine with only partial application. I don't know of any language that does this, but I've been experimenting with limiting myself to this style, and it has been working out quite well.

First of all, people (including formerly me) make too big of a deal about whether a language supports anonymous functions. To me it is a syntactic red herring because it doesn't matter that much if you have to introduce a name. We are all guilty about caring way to much about brevity (and syntax in general). A more charitable interpretation is that support for anonymous functions is emphasized because it is a good signal that the language has other, more substantive support for functional programming.

Now, NFLS is a more substantive feature, though I think it is still somewhat superficial. Here I'm distinguishing NFLS from closures. NFLS is a syntactic construct whereas closures are a semantic construct: a function bound up with its environment. Closures are a natural consequence of having first-class functions, i.e. functions as values, in a language that supports NFLS.

But my insight, which may be obvious to others but was not to me, is that you don't have to have NFLS to have closures. In particular, you can form closures by partial application, and it is not too inconvenient to have that be the only way to form closures.

To put it another way, to program functionally, you have to be able to pass functions around, i.e. you have to be able to have higher-order functions. In addition, those functions passed around need to have an environment that consists of more than the arguments provided at their call site. So you need closures. But you can get by with partial application alone, i.e. you can get by without NFLS.

For my experiments, I've implemented partial application as a function in Perl and PHP. The implementation uses NFLS, but I don't use NFLS anywhere else in my code; I just use partial application.

I actually think it is not only okay to program this way: it may actually be desirable. I think it may be a simpler mental model that there are just functions, syntactically, i.e. no NFLS, and two ways to apply them: partially and completely.

I also wonder whether in new languages it might be simpler to support partial application as a primitive rather than support the syntactic complexity of NFLS and anonymous functions.

I will close by noting that I have purposefully avoided here any mention of the classic topic (well, classic within some circles) of how objects can be used instead of closures in languages that have no way to form closures. This is the way most higher-order programming gets done today, without the programmer even knowing it, and therefore without any of the fear or disdain that often result when explicit higher-order programming comes up against imperative brainwashing.

My tenuous Tennyson link

What's the simplest way to put it? My great aunt was the Baroness Tennyson. Yeah, that Tennyson, but a couple of generations down from the poet, and only for a little while. And to call her my great aunt might be a stretch. Before she was the Baroness, she was the widow of my grandmother's step-brother. 

Nonetheless, this tenuous link got me curious about the autobiography of her husband the Baron. It is called From Verse To Worse, which I found to be an auspiciously clever, humorous, and self-deprecating title. The Wikipedia page about him proved tantalizing, particularly in its claim that the autobiography was reminiscent of P. G. Wodehouse. So, I called in another ILL (Inter-Library Loan) favor from my long-suffering wife and got it.

And so far, it does not disappoint. Though I must admit that, for an American, I have a bit of a bias towards all things British, probably from watching too much BBC via PBS as an impressionable child and adolescent. It may also be explained by nature or nurture since my grandfather had a similar bias towards all things British. And here I'm talking about my grandfather on the Jewish side of my family, in which, to my knowledge, nobody ever entered the peerage. My mom says he used to ask her why she couldn't act less Italian and more British. In my defense, at least I have none of that fascination with the Royal Family that so many Americans seem to suffer from.

Some choice quotes from what I've read so far:
At Farringford I started to ride on a Shetland pony called "Dumps." He was about twenty years old then, and the most infernal little brute, and got me off just as he liked. (p. 21)
Previous to this he had been pensioned off in a cottage on the Farringford Estate, where he lived on hard boiled eggs cooked fifty at a time, and on dried goat's flesh. (p. 23)
There are two other memories of mine connected with Suez and Port Said, and these are of passing the Spanish Transports full of troops going out to fight in the Philippines, and of riding in a donkey-race with some of the other passengers, which I won. My mount was called Ta-ra-ra-boom-de-ay. (p. 28)
Amidst these glorious scenes of nature, we had a strange contrast in observing one of the most cruel practices of mankind. In the midst of the grilling heat of the Red Sea, we passed close to two ships taking cargoes of slaves from the interior of Africa to the opposite shore. They were all manacled together and looked a piteous spectacle. (p. 28).
What countries still had slavery at this time (1899)?

I will end there on this sobering note, hopefully with more updates to come, if again some night I cannot sleep. Unfortunately I think I can't scan and post the book since according to my cursory research on UK copyright, it won't be in the public domain until 70 years after the author's death, which will be 2021. I suppose I could try to get the publisher, if they still exist in some form, to release the rights ....

20 October 2011

Partial function application in Perl and PHP

Lately I've been playing with the idea that the only language feature you need to support the functional style is partial application.

I've even been playing with the more extreme idea that the even if you have other language features associated with the functional style, perhaps it is a good idea to limit yourself to partial application. The language features I'm thinking of avoiding are anonymous, nestable, and lexically-scoped functions.

I'll leave it to another post to explain these ideas. All I really want to do here is share my implementations of partial application in Perl and PHP.

Of course these implementations rely on all those features mentioned above: anonymous, nestable, and lexically-scoped functions. So the style I'm experimenting with uses all those features, but only here, in the implementation of the partial application function!

21 September 2011

Rosh Hashanah, the sun, and the moon

Here's my current stab at visualizing a series of the following events:
  • sunrise, sunset
  • moonrise, moonset
  • the Hebrew calendar
  • the Gregorian calendar
I'm using the days surrounding Rosh Hashanah just for fun, and because it is upon us.

All times are one hour too early because I am not correcting for Daylight savings.

One thing to note is the new moon on 28 Elul/09-27, as can be seen from the fact that moontime and daytime are nearly centered upon each other. (I'm using "moon-time" to mean the time between moonrise and moonset.) Ideally the new moon would be on 1 Tishrei, but it doesn't always work out that way.

Another thing to note is that this period includes the day on which there is almost exactly 12 hours of light, 27 Elul/09-26. (To match the chart, below I use times in PST not PDT, i.e. I ignore Daylight savings.)
  • sunrise 0544 (5:44am)
  • sunset 1745 (5:45pm).
You might think that this day with 12 hours of light should be the equinox (09-23), but here's an explanation of why this is not the case.

Some of the many areas for improvement include adding the days of the week, using daylight savings, and solving the problem with blurry text on top of color.

19 September 2011

Tisha B'Av and the moon

This year I attended a discussion of the Jewish holiday Tisha B'Av lead by Rabbi Nickerson at Temple Isaiah. Indirectly, this led me to do a lot of learning about the moon. How did I get from Tisha B'Av to the moon?

Well, first I learned that Tisha B'Av just means the ninth day of the month of Av. (Well, its deeper meaning is the commemoration of the destruction of the Temples, but that's not what I'm concerned with here.) I noted with surprise that this year the ninth of Av was also the ninth of August. I'm too lazy to figure out how often this happens, but my guess is that it is pretty evenly distributed and thus happens only about once every 30 months (2.5 years).

Then I remembered something I learned from Joshua Mason-Barkin when one time he led our Torah study at Temple Isaiah: Jewish months start around the time of the new moon.

So that got me thinking: this August, the day of the month will correspond to the phases of the moon. This is no big deal for a Jewish month (it literally happens all the time), but is kind of special for a Gregorian month. Wikipedia helped me make the following guesses for the big four phases of the moon in August. (The key piece of information was that a quarter of a synodic month is about 7.38 days).
  1. I guessed that the new moon must have been around day 1 (Aug 1).
  2. I guessed that the first quarter must have been around day 8.4 (Aug 8).
  3. I guessed that the full moon would be around day 15.8 (Aug 16).
  4. I guessed that the last quarter would be around day 23.1 (Aug 23).
  5. I guessed that another new moon would be around day 30.5 (Aug 31).
I wasn't quite right, but I was close. Here are the exact answers from Griffith Observatory's LA-customized run of the US Naval Observatory's MICA software. (The only sense in which this is LA-customized is with respect to the time zone, i.e. the phases of the moon (unlike moonrise and moonset times!) are global.)
  1. new moon: Jul 30 11:40
  2. first quarter: Aug 6 16:08
  3. full moon: Aug 13 11:57
  4. last quarter: Aug 21 14:54
  5. new moon: Aug 28 20:04
Here's a calendar visually showing the phases of the moon for each day in August 2011.

The main source of my errors is that the new moon wasn't exactly at 00:00 on August 1. It was actually about 1.5 days before that, Jul 30 11:40. Jewish months start around the time of the new moon, but not exactly at the new moon. To be fair, the month of Av started at sunset on July 31, which was a little closer to the new moon than 00:00 on August 1.

How far off is the start of the Jewish month from the new moon? What were the sources of my errors other than this main one? What's up with the times of moonrise and moonset? Are they related to the phase of the moon? What are some good ways to visualize the relationship between moonrise, moonset, sunrise, sunset, the Gregorian date, and the Jewish date?

I will try to cover some of the questions in a follow-up blog post.

Tisha B'Av commemorates the sometimes-tragic consequences of the irreconcilable differences between Jewish and Gentile civilizations. But this year it landed in harmony with the secular calendar, bringing me closer to the solar system we live in and bringing me closer to the great ancient civilizations that tried, and almost succeeded, in reconciling the irreconcilable motions of the earth, the moon, and the sun.

15 September 2011

Pestering cruise offer robo-call

Anybody else getting this robo-call?
On behalf of Royal Caribbean, Norwegian, and Celebration Cruise Lines, your household has been selected to receive an all-inclusive cruise. For fun in the sun, press "one;" to be removed, please press "two." Again, to speak to an agent, please press the "one" key.
We get it about once a week. I've tried to be removed by pressing "two" but it has not worked. Of course the number is blocked, which is not allowed. Also we are on the "Do Not Call" list so they should not be calling in the first place.

The secret crisis in real-time software

This is a weird post, because really it is just two links. First, I want to give a shout-out to the following article, which I view as very important.

Edward A. Lee. "Computing Needs Time". Communications of the ACM, 52(5):70-79, May 2009.

Second, and, far less important, but in line with the general self-aggrandizing character of this blog (and most blogs?), here's a link to a post of mine on Lambda the Ultimate, "My enthusiastic support, for whatever that's worth."

13 September 2011

Faith in DRY; no hope for software

DRY means Don't Repeat Yourself. It is, or at least should be, a fundamental principle of software engineering. I believe in DRY. Strongly. Perhaps more strongly than I believe in God. But I don't advocate for it, because advocating DRY implies the following beliefs:
  1. lots of people don't believe in DRY, and
  2. of those people, lots can be convinced of DRY.
I believe (1) but not (2), and that combination deprives me of hope for software. As in, all hope is lost. Seriously. Not that all the computers in the world will soon stop working, as was feared for Y2K, or something dramatic like that. Just that we are doomed to never make any progress beyond where we are today. Today we produce software through a laborious, undisciplined process that combines the low quality work of many with the heroic high quality work of a few. What would progress look like? Well, an efficient, disciplined process that raises the minimum quality of the work and requires no heroism. But it ain't gonna happen. Not enough people believe in DRY and other good practices like it.

A person should come to believe in DRY automatically after their first experiences writing software. If this has not happened, you should not try to convince them of DRY; rather, you should try to convince them to stop writing software. This is not to say that such a person is bad or unintelligent; they are just bound to write software of low quality.

There are people who "get" DRY and people who don't. Trying to convince someone of DRY is asking them to change something too fundamental. It is somewhere between a way of thinking and a core belief. It is not something whose value you can prove to someone. The trade-offs are too complex to measure objectively.

Now, you may say that I am being too extreme in that there must be some people who are on the fence and can be convinced of DRY. The only wiggle room for hope I see here is that some "closet" believers can be encouraged to come out when other believers set a good example by practicing their faith openly and vigorously. Also, you can of course share techniques for DRY among believers. But that's not what we're talking about here.

Now, you may also say that I am being too extreme in that even a non-believer must be able to play a productive role in writing software if that role is appropriately bounded. Perhaps this can help a little, but I see two reasons why it can only help a little.

The first reason bounding only helps a little is that DRY is still important at small scales. At small scale it is easiest to achieve, and therefore perhaps least interesting to discuss among believers, since the techniques are more obvious, e.g. the use of subroutines. But please remember that there are people who basically do not believe in subroutines. I have worked with people who think nothing of a subroutine that is 500 lines long. In fact it makes more sense to them that way. They say they like that they can read it straight through like English text without being distracted by "jumps" to subroutines. The fact that DRY is not practiced even when it is easy to achieve shows how deep non-belief can run.

The second reason bounding only helps a little is that bounding someone's work can mean forcing them to repeat what others have done. DRY really includes the less-catchy abbreviation DRSE, Don't Repeat Someone Else. Another way of looking at this is that DRY in some sense works against modularity. Or, to be more precise, DRY frequently demands re-drawing the boundaries of modules when commonalities are discovered as those modules develop. So restricting someone's work to a pre-determined module can mean inviting a large-scale DRY violation. Now, non-believers would usually not see such commonalities, and even if they saw them, they would never exploit them. The point is that bounding their work does not bound the impact of their non-belief. You still end up with software that repeats itself.

Even though we're never going to convert the non-believers, it would be nice if our tools at least allowed us to practice our faith. Instead, particularly at large scales, they require us to go to great lengths to practice DRY. The trade-offs, already hard to justify objectively, become even harder to justify at large scale.

For an example from my experience, build systems do a terrible job of supporting DRY. In some sense these are small-scale problems but I consider them large-scale in the sense of considering stuff like build systems and test code that isn't part of the final product.

Build systems suffer from the same problem of any system that encodes information without abstraction mechanisms to avoid repetition: they make the fatal mistake of distinguishing data from code. Have the 60-year-old discoveries of LISP taught us nothing? Concretely, why can't I specify my build using a real language, with subroutines? Even better if this real language is an existing rather than novel one.

To be fair, some build systems run counter to this trend; for example Buildbot builds are specified in Python. An alternative is of course to continue to distinguish data from code, but make it easy for the user to generate the data, thus abolishing the distinction. This is usually what practicing DRYers end up doing, but systems often make it very hard to do.

I've just begun to dip my toes into the big water that is database programming, but it already seems to me that, despite mighty efforts to the contrary, the state of the art is still generating SQL queries in a way that requires repetition and therefore invites inconsistencies between the queries, the database, and the surrounding code. Perhaps C#'s LINQ makes some progress on this front; I don't know. And even if they did not widely succeed, perhaps the fact that mighty efforts that have been made (e.g. object-relational mapping) is encouraging.

I will end on that encouraging note.

07 September 2011

Are sunsets boring?

Here are my comments on a thought-provoking piece by Lillian Daniel called Spiritual but Not Religious? Please Stop Boring Me. Thanks to Rabbi Joel Nickerson for bringing it to my attention by tweeting a link to it.
On airplanes, I dread the conversation with the person who finds out I am a minister and wants to use the flight time to explain to me that he is "spiritual but not religious."
On airplanes, I dread conversation, period. I guess that makes me an all-around misanthrope. This could be argued to be either an ethically stronger or weaker position than Daniel's more targeted dread. While I dread more people, a worse thing, I dread all people equally, perhaps a better thing.
Such a person will always share this as if it is some kind of daring insight, unique to him, bold in its rebellion against the religious status quo.
It is indeed tiresome when people overestimate the novelty of their thoughts, especially in the age of Google. But in some communities in the US, being non-religious is still a daring thing to share and does represent a divergence, if not a rebellion, from the status quo.
Next thing you know, he's telling me that he finds God in the sunsets. These people always find God in the sunsets. And in walks on the beach. Sometimes I think these people never leave the beach or the mountains, what with all the communing with God they do on hilltops, hiking trails and . . . did I mention the beach at sunset yet? 
Like people who go to church don't see God in the sunset! Like we are these monastic little hermits who never leave the church building. How lucky we are to have these geniuses inform us that God is in nature. As if we don’t hear that in the psalms, the creation stories and throughout our deep tradition.
Right, so why not use this as an opportunity to engage with this person and suggest to them that their "god in nature" idea is not only not in conflict with religion but in fact contained within religion? Perhaps they're more interested in showing off their not-so-novel idea than learning something. If so, I sympathize with Daniel. I know the type. I am one myself.
Being privately spiritual but not religious just doesn't interest me. There is nothing challenging about having deep thoughts all by oneself.
But the premise here is that this god-in-sunsets person is not having these thoughts all by himself! He's trying to engage with you about them. Or at least he might be, if he's not just trying to show off or pick a fight.
What is interesting is doing this work in community, where other people might call you on stuff, or heaven forbid, disagree with you. Where life with God gets rich and provocative is when you dig deeply into a tradition that you did not invent all for yourself. 
I agree with this idea of creating meaning through friction or even conflict between people. One might even go so far as to (circularly?) define God as "what people are arguing about when they argue about what God is." Perhaps this attitude is not surprising, since I am a Jew. But of course Jews have no monopoly on this.

But, I think it is the friction, not the tradition, that is necessary here. Having a tradition as a background for the friction grounds the discussion in a useful way, but is not necessary for the discussion.
Thank you for sharing, spiritual but not religious sunset person. You are now comfortably in the norm for self-centered American culture, right smack in the bland majority of people who find ancient religions dull but find themselves uniquely fascinating. Can I switch seats now and sit next to someone who has been shaped by a mighty cloud of witnesses instead? Can I spend my time talking to someone brave enough to encounter God in a real human community? Because when this flight gets choppy, that's who I want by my side, holding my hand, saying a prayer and simply putting up with me, just like we try to do in church.
The idea that our culture has become too self-centered resonates with me. I think the rise in popularity of self-authored wedding vows is perhaps an indicative trend, though one I can hardly condemn since I was part of it at my own wedding. My wife and I did use Google to borrow from others to form our vows and in that respect perhaps we showed some humility. Or was it just laziness? I suppose we formed our vows within the amorphous spiritual community that is the Internet.

I can see how the companion Daniel wishes for would be far superior for her, and perhaps even for me. But I feel compelled to point out that being religious is far from a guarantee that a person will be as spiritually rich as she describes. She is asking to sit next to someone very like her extraordinary self.

She seems to appreciate some degree of difference, so perhaps a rabbi companion would work as well for her as a minister. Though it is interesting to ask whether a turbulent flight is a time in which you want your beliefs to be questioned; I can see it going either way. On the one hand you might want to be comforted by agreement; on the other hand the rich engagement that comes with some disagreement might provide some welcome distraction.

In the end it is of course not important that we are interesting but that we are good. It matters not whether we see God in sunsets, or the testy supernatural being of the old testament, or both. It matters how we relate to the world around us: its people, animals, and environment. Then again, isn't being interesting part of how we relate to other people, and therefore perhaps a facet of being good?

P.S. For full disclosure, about 20 years ago, Lillian Daniel played bass in a band called Geek with my brother Derek Denckla.

17 August 2011

Scan of The Autobiography of WHD

Here, finally, is a PDF of Scan of the Autobiography of William Henry Donner.

It was quite an adventure trying to get Google (Blogger, Google Docs, Google Sites) to host a PDF without showing it in its own viewer. I ended up putting it up as an "attachment" on Google Sites and using a "Download" link in the management interface of Google Sites that I think/hope is actually usable by everyone.

You would think that sharing a PDF would be simple. Oh well, to err is human, to really screw things up requires a computer. I can't figure out whether this is Google's fault or, giving them the benefit of the doubt, somehow a result of their business strategy, which would somehow be impeded by easy hosting of PDFs viewed outside of their viewer.

Anyway, back to the content, I have definitely opted for content over form, inasmuch as those those two things can be separated.

In other words, this scan does no aesthetic justice to the original. I was concerned to keep file size small.

If you are fortunate enough to have access to one of the hundred copies of this book in existence, I highly encourage you to have a look. For the rest of you, here is the scan. At least I did the title page in color so you could get a sense of the use of red as well as black and I did the photo pages in gray scale rather than black and white.

I cropped the heck out of it so that a page contains pretty much only text. Though this ain't pretty, I thought it would make it easier to read in most programs on most screens.

There are lots of (small) blank pages sprinkled throughout; this is to make the PDF "just like the book," pagination-wise, including matching the content of what shows up int "two-up" viewing mode.

06 August 2011

Really different programming languages

If you have the luxury of time to learn a new programming language, here's my plug to learn a really different one. Though there is value in seeing a slightly different take on the same idea, like listening to a cover of a song, life is too short to spend time on that before you've exposed yourself to something really different.

Make sure you know what "really different" means, too. The popular discourse surrounding programming languages centers on what are really tiny differences. So you can easily get a false sense of what "really different" means. There's some truth to the idea that the brilliant success of our consumer culture is to make us think we have choice while in fact providing us with very little. That having been said, a language doesn't have to be unpopular to be really different, and of course not all unpopular languages are really different.

Some of the really different languages I've been exposed to were popular, but, importantly, not with people who consider themselves programmers. For instance, in my experience, languages used for musical applications tend to be really different. Perhaps I'll make another blog post to explore why this might be more than coincidental. But regardless, domain-specific languages are a good place to look for real difference.

I'll name a few, but these are just examples: my point here is not to promote specific languages. For music, Max. For signal processing and controls, Simulink and Stateflow.

Back to the category of good old general purpose languages for programmers, I'll give as examples Haskell, Prolog, and Erlang.

What is so important to me about Haskell is its purity. That is, its lack of implicit side-effects. Any functional language will open your eyes somewhat, and any language with type inference will do the same, but Haskell is the only one I know of that is pure. Laziness might be pretty hard to come by outside of Haskell, too. But to reiterate, because I want to be very clear on this point, I am not recommending Haskell. I am recommending being exposed to the big, really different ideas that Haskell represents.

Prolog and Erlang I myself have never tried, but they seem to represent big, really different ideas about programming, so I really want to try them, and I really want you to try them.

In closing, if you already know C++, try not to learn Java or C#. If you already know Ruby, try not to learn Python or Perl. In fact, if you know any of the languages I just mentioned, try not to learn any other of them. They're all object-oriented, imperative, textual languages. True, some are dynamically typed and some are statically typed. And true, the statically typed among them have different approaches to generic programming. And true, some have garbage collection and some do not. And C# has LINQ, which is interesting, and it has the capability to do things like LINQ, which is perhaps even more interesting.

Well now in my closing I've almost convinced myself out of my own argument. I guess I'll soften my argument to this, then: try to learn a really different language, but if you can't, when you learn a not-so-different language, focus on those features that are really different. As an extreme counter-example, I once saw a list of distinctive features of C# and it included easy quoting of strings with backslashes in them to make Windows paths feel more idiomatic. While I acknowledge that this may be of some pragmatic value, this is not the kind of thing that causes your mind to expand by learning C#.

Sorry to end on that negative note.

05 August 2011

Pleasant Software Development

During software development, I've often been tempted to say "you're doing it the wrong way." In a few cases, especially earlier in my career, I even gave in to temptation and said it. I may have even used a word considerably stronger than "wrong." I've certainly been tempted to.

I sometimes give in to a third-person form of this temptation by saying privately, "so-and-so is doing it the wrong way." I sometimes try to show a little self-awareness by saying, "I try not to frame things in terms of right and wrong, but in this case I can't resist saying that so-and-so is doing it the wrong way."

There are two problems with the idea of "the wrong way." One is that, to my continuing surprise, reasonable people vary widely with respect to what they think is wrong. The other is that even in those few cases where all reasonable people agree there is a wrong way, it is not productive to phrase it that way.

For the moment I'm only interested in the more common case, where there really is not a right and wrong, but it sure feels like there is. For that case, I've developed a bit of a mantra to calm myself down:
I can't say that this is wrong, but it sure is unpleasant.
This seems simple, or even obvious, but it had not occurred to me that I could validate my own feelings while still avoiding false and judgmental claims about what is wrong.

The reason I use the word "judgmental" is that the notion of "wrong" I'm trying to avoid has a moral dimension as well as a technical one. I care so deeply about these issues that I not only confuse truth with beauty, I also confuse technical and moral truths. Or, put another way, I confuse all three of the following things: what is right, what is righteous, and what is pleasant. I probably have something to learn from the Romantic poets, who I think struggled with such issues.

By reclassifying most things from wrong to unpleasant, I don't mean to to minimize their importance. Far from it. In fact, when you realize that you and your coworkers have a difference of taste, not a disagreement about what is right, that usually means it is time to walk away. Be civil, e.g. say goodbye, but walk away. You're not going to change someone's taste. At the risk of being over-dramatic, I think the Serenity Prayer is relevant here:
God, grant me the serenity to accept the things I cannot change,
Courage to change the things I can,
And wisdom to know the difference.
What do I mean by "walk away"? Maybe just end the conversation. But maybe it is time to look for another group at your company whose tastes are more like yours. And maybe, just maybe, it is time to move to a new company altogether.

Now for a final note on a big question: why are there so few facts about software development that most things come down to a question of taste? My gut reaction is that there are more facts out there to be learned, but it is very hard to study these questions. I mean no offense to those who study such questions, but I have to say I pay little attention to their results because I am inherently skeptical of them. They are doing that kind of work that is both really important and really hard.

It is perhaps telling that The Mythical Man Month is still one of the most important books about software development. I think the reason is both that it is a great book and that we haven't learned a lot since it was published in 1975.

Something I read claimed that computer science was still in its infancy and had not yet found its Newton. My initial reaction was "no, it has; Turing is its Newton." But then I got to thinking... Turing's greatest result is a negative one, about what computers can't do! Can that be analogous to Newton?

It is a fun debate to have, but to get back on topic, what I wanted to say was if computer science is in its infancy, then software engineering is positively embryonic.

I initially bristled when The New York Times told me that editorial policy prevented me from being listed as a software engineer in my wedding announcement, because editorial policy is that there is no such thing as software engineering. But then I got to thinking... Maybe those editors are really on to something. If usually all I can say is "It's not wrong, it's just unpleasant," am I an engineer?

Recycling may be garbage

I am skeptical of the value of recycling. But perhaps my greater concern is not whether recycling is worth it, but whether we can really have an informed debate about recycling and similar pressing issues in our society. Sadly, my guess is "no."

I think there are a lot of people who believe recycling is worth it and are not willing to question that belief. In that sense recycling has been one of the more dramatic successes of the environmental movement. In a short period of time, they've brought about big changes to people's behavior and governments' policies. It is all the more impressive that they've been able to bring about these changes despite unclear evidence of their value.

Maybe recycling will turn out to be like the profession of medicine: quickly popular and only eventually deserving of that popularity. Long before doctors could really help with much, they convinced society as a whole that they could help, and created a culture of clinics, hospitals, and general doctor-use and doctor-respect. Then society was all ready and primed when the time came (roughly speaking, the 2nd half of the 20th century) when they could actually start helping.

Anyway, back to the lack of questioning, perhaps it is telling that the best anti-recycling reference is still the 1996 New York Times Magazine article "Recycling is Garbage," by John Tierney. In other words, I would really have hoped to find more recent good mainstream references on the subject. Maybe there are, and I just haven't found them. Or maybe that was such a great article that there's no more to say on the subject. Or maybe it was so clearly wrong that no one else has bothered to pursue it. Or, most probable (and perhaps worst) of all, maybe questioning recycling is viewed as uninteresting or actually taboo.

Though they are in the minority, it is important to note that there are plenty of people on the other extreme; they believe recycling is not worth it and are not willing to question that belief. For instance there are a lot of frustratingly-conservative people who view any change with not just skepticism but derision and certainty of its foolishness.

What we really need, as always, are people who are in between, i.e. people who, regardless of what they currently believe about recycling, are willing to question those beliefs. We also need a few people who are equipped to perform the careful analysis of costs and benefits that is sorely needed. Plus they need to be equipped to communicate this analysis to the rest of us! The results of this analysis must be made as simple as possible, but no simpler. For example, I suspect the results of this analysis cannot be as simple as "it's worth it" or "it isn't."

I suspect that the costs and benefits of recycling vary greatly depending on things like the following. What materials are being recycled? Where is the recycling being done? How is it being done? How do you subjectively value some of the costs and benefits that are hard to assess objectively?

For example if in your area water is plentiful, that may lower the cost of water. Water is often used in both recycling and manufacturing from scratch. An expert could tell you which one uses more, but only you can say how much you think water truly costs. Perhaps you believe the market for water works perfectly and the true cost of water is the same as its market price. But I think not everyone feels that way. I certainly hope not.

Perhaps in your area water pollution is more costly than water use, or viewed by you as more costly. Then for you water pollution is more important than volume of water used. Perhaps climate change is your greatest concern; then CO2 emissions may trump anything having to do with water.

My point in these examples is that an expert can't be asked to say whether recycling is worth it. An expert can only be asked to say whether recycling uses more of various resources than manufacturing from scratch. Unfortunately it is up to you to decide the relative costs of those resources. What you really need then is not so much an expert but a person who you feel shares your values who has carefully considered the experts' more-or-less objective analysis.

In closing, I encourage you to Google for "Recycling is Garbage," since as far as I can tell it is the touchstone for all subsequent discussions of the topic.

P.S. I want to give a quick "shout-out" to a book I got from Greenhaven Press' Opposing Viewpoints Series, Garbage and Recycling. I see there is a new 2011 edition available. The whole series looks really great, and I think the U.S. would be a better place if kids read more stuff like this. Or, for kids who don't like to read, I recommend Morgan Spurlock's "30 Days" TV series, for non-polemic looks at some of our county's most important current issues.

30 June 2011

Places in the Autobiography of William Henry Donner

This post is not that interesting unless used as a reference alongside the book.  It is a list of links to Google Maps of places mentioned in the book.

Stuttgart, Germany
Pittsford, New York
Mossley, England
Franklin St & 8th St, Columbus, Indiana
Indianapolis, Indiana
Hope, Indiana
Hanover College
North Vernon, Indiana
Jeffersonville, Indiana
New Albany, Indiana
Louisville, Indiana
Sycamore St & 5th St, Columbus, Indiana (This address appears to no longer exist so I've mapped Sycamore & 6th.)
Hastings, Nebraska
Gas City, Indiana
Monessen, PA
Charleroi, PA
Donora, PA
Cerro de Pasco, Peru (Note "Open-pit Mine.")
Oroya, Peru (I have mapped "La Oroya" since that seems more likely what he meant given its location between Lima and Cerro de Pasco)
Buffalo, New York

The Autobiography of William Henry Donner, Chapter 23

The Autobiography of William Henry Donner has disappointed me in some ways, the main one being that it is largely impersonal. It mostly tells the stories of W.H.D.'s business successes (and a few failures). Of course, if that is what I had wanted, it would be great. Anyway, here is a chapter that is more personal and amusing, if you don't mind what might be considered some mild anti-Semitism. (Color not added, i.e. color in the original.)

Chapter 23. See Yourself as Others See You. Year 1895. When living in Anderson I left a pair of shoes with a cobbler to be repaired, but forgot to pick them up on the way home from work. I needed them that evening & asked my brother Fred, who was stopping with us & working in the mill, if he would go down to the cobbler near the post office and get them for me. I explained that Mrs. Donner and I were going out for dinner, that I needed them and was crowded for time. Fred replied, 'Certainly.' He started off, located the cobbler's shop as directed and asked for Mr. Donner's shoes. He was told 'I have no shoes for Mr. Donner.' Fred then asked if there was another cobbler nearby and was told there wasn't, but there was one two squares away. My brother concluded that the shoes must be in this shop and looked around. He discovered a pair which he thought were probably mine. He offered to pay for the repairs, take them home, and return them in the morning if they were not his brother's, to which the man agreed. When Fred brought them home and I said they were mine, he immediately began to roar with laughter & said that when he asked to whom they belonged the cobbler stated, 'I don't know the man's name, but he passes here frequently before seven o'clock in the morning, is always in a hurry, and looks like a Jew.' Fred thought it was a good joke and circulated the story among my friends.

29 June 2011

The Autobiography of William Henry Donner

Okay well my time off work has so far been spent on many things other than my great plans for my blog. But here I am back for a moment. This is off-topic, but I wasn't sure where else to put/share this.

I just got my hands on a copy of The Autobiography of William Henry Donner. William Henry Donner is my great-grandfather, though not biologically. He adopted my grandmother after he married my great-grandmother. For both of them, it was their second and final marriage.

This book is interesting on multiple levels, but the level you might naturally count as the first is its aesthetics. So I thought I would reproduce the text of colophon here. I may supplement this with a photo and/or scan later. Note that the color is in the original, i.e. this was a two-color print, with red headings and black text!

THE AUTOBIOGRAPHY OF WILLIAM HENRY DONNER has been privately printed in an edition of one hundred copies by Clifford Burke at Cranium Press, San Francisco. The type is a variant of Eric Gill's Perpetua from the Stephenson Blake Foundry, set by hand. It is printed on hand made Tovil, from the English mill of Barcham Green. The photographic prints were made by Larry Kunkel, who also supplied the photograph on page 25. The binding was designed & executed at the press by Diane Burke. Fall 1973.

28 April 2011

undefined subroutines in Perl

Perl does not complain about calls to undeclared subroutines made with parentheses. E.g. if f is undeclared, Perl would not complain about "f(2)", though it would complain about "f 2". Neither "use strict" nor "use warnings" changes the situation.

This is not always a bad thing, since it enables techniques in which f is undeclared at compile time but will be defined at run time. This is possible since "declared-ness" is a static / lexical / syntactic property, whereas defined-ness is a dynamic / semantic property.

But, this is a bad thing if such "undeclared but defined" techniques are not being used. In those cases, an "undefined subroutine" error can happen at run time. Such bugs can slip by tests when coverage is incomplete, e.g. in code to handle an error that is hard to provoke.

Three ways to avoid this problem are listed below.
  • avoid parentheses when calling subroutines
  • call only references to subroutines
  • use B::Lint
The most direct solution is to avoid parentheses when calling subroutines, e.g. to use "f 2" instead of "f(2)". This requires subroutines to be declared before they are used, which may require some adjustment to existing code or some adjustment to habits when writing new code. It also sometimes requires precedence to be made explicit, e.g. "f(2) or die" doesn't simply become "f 2 or die", it must become "(f 2) or die" or similar to preserve the original meaning.

If parentheses cannot be avoided, then a solution is to call only references to subroutines.
This takes advantage of the fact that Perl can detect undeclared variables via "use strict".
E.g.,
sub MyFunction { ... }
...
MyFunction();
becomes
my $MyFunction = sub { ... };
...
$MyFunction->();
One consequence of this style is that subroutines must be defined before they are used. This may be considered a good thing or a bad thing. Another consequence of this style is that it makes stack traces much less meaningful. This is almost certainly a bad thing. Consider the following program.
use Carp qw(cluck);
 
my $f = sub { cluck 'cluck'; };
sub g { cluck 'cluck'; }
 
$f->();
g();
The output of this program is
cluck at ./sub.pl line 9
  main::__ANON__() called at ./sub.pl line 12
cluck at ./sub.pl line 8
  main::g() called at ./sub.pl line 11
One way around this "__ANON__" problem is to use references to named subroutines rather than references to anonymous subroutines. E.g. the "__ANON__" problem goes away if the program above is modified with the following diff.
< my $f = sub { cluck 'cluck'; };
---
> my $f = \&g;
But, this re-exposes us to the problem of undefined subroutines at run time. E.g. above, if the user had accidentally typed "\&G" instead of "\&g", this would go undetected until runtime. In addition to being error-prone to write and maintain, this solution is cumbersome to read. E.g.
sub MyFunction { ... }
...
MyFunction();
Becomes
my $MyFunction = \&MyFunction;
sub MyFunction { ... }
...
$MyFunction->();
To discourage direct use of named subroutines, some naming convention should probably be used. Perhaps a prefix of "ppp", e.g.
my $MyFunction = \&pppMyFunction;
sub pppMyFunction { ... }
...
$MyFunction->();
Another way around the __ANON__ problem is to use the Sub::Name CPAN module.

Finally, the B::Lint core Perl module can be used. Though it claims to be equivalent to an extended version of the -w option, there are some important differences that may limit its applicability. It is unlike -w in that it only compiles the program; it does not run it. Also, unlike -w, it has no lexical form, whereas -w has the analogous lexical form "use warnings".

I conclude by thanking Perl Monks for the posts below.

22 April 2011

underscore, "while", and angle brackets in Perl

This post discusses some pitfalls of the Perl construct "while (<>)". We'll refer to it as WAB (While Angle Bracket).

WAB sets $_ but does not localize *_ (the underscore glob). This can cause undesired interactions with other constructs that set $_. These constructs include "for ()", "foreach ()", "map", and "grep".

In general, if a WAB is dynamically enclosed by one of these other constructs, it will try to stomp on the enclosing $_. If $_ is not a constant, it will succeed in stomping on it. If $_ is a constant, recent Perls will die with "Modification of a read-only value attempted".

The program below, wab.pl, shows this. Its WAB stomps on the $_ set by the enclosing "for ()". What's more, since $_ is just an alias to the members of the list given to "for ()", the WAB stomps on the list, too!
The command "true | ./wab.pl" gives the following output.
$VAR1 = undef;
$VAR2 = undef;
The effect is more dramatic if the list given to "for ()" contains constants. If we modify wab.pl with the following patch and run it under a recent Perl, it dies with "Modification of a read-only value attempted".
12c12
< for ( $a )
---
> for ( 1, $a )
There are various ways to avoid WAB's behavior. One way is to explicitly localize *_. For example, we could modify wab.pl with the following patch.
8c8
< sub f { while ( <> ) {} }
---
> sub f { local *_; while ( <> ) {} }
The output would then be as follows.
$VAR1 = 1;
$VAR2 = 1;
We can also just stop using WAB. For example, we could modify wab.pl with the following patch.
8c8
< sub f { while ( <> ) {} }
---
> sub f { while ( my $f = <> ) {} }
That concludes the main body of this post. Some additional notes appear below, for the more curious.

21 April 2011

bash pipefail

If you care about the exit code of a piped bash command, you must set the "pipefail" option. The code below shows this.


Output:
false alone: 1
false piped to head: 0
false 'pipefailed' to head: 1
The "take home" message from this is that you should always set the pipefail option. Too bad it is not the default.

Below are links to some other sites on this topic.

20 April 2011

Inaugural post

Now that I've left Oblong Industries, I have time to write a blog.  I plan to post on programming, build systems, and software engineering in general.  I plan to express my opinions as well as present facts I wish I'd known.  These facts will rarely be discoveries, i.e. most of them will be widely known already.  For those widely-known facts, I hope to add some value by presenting them in a way I wish had existed.  Perhaps that will be a useful theme: "facts I wish I'd known, presented in a way I wish had existed."