2008-04-10

The Spammers Have Won

My last post here warned, in a cryptic and laconic way, of the dangers of trusting automated processes over human judgment — to wit, it was a Google search for the result of people doing a search-and-replace on the font name “Arial” to replace it with the font name “Verdana”, but also altering content as well as markup, and partial words as well as whole. Thus, “adversarial” → “adversverdana”. Cute, huh? (No, I don't go trolling for that kind of thing. I was reading one of the documents so afflicted.)

Apparently, between that and the way that I'll leave this thing unattended for months while meaning to post stuff but not actually doing that thing (in part because, well, originally I'd been hoping to write actual halfway-decent posts here, not twitters-out-of-place like that), I've been declared a possible spam blog and must now transcribe letters from an image to prove my humanity in order to make or edit posts.

Really? In my last job, I got paged in the middle of the night, on weekends, on weekends in the middle of the night, and even on vacation HOW many times, because some mail system had fallen over with its legs in the air from too much spam? And I spent HOW much time delicately tuning Postfix's rate-limiting, because there just wasn't enough hardware for the spam, but I didn't want to delay actual people's LKML subscriptions or whatever as collateral damage? To get this.

So, on the one hand, I can understand where the Google Overlords are coming from, but on the other hand, I'm kind of insulted. And I usually don't take computers' opinions of me all that personally.


Meanwhile, I note that, mysterious spam flag or no, infrequently updated or no, this blog still comes up in the first page of a Google search for... my name. Which, as it's shared by someone famous enough to have his own Wikipedia page, is not a completely vacuous achievement. Or something.

2008-02-28

Fun with the Value Restriction

This is not a valid OCaml program:

type 'a endo = Endo of int * ('a -> 'a)
let poly = Endo ((succ 23),(fun x -> x))
type thing = { u : unit }
let mono = Endo (0,(fun { u = u } -> { u = u }))
let _ = [mono;poly]


The typechecker rejects it, with this error message:

File "vrmh.ml", line 5, characters 14-18:
This expression has type 'a endo but is here used with type thing endo
The type constructor thing would escape its scope


Removing the last line makes it typecheck. As does exchanging the second and third lines, thusly:

type 'a endo = Endo of int * ('a -> 'a)
type thing = { u : unit }
let poly = Endo ((succ 23),(fun x -> x))
let mono = Endo (0,(fun { u = u } -> { u = u }))
let _ = [mono;poly]


Yes. Notice the mysterious action-at-a-distance. Notice also how the type inferred for poly (see ocamlc -i) is not polymorphic at all, but rather thing endo, the same as mono. Notice further that it would not be possible to define it with an explicit ascription of that type before the definition (i.e., outside the scope) of thing itself. Apparently this is bad.

And then there's the reason why the type of poly didn't have its type variable generalized, thus leaving it with the type '_a endo and subject to unification with the type of mono. This is, of course, the value restriction of ML fame, which I will not explain here; but it's a little more confusing (read: I spent far too much time trying to come up with the mostly minimal test case seen here) (so, yes, this actually is something I ran into in a halfway-real program) in OCaml, where it's been relaxed in certain ways. But not others. For example, this:

type 'a endo = Endo of int * ('a -> 'a)
let poly = Endo (24,(fun x -> x))
type thing = { u : unit }
let mono = Endo (0,(fun { u = u } -> { u = u }))
let _ = [mono;poly]


Is fine.

2008-01-27

Wheels Within Wheels

Exhibit A: Hashed and Hierarchical Timing Wheels: Efficient Data Structures for Implementing a Timer Facility, by George Varghese and Tony Lauck, originally in SOSP '87 and later reappeared in 1996 when network protocol research had caught up to it.

Exhibit B: An implementation of hierarchical timing wheels for the fleshy-ape platform, due to David Allen (2002).


(I haven't actually read Getting Things Done, but I have friends who swear by it, some of whom talk to me about it, to which I tend to wind up responding with “oh, that's just locality of reference” or similar.)

2007-12-30

On the importance of punctuation

Just now I was reading a slashdot article where a bunch of people where whining about some links or other being to some site called “myminicity”. Several mentions of that name later, it finally dawned on me that it was not, in fact, a compound of the usual English state-of-being suffix -ity and some hypothetical trendy nonsense word(s) I hadn't heard of yet (cf. “meme”); but, rather, was to be read as the words “my mini city”.

(I still don't know what the thing actually is, because I don't care.)

If only people had decided to use hyphens when gluing words together for domain names, then I wouldn't have to occasionally waste valuable seconds wondering WTF some string of half-pronounceable letters is supposed to be. (They also wouldn't run the risk of an unfortunate powergenitalia incident, but how often does that happen?) Ah well.

2007-12-27

The Sound of Silence

Let's say you have a video file of some sort with no audio stream, and a device that plays video files but can't handle ones with no audio. And you want to use the command-line tool ffmpeg, because you already have a script set up to use it to do whatever transcoding, but for the slight problem of sound.

Maybe you don't, but I did. Know that ffmpeg can take multiple input and/or output files and shuffle them around, in addition to decoding/encoding them. Know also that ffmpeg is documented in a manner both voluminous and not terribly approachable.

The wrong thing to do is to try to figure out how to extract the length of the video track and generate that many audio samples of silence. But, if one hasn't noticed the right part of the man page, this may be what one tries to do. (I did.)

The right thing to do is to use the -shortest flag, which directs ffmpeg to stop whenever any input stream reaches its end, rather than when all inputs are done. Some of you may be (but probably none of you are) thinking of various versions of the Scheme procedure map and their behavior on lists of unequal and/or infinite length, recently a point of contention in the discussion leading up to R6RS. And what is Unix if not a platform for stream processing? (Don't answer that.)

Thus: -f s8 -i /dev/zero -shortest, placed either before or after the regular input file, depending on whether input that does have audio should be silenced or not, respectively.

It's a not entirely inelegant solution to a mildly ridiculous problem.