Batch tricks: Recursion

Aah, recursion, the favorite pet of every programmer. Surely it must be possible to recurse even in Windows batch files (I'm still trying to prove Turing-completeness, by the way :-)).

The first tentative test would be an infinite recursion:

@ECHO OFF
:JUMP
CALL :JUMP

And know what? It works. Well, kinda:

******  B A T C H   R E C U R S I O N  exceeds STACK limits ******
Recursion Count=599, Stack Usage=90 percent
******       B A T C H   PROCESSING IS   A B O R T E D      ******

But that's ok, we didn't expect this to do anything useful except of causing a stack overflow. But as we can see, cmd has a stack of some sort and seemingly manages it well enough to allow for recursion.

Time for another test, this time something remotely practical: Factorials. Never mind that those are more easily done with iteration, we want to make sure that recursion works properly:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

CALL :fac %1
ECHO %RETURN%

:end
ENDLOCAL
GOTO :EOF

:fac
IF %1==0 (
        SET RETURN=1
        GOTO :EOF
)
SET /A TEMP=%1 – 1
CALL :fac %TEMP%
SET /A RETURN*=%1
GOTO :EOF

We need a temporary variable at the end, unfortunately, since cmd does not allow computations inline. But aside from that it looks pretty much how it should. The case for breaking the recursion is also provided in the form of an IF block (sorry, no functional programming niceties, like different function definitions).

But does it work? Oh, sure it does:

> fac 5
120
> fac 10
3628800

And my calculator tells me that those are actually correct. 12! is unfortunately the highest factorial we can compute with it, since we are limited to 32-bit signed integers. A minor bug is still present when using negative numbers, though (infinite recursion, again). This is corrected in the attached version (as well as giving a helpful hint when running the batch without arguments).

Just as a side note, a fun way to implement factorial calculation by leveraging cmd's own “calculator”:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET TEMP=1
FOR /L %%i IN (1,1,%1) DO SET TEMP=!TEMP! * %%i
SET /A TEMP=%TEMP%
ECHO %TEMP%
ENDLOCAL

We simply construct the complete term and evaluate that by using SET /A. Nothing fancy, but probably faster than the recursion.

Careful with those parentheses

Start with a fresh, minimal batch file:
@ECHO OFF
IF 1==1 (
        ECHO foo (bar) baz
) ELSE (
        ECHO gak
 )
Run it and enjoy the following error message: baz was unexpected at this time.

What happened here?

Well, look at the following code:
IF 1==1 (ECHO foo)
Where would you expect the ECHO command to end? Right, just before the closing paren. Let's rewrite that line:
IF 1==1 (
        ECHO foo
 )
Still looks nice. But what happens if you want to output a closing parenthesis (maybe for a smiley) inside an IF block?A straightforward idea of writing this would be
IF 1==1 (
        ECHO :-)
 )
Our experience with ECHO tells us that it prints the whole line, unless interrupted by things like & or >. And of course ECHO :-) works just fine from the command line. Put into an IF block, however, yields an error:
IF 1==1 (ECHO :-))
) was unexpected at this time.
And from here it's probably obvious what happened. The first closing parenthesis will end the IF block, kinda like the first */ will end a comment in C. Cmd's behavior here makes sense for single-line IFs but in my opinion it is a bit annoying when going multi-line.Now we know what to look for, it'd be nice to know how to prevent this in future. The first idea would be to move the interior of the block in a subroutine:
IF 1==1 CALL :SUB
GOTO :EOF
:SUB
ECHO :-)
GOTO :EOF
This works, but using a subroutine for a single line is not very nice (OK, may depend on how long the line is). Another option would be to put the closing parenthesis into an environment variable:
SET P=)
IF 1==1 (
        ECHO :-%P%
 )
Still not nice but at least it doesn't rip the code apart. The easiest way, however, would be to use escaping. The escape character in cmd is ^, so the code would look the following:
IF 1==1 (
        ECHO :-^)
 )
We just got our smiley a hooked nose.

