» re-reading robert jordan

I was in an airport bookstore last week and picked up one of the newer Wheel of Time books. I opened it to a random page and read:

Nynaeve crossed her arms under her breasts and sniffed.

Yes, well, shocking. I stopped reading after Winter's Heart, but I have found something that almost makes me want to start reading them again. It's Leigh Butler's Wheel of Time Re-Read, wherein she, well, re-reads Jordan's epic, complete with varying amounts of breezy, pop-culture commentary on each bit. My favorite bit so far, having only “re-read” The Shadow Rising, was an musing on Mat as the classic American hero.

She's in the middle of The Path of Daggers right now. I find myself strongly tempted to re-read all of the novels--and read the new ones--through the lens of this blog. I haven't looked at the inspiration for this project, the Lord of the Rings re-read, but I suspect that one would be equally compelling.

posted by Nate @ 2:44 PM [ 8 May A.D. 2010 ]

» analogical thinking

We were riding around in the car this past weekend and Becca was complaining that Ally was so enamored with everything she did. Tricia was attempting to explain that this is because Ally thinks Becca is so cool and someone to look up to. Tricia told Becca, “She thinks you're the cat's meow!”

Becca thought about that for a second, and Ally piped up with, “You're the dog's woof!”

Hooray! My child is thinking analogically! This feels like a big step. We compliment Ally on her observation.

To which Ally responds, “You're the pooping dog's poop!”

OK, still thinking analogically, but...

posted by Nate @ 8:26 AM [ 5 May A.D. 2010 ]

» functional language proponents

Seen on an LtU thread:

Actually, I think one of the reasons FP proponents are more convinced of the superiority of functional programming than is necessarily warranted is due to their high degree of applicability to writing compilers, where almost all I/O is input to a function at one end and output at the other end, where the input and output are defined in specifications, where there is an unambiguously correct mapping from source to target, where the data is inherently tree structured, where the structure of the computation involves recursive pattern matching and transformation, where there is virtually no dynamic code loading necessary, etc. It's a match made in heaven; and if all you do is geek on languages and compilers - especially in an academic context - of course it's self-evident that functional programming is superior to everything else.

How true, how true.

posted by Nate @ 3:55 PM [ 28 April A.D. 2010 ]

» pwnat

Cool tool of the day: pwnat. From the description:

pwnat, pronounced “poe-nat”, is a tool that allows any number of clients behind NATs to communicate with a server behind a separate NAT with *no* port forwarding and *no* DMZ setup on any routers in order to directly communicate with each other. The server does not need to know anything about the clients trying to connect.

Simply put, this is a proxy server that works behind a NAT, even when the client is behind a NAT, without any 3rd party.

There is no middle man, no proxy, no 3rd party, no UPnP/STUN/ICE required, no spoofing, and no DNS tricks.

The above page also features a description of how it works. Very cool.

posted by Nate @ 3:21 PM [ 27 April A.D. 2010 ]

» commentary on peter pan

I have meant to blog about Sympathy for Hook: Toward a Christening of Peter Pan ever since I read it several months ago. Even re-reading it today, it stirred up the same mix of emotion (“cool!”, melancholy, thoughtfulness) that it did originally. To whet your appetite:

Peter Pan is about the death of children, long a daunting challenge to both simple faith and learned soteriology. It is, however, equally about deadly parental neglect--about not wanting or loving children. It is all too timely for our era of selfishly infertile and casually feticidal adults. Perhaps we miss Peter Pan's central themes in part because child death post partum has become far rarer than it was a century ago. We also may miss them, at least in part, because we dismiss as mere caricature the story's main adult character, Captain Hook: We fail to recall and give due weight to the tradition, which goes back to the play's first staging, under Barrie's direction, that Hook be played by the same actor who plays Mr. Darling, a flawed father. Mr. Darling and Hook are, in fact, the same character, operating respectively in this world and in Barrie's limbus puerorum, Neverland. Although, as G.B. Shaw noted, Peter Pan “is ostensibly a holiday entertainment for children but really a play for grown-up people,” appreciation of its burden for grown-ups requires attention to its main adult character. Appreciation of Peter Pan requires sympathy for Hook.

