Wednesday, November 24, 2010

Caroling

I'll be caroling with Master Chords at Bayou Bend on Dec 2, 9, and 10.
Details on the flier.

Thursday, October 21, 2010

70 pushups!

I've been doing my push-ups* in sets: 20 push-ups, hop up, rest 10 seconds, down and do 20 more, etc., for a total of 80 push-ups (my third rest period is 15 or 20 seconds). I think I've done them that way for two weeks now. The hope is, of course, that it will increase the number I can do all in a row.

This morning, I did a progress test, and there was definite improvement. There's always some variability in how many I can do, so it might range from 63 to 67, but today I did 70. I have never, ever, done 70 at a stretch. So yay. I'll keep doing the sets, and probably slowly increase the number per set.

*Hmmm...no hyphen in the title, but hyphen here. There doesn't seem to be a consistent version in Google.

Sunday, September 12, 2010

Can't Go Bach Again

At the end of the Bach choral season in the spring, we have re-auditions. This allows Albert (the conductor) to review what he's got, and compare it to any potential new members auditioning. This year, I didn't hear back from Albert in a timely fashion. Around mid-summer, I got a phone message from him asking me to call back. I did, and left him a message. Then later, another.

I took the fact that I got a phone call rather than an email as a negative sign. Not hearing back was another. Finally, I got the email that confirms that I'm not in the core group for this season.

Sigh.

Saturday, August 14, 2010

We All Deal Feet

We went to Ideal Feet today. As you may know, Shelly has been plagued with foot and back pain for years. I heard Ideal Feet's commercials on 740 KTRH (which, I have to say, is not the best place to find things to try) and I thought it would be worth looking into.

The first thing to say about them is we do not like the way they do business. Most notably (and you'll find this complaint if you web search) is that they have no money-back guarantee. No refunds. Their policy on this is
"Since our products are personal items we do not offer refunds. But should you have any difficulty wearing the supports we will adjust them for FREE!"
What? I should point out that an "adjustment" means you bring them back and they re-measure and give you a different size. And you can do that at any time, as often as needed. The point being, they don't mind taking them back, they just don't want to give you your money back over your dissatisfaction. So it might help to think of this as a service contract, and not merely paying $400 for a couple of pairs of insoles.

On to our experience: we were helped by Brandon, who is a nice guy, and when he's not in the process of delivering the company-mandated spiel, seemed to be inclined to be honest with us. He is a salesman, and was up-front about having no medical expertise.

The spiel, on the other hand, is unadulterated hucksterism. It consists of mentioning "aligning 26 bones and 33 joints" any number of times; a "balance test" that doesn't test balance, but purports to show that the insoles provide stability (but is really just a bit of trickery worthy of the Church of Scientology); and taking impressions of your foot without and with the insoles to show how the pressure distribution changes, which is the most honest (and relevant) bit.

Then came the fitting. He measured Shelly's feet— the significant measurement being the arch length— and took "2 seconds" (yes, part of the script) to go to the back and pick out the insoles for her. Shelly asked whether this was a one-size-fits all solution, and he said that, no, there are some 40+ sizes back there, very precisely sized by arch length (not arch height). As your feet adapt, your arch length can change, and you would then need to come in for a re-fit (i.e., exchange them for a different size).

The insoles are noticeable: there's a big lump right under the middle of your arch, which requires you to gradually work up to wearing them for extended periods. Shelly required that I go through the fitting, as well. I actually like the main insoles; the secondary ones (that you wear when you're not wearing your primary ones, to keep your feet from reverting) I did not like.

In the end, in spite of all the red flags, we got a set for Shelly. Desperation makes you try things that you would otherwise consider stupid. Maybe the company is counting on that. There is a chance that this is a worthwhile product, and that the company is just horrible about how they do their marketing.

We'll let you know. So in the meantime, feel free to go in for a fitting. Enjoy the spiel. But don't buy anything. Tell them you're waiting to hear how they work out for us.

Thursday, August 5, 2010

A little JavaScript™ Invention

One deficiency in JavaScript™ is that it has no sleep command. Instead, it has a setTimeout function, which works differently: you tell it what you want to run, and how long you want it to be before it starts, and that acts like a little time bomb in the background while your program continues on. It doesn't pause. So if you want it to actually pause, you need to pass the entire rest of your program in.