Note, that if you have the parentheses in a variable (such as the 32-bit program files directory on x64 systems), then you need to either use delayed expansion or a subroutine (to avoid the parentheses).

Things to learn from this: The escape character is applicable anywhere in batch files. It causes every character to be recognized as not being part of the syntax.

Word line breaking going wrong?

Something weird occurred to me today. In German you can build compound words by joining them directly together (sometimes for clarity also with a hyphen): “Webseite” (web page) and “Web-Seite” are both examples of that. You can also refer to parts of compound words and reuse them in the same sentence with another compound word, this is always done with a hyphen: “Webseite und -auftritt” (web page and presence, short for web page and web presence).

That out of the way, my problem: The hyphen in the latter case belongs to the word it sticks to. So the following line breaking in Word 2007 kinda puzzles me:

Word 2007 line breaking

I have no idea why the hyphen moves to the previous line, it should be on the same line as “analyse”, right left to it. As you can see, there is no space or other character between hyphen and word.

My poor timetable, horribly disfigured :-(

Feedback

I ordered something last Monday and it got sent to me meanwhile. In the mail that said that the package is on its way I found the following sentence: “If you are satisfied with our service you can give us feedback here” followed by a few links. I always wonder what such feedback and evaluation systems are good for. Well, one benefit is obvious: Customers have a measurement for credibility of the seller. But is it worth bothering every single customer with evaluating the seller?

In my opinion all this is more a nuisance than pleasant. The rule for buying something should be that everything works out fine, so why do we need an explicit evaluation in that case? Angered customers tend to spend more time venting their displeasure, I think. But if I bought something and have no reason to complain I don't visit thee sites and give feedback, possibly writing some 500 characters every time. There is nothing to say, everything went off without a hitch – so what should I possibly write (e. g. Amazon forces to write a comment when giving feedback)? What could possibly be said against defaulting to “Both sides are pleased” and just using the feedback system in the case you were displeased?

I think the customer shouldn't be bothered more than necessary. And certainly unnecessary exercises should be avoided, especially if they do not directly relate to what you really want to do (buying stuff). I usually ignored such requests for feedback simply because I don't want to be bothered with it.

Sapir-Whorf for programming languages

The Sapir-Whorf hypothesis is an interesting concept in linguistics that basically states that the language(s) you speak affect the thoughts you are able to think and your understanding. Now I read an interesting connection to programming languages by Jeff Moser.

I never thought that this may apply to programming languages as well, but it seems reasonable. Paul Graham notes such a thing as The Blub Paradox where he explains that one's choice of programming language usually determines an opinion towards inferior ones (“How anyone can get anything done with it. It doesn't even have x (Blub feature of your choice)”) and towards more powerful ones (“He probably considers them about equivalent in power to Blub, but with all this other hairy stuff thrown in as well. Blub is good enough for him, because he thinks in Blub.”). Blub is the language the programmer thinks in and it inevitably determines his way of solving problems and judging other tools for solving them.

Probably that's the reason why we (CS students at Uni Rostock) were told that learning programming is not about mastery of one programming language, but rather solving problems in as many languages as possible. To prevent lock-in to one particular language and the thinking connected to it.

That said, I still won't learn Perl :-)

Usability Nightmares, Part 4

I still don't quite know what I should think of this:

A really weird hint for entering comments
First I only read the part that you should write your comments within 15 minutes (or paste them). That alone is sick enough. And yes, there is a  in the top of the page. I just wonder why. The site isn't as comment-heavy as Slashdot, Heise or other large IT sites so the benefit of seeing the latest comments (well, the ones that are at most 15 minutes old) isn't really that great and besides, that could be done without forcing the user into something he wouldn't need to do (Hint: there is this wonderfully hyped Web 2.0 thing called AJAX).

And the second part of the commenting hint is just downright ridiculous. Something on their side is seriously broken if they need that kind of hint. After digging a bit in the source code of that page it turns out that their comment-system is entirely Javascript, at least the validation part. The form points into void and the only thing that will submit something is probably the JS function AddComments() that is called on submit on that form. However, I lacked the motivation to actually look through that, given that I know nearly no Javascript.