Recommended reading, particularly for parents and doubly so for fathers.

Tricia and I started reading Peter Pan this past summer and were somewhat taken aback at the tone and violence in the book (thanks, Disney!). But this essay makes me think that completing the book will definitely be worthwhile. Now to find the road trip to read to each other...

posted by Nate @ 9:23 PM [ 18 April A.D. 2010 ]

» financial regulation

Eliot Spitzer on the need for government financial regulation:

When I was Attorney General of New York, we investigated what I refer to as the "analyst cases." The cases were about investment banking. To understand them, all you need to know about investment banking is that the business has two sides: you have supposed analysts, who recommend stocks for investors to buy, and you have underwriters, who sell IPOs, secondary offerings, and other things that raise capital for the companies. We argued that there is an inherent conflict of interest when you have people in the same business who are both recommending a stock to retail investors--saying, "this is a great stock, buy it"--and doing the underwriting. The more successful the underwriting, the more fees it will generate, and the more favorable the analysis, the more likely the underwriting will succeed.

This is clearly a conflict of interest. In fact, Jack Grubman, the telecom analyst banned from the securities industry in 2002, brilliantly encapsulated this whole era: what used to be viewed as a conflict of interest, he said, is now viewed as "synergy." Think about that. What used to be viewed as a conflict of interest--hence dangerous to people, something to warn them about--is turned into something that creates value. This was the way we masked the problem. In the analyst cases, we didn't discover the conflict of interest: everyone understood it and had accepted it for a long time. But at the attorney general's office, we called it what it was...

The lawyers for Merrill came into my office. Now, when you're a white-collar defense lawyer, you argue in the alternative. First you say the emails were taken out of context. Then you say: "you don't fully understand them." Then you say, "no, they were fabricated." Then you say the person doesn't really speak on behalf of the company. And then you check the limits on your insurance. I was a white-collar defense attorney for a number of years, so I know the drill.

They didn't make any of those arguments. They came to me and said, in essence, "Eliot, you're right. Absolutely right about the conflicts, the tensions, the problems. But we are not as bad as our competitors." That was their defense to the charge that they were defrauding their customers and the marketplace. When I asked to hear more about it, they said, "let me tell you about Goldman and Citi." I've turned defendants over the years, but these guys were the easiest flip I've ever done.

There is a very important point here: the people at Merrill Lynch understood that their business model was problematic. They understood that there was something wrong with recommending stocks that they didn't think were any good. But they had to choose between ethics and profits, and they made the choice that harmed individuals and undercut the integrity of the market. And then they said it wasn't up to them to enforce the rules of transparency. Somebody else should do it.

posted by Nate @ 3:36 PM [ 12 April A.D. 2010 ]

» greenspun makefiles

Greenspun's Tenth Rule:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Can we apply that to Makefiles, too? This is what I wrote tonight:

find-hwm-sources = $(subst $(srcdir)/arch/$(ARCH_DIR)/,,\
                            $(wildcard $(HWM_DIR)/$(1)/*.$(2)))
hwm-c-objfile-name = $(subst /,-,$(1:%.c=%.o))
hwm-S-objfile-name = $(subst /,-,$(1:%.S=%.o))
hwm-sources-varname = HWM-$(1)-$(2)
hwm-objects-varname = HWM-$(1)-$(2)-objects

define hwm-object-template
$(call hwm-sources-varname,$(1),$(2)) := $(call find-hwm-sources,$(1),$(2))
$(call hwm-objects-varname,$(1),$(2)) := \
  $$(foreach o,$$(value $$(call hwm-sources-varname,$(1),$(2))),\
     $$(call hwm-$(2)-objfile-name,$$(o)))
$$(value $$(call hwm-objects-varname,$(1),$(2))) \
  : hwm-$(1)-%.o : hwm/$(1)/%.$(2) $(if $(subst S,,$(2)),,assym.s)
	$$(CC) $$(if $$(subst S,,$(2)),,-D_ASM -include assym.s) $$(ALL_CFLAGS) $$< -c -o $$@
HWM_ALL_OBJ_$(2) += $$(value $$(call hwm-objects-varname,$(1),$(2)))
endef

HWM_C_SUBDIRS := timer rhymer nickel dimer dcache icache ucache wecache zing
HWM_S_SUBDIRS := base
$(foreach s,$(HWM_C_SUBDIRS),$(eval $(call hwm-object-template,$(s),c)))
$(foreach s,$(HWM_S_SUBDIRS),$(eval $(call hwm-object-template,$(s),S)))

(newlines and backslashes inserted for sanity in word-wrapping; had they actually been there, make probably would have choked.)

Just think how much easier that would have been in a language with real macros. Of course, it's also possible that there's a much simpler way to do what I wanted...

posted by Nate @ 10:23 PM [ 9 April A.D. 2010 ]

» looping issues

I really enjoy using loop. Collapsing a surrounding let in a with binding clause or lifting an if expression into a conditional execution clause brings me happiness. One of the things I dislike about it, though, is collecting with nested loops. In highly repetitive macroized code, for instance, it's not unusual to want to do something like:

(loop for ...
  do (loop for ...
        collect ...))

Except that doesn't work, because you're only collecting in the inner loop, not in the outer loop where you want. There are ways around this; you can do:

(loop with list = nil
  for ...
  do (loop for ...
       do (push ... list))
  finally (return (nreverse list)))

Or, if you like using loop's features:

(loop for ...
  nconc (loop for ...
           collect ...))

I don't particularly care for either of those, though I'll use the last one if the situation arises.

Recently, though, I found a shortcut for a special case. I needed to loop over several quantities, each of which could be true or false. Extending the second workaround to a multilevel loop...well, let's not go there. However, by doing some bit-twiddling, I arrived at:

(loop for bits from 0 below (ash 1 n-quantities)
  for q0 = (logbitp 0 bits)
  for q1 = (logbitp 1 bits)
  for q2 = (logbitp 2 bits)
  ...
  collect ...)

which works well and avoids deeply nesting code. It even works if you have one quantity that iterates over a number of values that's not a power of two. Say you have three true/false things and one tri-valued thing:

(loop for bits from 0 upto #b10111
  for q0 = (logbitp 0 bits)
  for q1 = (logbitp 1 bits)
  for q2 = (logbitp 2 bits)
  for q3 = (ecase (ldb (byte 2 3) bits)
             (0 ...)
             (1 ...)
             (2 ...))
  ...)

Perhaps not overly useful, but a nice trick to have in your bag.

posted by Nate @ 11:37 PM [ 6 April A.D. 2010 ]

» love my debugger

I love my debugger.

I realize that this is not the usual stance among developers. The Practice of Programming by Kernighan and Pike states in the chapter on debugging:

As a personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging statements stay with the program; debugger sessions are transient.

Now, “thinking harder” is certainly a valuable skill. Debugging kernel oopses without the running kernel is certainly a valuable skill. (Read that link; it's the sort of debugging you ought to aspire to.) But I think it's fair to say that the above paragraph advocates two approaches to debugging: thinking hard and putting in print statements.

The critical observation that's made me love my debugger in the last several months is this: a debugger is a tool for inserting print statements at runtime. Stick a breakpoint where you think things are going wrong and poke around when you stop there. Stick a breakpoint a little further along if you need to. Disable the previous one because it's not helpful. If your debugger supports it, tell it to automatically print out some information when it hits a breakpoint and/or make that breakpoint depend on some condition you think is interesting. If you're feeling daring and you think you botched an assignment somewhere, tell the debugger to modify some variable values when you hit a breakpoint and continue execution. Yes, it's all boiling down to print statements, but you're doing it at runtime.

Plus, you can do all of these things without recompiling your program. And that is a huge huge win. With a huge program to debug, even with a beefy machine for compilation, you're stuck twiddling your thumbs waiting for a compile/link cycle. Ooops, wait, you have to do another one because you screwed up a semicolon or some matter of syntax. Oh, hm, that print statement isn't giving me enough information; I need to go insert another one somewhere. Bother, that's too much information, I should set up a debug level framework for enabling these messages separately. Wait, I need some information over here to obtain more clarity; should that be debug level one or debug level two or another debug level entirely? Whoops, fix that format string mismatch with my printf...you see how this can get tedious.

I was starting down the above path earlier this week when I decided to use the debugger instead. (And in a humorous twist, I was working on GDB, so reaching for the debugger should have been the first thing on my mind!) And the experience was significantly more pleasant and took me much less time than bothering with debug levels and printfs and staring at log output.

I'm not as good as Kernighan and Pike; perhaps I don't think hard enough about where to place my debug statements. Or I make too many simple typos and require too many recompile steps. Or the programs I work on don't follow the Unix Way strictly enough and are too big. And yes, I've worked on several codebases where using a debugger was painful and print statements are a better option. But the next time you're about to write a bevy of print statements to tell you everything you need to know about what your program is doing, try using a debugger instead. I bet you will be surprised at how much better the debugging experience is.

posted by Nate @ 9:11 PM [ 25 March A.D. 2010 ]

» movie recommendations

Tricia and I are planning on activating a free 1-month Netflix subscription in the next few days. Our short list of movies we'd like to rent during the subscription is:

Anybody have any other suggestions?

posted by Nate @ 12:02 AM [ 18 March A.D. 2010 ]

» book report

I've had a bit more time to read than normal these past two months because I've been traveling for work. Even though I don't feel like I've been reading a book a week (my goal), the list below suggests I'm not doing too badly.

My recommendations from the above list are: Daemon, which is essentially Halting State cranked to 11. The assembly line was an excellent representation of the lure behind MMOs. Whole Earth Discipline was a challenging book, especially if you lean “green.” I understand the positive side of postmodern thought much better after reading The Next Reformation; Who's Afraid of Postmodernism can serve the same purpose, but as it focuses on Foucault, Derrida, and Lyotard, it doesn't give one quite as much history or as broad an understanding as The Next Reformation.

Honorable mentions: Unlocking the Clubhouse gave me a lot to think about with raising two little girls and exposing them to technology (which I admittedly haven't done very much of beyond twiddling with iTunes and explaining how to play CDs in the PS2). I appreciated the vision that Cradle to Cradle presented; I wish all books were made out of similar material, both for the pleasantness of heft and for the eco-friendliness. The Price of Spring was just as good as I expected it to be. If you like fantasy and you haven't read Daniel Abraham's Long Price Quartet, you ought to start now.

What didn't make the list above? I tried reading One Market Under God by Thomas Frank, but I only made it about a quarter of the way through before I got sick of his smug know-it-all tone. I've mostly finished Discussion of the Method by Billy Vaughn Koen, which serves much the same purpose for the engineer-ingly bent among us as Gödel, Escher, Bach did for computer scientists. I skimmed through No Easy Answers by Allan Franklin; his descriptions of famous physics experiments were interesting, but past the first one or two, they didn't really draw me in. The description of the Meselson-Stahl experiment that proved how DNA replicated is worth a read, though.

posted by Nate @ 7:08 PM [ 5 March A.D. 2010 ]

» cities and redemption

From Sidewalks in the Kingdom by Eric Jacobsen:

...This radical change in the status of the city from a place of sin and unfaithfulness to the ultimate context for our redemption raises at least one important question: What can account for such a radical shift? Why did God take what looks to be one of humanity's worst inventions and use it as the primary context for our redemption?

The answer to this question is to be found in the question itself. Our God is fundamentally a God of redemption. God takes us (and our decisions) seriously. When we make mistakes--even profound ones--God does not obliterate the scars these mistakes leave on our character and start over. Rather, God takes our mistakes and reworks them into his divine plan and transforms our scars into something beautiful. Joseph said to his brothers when they repented of selling him into slavery, “Even though you intended to do harm to me, God intended it for good.” So also it seems that God has said of our cities, “You meant them to be a form of escape from me, I used them to draw you back to me.”

And we see hints of this redemption theme all around the cities of the Bbible. Cain's desire to flee to Enoch after killing his brother later finds a redeemed expression in the cities of refuge. The fear of the residents of Babel that they might be scattered is redeemed when the Isrelites find cities in the Promised Land in which they can gather. The Hebrews long to be free from their tyrant, Pharoah, and eventually found a good king in the city of David. And finally, the Babel residents' desire to make a name for themeselves is met in Jerusalem, where God has caused his name to dwell.

Redemption shows that God's power to redeeem and restore is stronger than our ability to alienate and break down. But redemption is not always the strategy that we would chose if it were up to us. Often what we seek is a return to innocence. We want to forget about the past and start over. Psychologically, we repress painful memories. Relationally, we cut ourselves off from people who remind us our past. And culturally, we ignore our history in favor of what is new and current.

...But for those who seek to take the Bible seriously, this cannot be our strategy. We cannot hate the city when our God is using it for good. We can suport the city from a truly rural setting, but we cannot retreat to our own private gardens. That way has been closed off. We must at some level learn to take our cities seriously. Whether live, work, worship, and play in our imperfect cities, or even just for them at a distance, we need to look to our cities if we hope to catch a glimpse of what God has in store for us.

I approve of the strategy of incrementalism. Starting over can be an option, but the opportunity to do so happens so infrequently that we are danger of idolizing it. Not just in cities, but in other contexts, too.

posted by Nate @ 2:30 PM [ 18 February A.D. 2010 ]

» banks asking for regulation

If banks are going to continue in their expectations that the government is going to bail them out, then the government is naturally--regardless of arguments from the left for increased regulation or from the right for steering clear of the self-correcting market--going to impose regulations to make it less likely that banks will place themselves in a position in which a bailout is necessary. Simple economics. You can debate back and forth about the popular merits of such a decision and the political maneuvering that comes with that. But the government is acting in its own self-interest in this case, plain and simple. The banks are getting exactly what they asked for.

posted by Nate @ 9:52 PM [ 22 January A.D. 2010 ]

» grouchy c programmer

Whenever possible, feature macros in C should be #define'd to 0 or 1, rather than letting the definedness or lack thereof be the switch for the feature. This convention means that you can talk about the feature macro in conditions, rather than having to jump through hoops to do so. (Doing so also means that you can play clever tricks in code with said feature macros if need be...) Of course, this implies that your compiler needs to be intelligent about dead code elimination in the presence of disabled features, but what compiler isn't?

Also, to all the hotspot rockstar programmers out there who are enormously impressed with their ability to record key routines from the C library using whizbang vector instructions and cache control instructions and show massive speedups: please try to actually test your code to ensure that it has the same correctness properties as the code in the C library. Nobody cares how fast your routines are if they cause buffer overflows on real-world code, rather than the trivial benchmark you threw together.

posted by Nate @ 10:05 PM [ 15 January A.D. 2010 ]

» ice skating

We took the girls ice skating yesterday. Becca liked it so much that she declared that she wanted to go back today. So we did that, with one change: I put on skates today and went out on the ice. Yesterday was mostly holding onto Ally while Becca was on the ice or vice versa. Tricia was going to send me out on my own.

“I'm not sure I've ever been out without holding onto somebody before,” I said.

“How many times have you been ice skating before?”

“Two.”

“How old were you?”

“Twenty-one.”

As you can guess, I haven't had much experience ice skating. By the end of the public skate session, though, I had managed to make it around the rink a couple times at a fair distance from the side. I even managed to take both of the girls out all by myself--and let me tell you, that was about the most fun I've had with my children in a while.

I was so proud of Becca too, for really trying to skate both days. She even managed to travel short distances (a couple of yards) on her own.

posted by Nate @ 11:33 PM [ 1 January A.D. 2010 ]