Monday, April 30, 2007

spring

It finally feels like spring has arrived here in Worcester. The flowers are blooming from the trees, in great white poofy and pink blossoms. After my first winter here on the East Coast, it feels glorious to stand outside and just soak in the sun.

This semester is finally over. I still feel a little unsatisifed with my performance in Dan's logic class; the simplest things trip me up. Ever time I do a logic session, I come out feeling mentally pummeled. Brain squish just like grape! But not because the material's necessarily difficult, but just that I come in with so much mental confusion.

For example, I got confused with the concepts of Skolem Hull and the Herbrand universe, which are different concepts. The Skolem Hull submodel only contains points that are interpretations of all the nameable elements of a language. A Herbrand universe, on the other hand, is a set containing only the nameable terms themselves. A hash collision.

We talked about models that include "junk" (elements that can't be named by terms) and "confusion" (named terms that go to the same element). It's funny, though, how the terms of logic are adopted by other subcultures, things like "compactness" and the "no junk, no confusion" properties, and in ways that are totally different from the definitions in mathematical logic.

I should probably spend a few more days in the sun and try to weed out the junk and confusion in myself, the ill-formed and redundant thoughts.

Friday, April 20, 2007

function of the day: fold

The fold function does very much what the name implies: it's meant to fold ingredients into a big mixing bowl, of course. Here's a definition:


;; fold: (ingredient bowl -> bowl) bowl (listof ingredient) -> bowl
;; Folds in a list of ingredients into a bowl with a folding-action.
(define (fold folding-action a-bowl ingredients)
(cond
[(empty? ingredients) a-bowl]
[else
(local ((define mixed-bowl (folding-action
(first ingredients)
a-bowl)))
(fold folding-action mixed-bowl (rest ingredients)))]))


FOLD here adds an ingredient at a time, using the folding-action to mix in every ingredient thoroughly into our large bowl. Once we have this incorporating function, we can roll up our sleeves and whisk some pancake batter:


;; make-pancake-batter: -> string
;; Example of FOLD to make pancake batter.
(define (make-pancake-batter)
(local ((define (whisk an-ingredient a-bowl)
(string-append a-bowl an-ingredient))

(define pancake-ingredients '("flour" "sugar" "eggs" "milk"))

(define empty-bowl ""))
(fold whisk empty-bowl pancake-ingredients)))

Oh! I forgot the baking powder, so those pancakes will be a little stiff. Oh well.

Of course, we might even want to whisk in a slightly different way:

(local
((define (whisk an-ingredient a-bowl)
(cond [(string=? an-ingredient "eggs")
(string-append a-bowl "egg-white-only")]
[else
(string-append a-bowl an-ingredient)])))
(fold whisk "" '("flour" "eggs" "cabbage")))

Now we've got the basics of an okonomiyaki, I suppose.

We might even be silly enough to mix things that aren't even food!

> (fold + 0 '(1 2 3 4 5))
15

but this seems like a boring example compared to whisking.

Folding is popular, but for some reason it goes by different names by different programming camps. Python programmers call it REDUCE, and Ruby programmers call it INJECT. I don't know about these names, though: I think they sound a little bit aggressive for my taste. As for me, I like the homeliness of "fold": it reminds me of the kitchen.

Tuesday, April 17, 2007

death and taxes

I can't help feeling haunted about the deaths in yesterday's shooting. The shooting itself makes no sense to me.

I can appreciate that people are trying to find meaning in the murderer's actions, trying to blame video games, or psychotic drugs, or jealousy, or divine retribution. It can't all be random, can it?

I suppose there's a story about the murderer that remains to be told, the motives and the exposure of lurid, petty details. Still, he is meaningless to me.

I do see clear meaning in the actions of people like Liviu Librescu. How gloriously different are the saints. I'd rather think about Professor Librescu and the others like him, who faced death with courage, teaching one final lesson: "Love is stronger than death." Another one of those lessons that I'm trying to believe.

Sunday, April 15, 2007

stick a fork() in it

Sometimes I really really dislike C for its low-levelness.

Here's one concrete example why. Predict the output of the following program:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char** argv) {
printf("hello world\n");
if (fork() == 0) {
printf("child\n");
} else {
printf("parent\n");
}
return 0;
}


with the following:

dyoo@dyoo-desktop:~/work/net-2$ gcc -Wall test-fork.c
dyoo@dyoo-desktop:~/work/net-2$ ./a.out
[predict your output here #1]
dyoo@dyoo-desktop:~/work/net-2$ ./a.out | cat
[predict your output here #2]

Yes; I was surprised too, but #1 and #2 can produce different output.

At least, this is what I see:

dyoo@dyoo-desktop:~/work/net-2$ ./a.out
hello world
child
parent
dyoo@dyoo-desktop:~/work/net-2$ ./a.out | cat
hello world
child
hello world
parent


The bug here is the interaction between the low-level fork() and the way that buffered output works in C. In the second case, since I'm piping through cat, there's more output buffering going on. The first printf() is buffered and not immediately printed but rather stored somewhere. The fork() duplicates the process. So when both the child and parent processes close, they flush their respective buffers... and we see this unusual output.

Some man pages do talk about this, like the one from SGI IRIX. Linux's man pages, not so much. Ah well.

Thursday, April 12, 2007

cyberdyne

I went to the NEPLS conference at Tufts University on Wednesday. It was a lot of fun; I got to hear programming language theory talks and meet with other people interested in the same sort of crazy things that pull my attention. I did like Dave's talk: the idea of collapsing idempotent type checks to preserve space seemed perfectly reasonable. I wonder if any of that will trickle back into PLT's contract system.

The last presentation, on Spatial Computing, was especially fascinating. At a first glance, it seemed ridiculous, and the scope of the project so breathtakingly absurd. I clamped my hands over my mouth to muffle my giggles. But as the speaker presented more and more, the whimsical thought came into to me: maybe this is how Skynet begins.

I hope that I too will someday build something that brings both laughter and pondering thoughts. And I'll also keep in mind to try avoiding the development of systems that might lead to the creation of bloodthirsty androids.