Usability Nightmares, Part 3

Right now a new Firefox update appeared, apparently out of nowhere. So I started up Firefox and waited. And then, right when the Chrome appeared a dialog jumped into my face, hooray. Lesson No. 1 from the usability labs (read many times by now): Unexpected things in the user's view just cause him to get rid of the damn thing as soon as possible and they won't read it.

Anyway, where was I? Ah, right, the dialog that popped into my view:

Firefox Software Update

The fun thing starts right here, though. Who'd suspected that upon clicking “Later” (which should be pretty clear in meaning as in “Not now, I don't want to be bothered anymore. I'll restart Firefox sooner or later, rest assured.”) just another message box would appear, telling me something I really need to know that instant:

The really unexpected message box

Great. Thanks. If I actually would read that (which I did, yes) the “Later” button already took more time (and one more click) than simply updating. I really wonder whether this is really necessary.

And one more thing: The message box is of course a XUL-generated one, without one of the nicenesses that message boxes have on Windows: Pressing Ctrl-C did exactly nothing (normal message boxes put their contents in the clipboard upon hitting Ctrl-C).

And just to complement all that: The update didn't work. I suspect me running Windows as non-administrator might be the reason. Sigh. Haven't those people learned? I mean, Vista didn't just drop into the stores yesterday …

UPDATE (2008–03–27): The update didn't request administrative privileges (and thus failed) because the updater.exe program (used to install the update) fails to request it. They rely on Windows to detect that this is an installer-type application and do the magic for them. Definitely not the best way to do this. For completeness: Here's their manifest:

<?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?> Updater See a block in there? I don't. Hey Mozilla guys: Not everyone is an admin.

Flying droplets from carbonated drinks

I just filled another glass of Ginger Ale and first I put it far away from my laptop. The reason: The droplets that bounce out from the glass from sparkling are pretty hard to remove once they land on the display and dry up.

Droplets from sparkling over a glass

The question is, how high (and far) do these droplets fly? They are propelled by a bubble of carbon dioxide that rises to the surface and bursts. That should give us an upper bound of the energy that is available for flying around. Ich also wonder whether the height is affected by the filling level of the glass, i. e. the way a carbon dioxide bubble can/has to rise.

Is there probably an ideal filling level where you shouldn't worry about droplets landing on your display (or other hard to clean objects in the vicinity)? Does the flying height maybe follow a specific distribution function so you could specify a filling level where you have 99 % certainty that no droplet escapes the glassy confinement?

I think I have to think about that later again. The droplets actually move fast enough to leave trails in the above image, captured at 1/250 second (may not be visible since I resized it, though).

Usability Nightmares, Part 2

Pop up blocking is nowadays a pretty essential component of every major web browser. However, what about the pop ups the user actually wants to see? Internet Explorer is pretty ignorant about this, only offering the opportunity to turn off pop up blocking for the session or completely for the site:

Pop up blocking in Internet Explorer

So, to revisit a blocked pop up you have to repeat the action that lead to it, be it clicking on a link, let the page load or whatever.

Mozilla Firefox is nicer in this regard as it allows you to select a blocked pop up to open directly from a list. However, as URLs get longer and the first part stays the same, the user faces this:

Pop up blocking in Firefox

Try to figure out which pop up you want to see from the list at the bottom.

Currently I can't think of a viable solution, although thumbnails or titles would be great for the user (except he's on dial-up). But since both options involve downloading the page in background and wasting bandwidth that way it's probably not a great idea. But the current solution of being either ignorant or at times pretty unhelpful isn't that great either.

Maybe the whole issue settles down after pop ups become extinct (hey, I still have hope).

Cable compatibility

Talk about weird problems that can occur:

Windows Vista Problem Report: Problem caused by Firewire cable

I never knew there could be compatibility issues with cables …

Syndicate content