That sounds crazy, and it kind of is. But JavaScript™ (I'm writing it that way because it really is a trademarked name) is for web apps, where you don't really run a whole program. What you're usually writing is callbacks for widgets. It's a callback-oriented language.

So today, I had the need to put a pause in a series of requests I was making, so that they wouldn't all happen at once. How to do that as I'm looping through the array? Tail-recursion, of course— that's how you loop in a functional language. I came up with a function that works like the forEach method, only it has a specified pause before invoking the callback:

          // Like forEach, but with a delay
function delayForEach (queue, callback, delay) {
var qIdx = 0;
// recursive block
(function () {
if (qIdx < queue.length) {
callback(queue[qIdx], qIdx);
++qIdx;
setTimeout(arguments.callee, delay);
}
})();
}

It's just a little thing, but I thought it was nicely elegant. It should be noted that this call will all run "in the background": if you call delayForEach on some array, your program will continue on, and the looping will be done as if it were running independently. Still, could be useful for somebody.

Upon reflecting a bit, it seems to me that it might be more appealing to use setInterval instead.

         function delayForEach (queue, callback, delay) {
var qIdx = 0,
interval = setInterval(function () {
if (qIdx < queue.length) {
callback(queue[qIdx], qIdx);
++qIdx;
}
else {
clearInterval(interval);
}
})();
}

Wednesday, August 4, 2010

Deriving the Y Combinator

The Y-Combinator Derived

The Y-Combinator was something that came up in my Programming Languages class at Rice. It was bizarre and inscrutable to me, and I never really acquired a deep understanding of it. Frankly, it doesn't have a lot of practical application, but it is interesting. And Douglas Crockford said something like, "If you understand this, you can call yourself a computer scientist." Well, I certainly want to be able to do that. And maybe this post will create a few more computer scientists. I hope so.

First, I want to note that I depended heavily on this page for my derivation steps. I changed them as I saw fit, but it was nice to have them to refer to when I screwed up.

My intent is to derive the Y-Combinator in a way that makes it obvious what's going on. This subject has been done quite a few times (and in quite a few languages), but they always use meaningless function and variable names, and I find that makes it hard to follow. So I'm taking my stab at it. I've been writing in JavaScript lately, so that's what I'm using here.

The first step on that road is to understand what we're deriving. The Y-Combinator is a function that provides "anonymous recursion". That is, if your language doesn't provide a way for a function to call itself while it is being defined, the Y-Combinator can give you that.

Specifically, let's say you have a function that you can tell how to call itself, and then it can be recursive:

function factorial (myself, n) {
return n <= 2 ? n : n * myself(myself, n - 1);
}

What you want, though, is a function that doesn't have to tell itself how to call itself every time.

// This doesn't work. We need "myself" to be defined somehow
function factorial_wish (n) {
return n <= 2 ? n : n * myself(n - 1);
};

The first step is to "curry" myself out of the original function:

function curried_function (curried_self) {
return function factorial (n) {
return n <= 2 ? n : n * curried_self(curried_self)(n - 1);
}
}

With this, curried_function(curried_function) returns the factorial function you want, which you can then call with a single argument, and it will work:

var working_factorial = curried_function(curried_function);
working_factorial(5) // returns 120

But what we really want is for the factorial function to reference itself, and not the curried outer function, so that it would be written more like factorial_wish above.

We do that by wrapping a function around it that will define myself for it, and will take care of calling curried_self with itself.

function curried_v2 (curried_self) {
return function factorial (userArgument) {
var inner = function(myself) {
return function(n) {
return n <= 2 ? n : n * myself(n - 1);;
};
};
var myfact = inner(curried_self(curried_self));
return myfact(userArgument);
};
};

Now the innermost function is in the form we want; the function that wraps it, inner, defines its myself for us. The function that wraps that is our new factorial function, which will be what we pass an argument to, and which takes care of the curried mess.

The use of the variables is not strictly necessary here, but it helps make clear what's going on. In programming, it is often a bad practice to combine multiple operations into one monolithic, incomprehensible statement. But in math, it is called "reducing", and it's good. And the Y-Combinator comes from math called Lambda Calculus. We're just trying to understand it in terms of programming.

The calling of this hasn't improved. You still have to call it with itself to get your factorial function out:

var working_factorial = curried_v2(curried_v2);
working_factorial(5)

What has improved is that the inner function is independent of the stuff it's wrapped in, so it can be pulled out, and you'll note that it looks exactly like the factorial_wish function from earlier, wrapped in a function that takes a myself. So what remains is (almost) the goop we're looking for.

var inner = function(myself) {
return function(n) {
return n <= 2 ? n : n * myself(n - 1);
};
};

function curried_v2a (curried_self) {
return function factorial (userArgument) {
// inner was here, and is still needed
var myfact = inner(curried_self(curried_self));
return myfact(userArgument);
};
};

So the next thing to do is to pass inner to our function, so it's not hard-wired to look at some global(ish) variable. We'll do this by (of course!) wrapping it in yet another function layer, where we can do the double call, as well:

function basically_Y (inner) {
function curried_v2a (curried_self) {
return function (userArgument) { // not necessarily factorial, any more
var myfact = inner(curried_self(curried_self));
return myfact(userArgument);
};
};
return curried_v2a(curried_v2a);
}

To use this, we pass in the inner function we previously extracted (or any function that is built like it), and we will get back a well-behaved recursive function that knows how to call itself.

var myfact = basically_Y(inner); // using the inner defined earlier
myfact(5)

All that's really left is generalizing it to handle more than one userArgument.

function Y (inner) {
function curried_v2a (curried_self) {
return function (/* any number of user arguments */) {
// .apply(null, arguments) is how you pass along all arguments
return inner(curried_self(curried_self)).apply(null, arguments);
};
};
return curried_v2a(curried_v2a);
}

I went ahead and substituted in for myfact, since it's not all that complex, (not to mention that this is no longer just about factorials) but I have retained the variable that is curried_v2a.

To get to the no-variables form, we do a little re-writing: Instead of defining curried_v2a, we create a function that takes it as a parameter, and then pass its definition to that function. The function does the calling-it-on-itself part, and we're done!

function Y (inner) {
return function(curried_v2a) {
return curried_v2a(curried_v2a);
}(function(curried_self) {
return function() {
return inner(curried_self(curried_self)).apply(null, arguments);
};
});
}

It's still incomprehensible, but if you've been through the derivation, the parameter names might jog your memory about what's what.

Thursday, July 22, 2010

The question nobody is asking

Shirley Sherrod is feeling a little vindictive. That's not surprising. She's been on quite a roller-coaster lately. She wants to sue Andrew Breitbart for releasing that out-of-context videotape of her. Again, that's understandable, although he didn't make the tape, and didn't know it was out-of-context.

She says, "[H]e came at me. He didn’t go after the NAACP; he came at me." Now that's not true. He released the tape in response to the NAACP's accusations of racism among the Tea Party ranks, to show that the NAACP has their own problem with racism. And it did. Sherrod doesn't know it, but she wasn't being held up as a racist, she was the one pointing out that the NAACP has a problem with racists in their ranks. She was Breitbart's ally in this.

The fact that the tape was edited to make her sound more racist than she is, is just a little bit of delicious payback in kind. It doesn't change the real point being made, which is the answer to the question no one is asking: Why was she giving this talk?

Well, she was trying to promote enlightened views on race, of course. (I should probably put "enlightened" in quotes, since her message was that it's "not so much" about black vs. white, but about class warfare instead.) It's admirable to want to promote enlightened views about race reconciliation. To whom would you want to promote such views? To those who already have them? Or to those who seem to identify more with the bad example? I don't think NAACP meetings are like AA meetings, where you get up and talk about how bad you were and everybody sympathizes because they're all recovering racists, too, and that support helps keep you on the wagon.

I think Shirley gave that talk because she believes that the NAACP has a problem with racism in their midst, and she would like to see it improve. Much like Andrew Breitbart.

Friday, July 2, 2010

Javascript and Dojo

Since I don't have any theater projects coming up, I figured I might as well fill in the space with what I'm doing at work. My latest gig is working with Javascript and (in particular) the Dojo toolkit to develop some web apps.

In the process of coming up to speed on Javascript and Dojo (neither of which I have used a great deal), I'm hitting Google a lot to learn how the various things work. There is, of course, some level of documentation on everything at the Dojo site, but in some cases it's incomplete, and I have to look elsewhere for someone to explain it better. So in the hopes that maybe someone else will be doing the same sort of thing someday, I'm offering this post to explain how dojo.deferreds work.
Update: Naturally, an updated version of Dojo has made this whole discussion nearly obsolete. The new features in the deferred are more intuitive.

What is a dojo.deferred?

In short, a dojo.deferred is an alternative to threads, a way of having relatively independent parts of your program running at that same time. As the documentation page says, "threads are hard."

Think of it as a chain of functions, which you build up one link at a time. You schedule them in the deferred, and kick it off, and it will work its way through them while the rest of your program continues to run uninterrupted (particularly useful if it's a time-consuming operating like waiting for a response from some remote server). If it reaches the end of its chain, it will sit and wait until you put another link on it.

Each link in the chain is a pair of functions. Which of them is called depends on what the previous link returned: if it returned an error, the errback function of will be called; if it returned a normal value, the callback function will be called. So it is critical that each function return something.

Building the chain

There are four possible functions you can call to add a link to the chain: addCallback, addErrback, addBoth, and addCallbacks, and which you call depends on whether you want to specify just a callback, just an errback, the same function to be run in either case, or separate functions for each. In general, the first link in the chain can be just a callback, because there's no danger of an error preceding it. But subsequent links should include both; if a piece unexepectedly ends in error and you have no errback to handle it, the whole deferred silently grinds to a halt.

Kicking it off

It might not be obvious that you have to actually start the chain processing. It doesn't start chugging immediately, you have to "prime the pump" with something for it to consider as the return value of the previous link. You do this by calling its callback() method, which you pass whatever value you want sent to your first callback.

Example time

I find that most examples are too detailed, so I'm going to keep this one more abstract, so that you see what the deferred is all about and don't get lost in the weeds.


//Let's say we have some functions we're going to chain up
/*
* The deferred is going to call each with the
* result returned by the previous one
*/

function thing_one(i) {
return 'Done with 1';
}
function thing_two(result) {
return 'Done with 2';
}
function thing_three(result) {
return 'Done with 3';
}

/* And here's a generic error function to
* use for every step
*/
function myErrback(e) {
alert("Some step of the deferred returned an error!");
}

// Create the deferred
my d = new dojo.Deferred();
// Chain up the steps
// No chance of failure, so no errback on the first
d.addCallback(thing_one);
d.addCallbacks(thing_two, myErrback);
d.addCallbacks(thing_three, myErrback);
// Kick it off by passing 'Go!' to thing_one
d.callback('Go!');

Note that even after you kick it off, you can add more function pairs to the chain, and they will be processed in the order received. I hope this helps somebody understand this nifty tool.

Thursday, May 6, 2010

No performances on the horizon

Bach season is over, and I haven't lined up any theater for the summer. There's a good chance I won't be doing any, because we're focusing on getting our house remodeled. There's a certain amount of irony in having to get a house in shape to be torn apart and re-made, but that's what's going on. We've got stuff that we will have to move out and store (plus, we'll have to move out, ourselves), so we have to go through everything and get rid of anything we don't really want.

Fun.

Wednesday, March 31, 2010

Videos from the Far Side

What conservatives say:

What liberals hear:

Monday, March 8, 2010

Camera Lust, The Next Generation


The new entry-level Rebel has everything I'm looking for in an SLR: full HD video, low-light performance, more pixels than I need, and a sub-$1000 price tag ($800 for body only, $900 for kit including 18-55mm lens).

Tuesday, January 26, 2010

Sucked into Facebook

In the unlikely event that any of you have clicked on my Blogging Friends link for "Not Worth The Effort", you would have found that his blog has finally lived up to its name. He has abandoned blogging for Facebook.

I don't intend to completely abandon blogging, but I have joined Facebook, and it is probably a better way of keeping in touch with my friends and family. On the other hand, I can say things here that I can't say there because there are fewer people to offend here. You, dear reader, are one of a very select group. You get to see this, which I think is gut-bustingly funny:



Not that I would mind Mom seeing that.

A push-ups update: I did not find that I gained much in the way of push-up endurance by doing multiple sets. I think I did gain about three on average, but it stopped there.

And in upcoming events: I'll be part of a ballet for the first time. Not cavorting around in tights, but I'll be onstage, in costume, singing. The Bach Choir, with Mercury Baroque and the Dominic Walsh Dance Theater are presenting a ballet-opera hybrid, Romeo & Juliet. A preview: