Wednesday, July 14, 2010

Windows Command Prompt Keeps Up with One Current Directory Per Drive

Or so it seems. This is copied from a console window on a machine running Windows Server 2003:
C:\Documents and Settings\jyoung>cd E:\InetPub\web sites

C:\Documents and Settings\jyoung>cd "E:\InetPub\web sites"

C:\Documents and Settings\jyoung>cd e:
E:\InetPub\web sites

C:\Documents and Settings\jyoung>e:

E:\InetPub\web sites>
Very strange. It seems that the command prompt keeps up with the “current directory” on a per-drive basis, so that when you cd to some drive that you’re not on, it changes the “current” directory for that drive rather than _the_ current directory. Then when you change drives, it remembers what drive you changed it to previously. I did not know that.

Oddly, using the /d flag is required to change directories across drives [reference].

Friday, June 25, 2010

Do your work, or throw an exception - example

The last post gave an illustration of a employee telling his manager if he cannot do his work as usual instead of requiring his manager to ask him if he will start doing what is expected of him every time she asks him to.

Below is a code example of this idea that I posted on StackOverflow:

class GoodEmployee {
void DoWork() {
if (CarIsInTheShop)
throw new CantDoWorkException();
else
_DoWork();
}
}

class BadEmployee {
bool DoWork() {
if (CarIsInTheShop)
return false;
else
{
_DoWork();
return true;
}
}
}


Imagine using each of these. Using GoodEmployee means that client code can operate as normal. Wherever appropriate, _if_ appropriate, a try/catch _may_ be used to properly handle the exception, if that is even possible. The most appropriate try/catch may be in place already in a form something like this:


// main loop:
while(!timeToQuit) {
try {
REPL(); // read eval print loop, for example
}
catch (TransientException e) {
TellUserHeCantDoThatRightNow(e);
}
}


Meanwhile, client code of GoodEmployee may look like this:


myGoodEmployee.DoWork();


Contrast this with proper usage of BadEmployee:


if (!myBadEmployee.DoWork) {
return false;
}
...
return true;


Not _so_ bad. But what if we call DoWork in lots of places? What if there are not 1 but many different methods like DoWork that have to be called? Worst of all, what if we want to have N layers of indirection that must exit when the employee cannot do his work? What if we apply this same pattern (return error codes instead of throwing an exception) to those methods? Then we have something like this:


A() {
if (!B())
return false;
// do some other work;
return true;
}

B() {
if (!C())
return false;
// do some other work;
return true;
}

C() {
if (!myEmployee.DoWork1())
return false;
if (!myEmployee.DoWork2())
return false;
if (!myEmployee.DoWork3())
return false;
// do some other stuff
return true;
}


YUCK!

I have worked on an application like this. Making any minor little changes to it is an absolute pain because it employs the above pattern throughout. Contrast that with otherwise comparable apps that throws exceptions and allows exceptions to be thrown--the latter group of apps not only have less code, cleaner code, and fewer bugs, they also have _more robust_ exception handling.

I hope these clearly examples show how exception-phobia and speculative catch blocks are destructive and literally multiply the amount of code you have to maintain, as well as hide and even introduce bugs.

Thursday, May 13, 2010

Do your work, or throw an exception

Imagine this: My car breaks down, and I cannot make it to work. Should I inform my boss that I will not do my work as usual, or wait until she asks me if I will come to work? Should she ask me every day if I will do my work as usual?

If there's something wrong with my car, should a light on the dashboard tell me, or should the engineers that designed it require me to check everything to make sure it is in working order every day before I start driving?

I think you would agree that, when something or someone does not behave as expected, a notification that he, she, or it did not do its job would be nice. In many cases, we have a right to expect this sort of behavior.

Likewise, every method you ever write should either do what it says it will do or throw an exception. E.g., myObj.Save() should either save myObj or should throw an exception. It should not return a value indicating if it was successful or not, as that would require client code to check for success.

If there are multiple occasions where you would catch an exception thrown by a method immediately in order to do something with it, then (and only then) you can create a tryDoSomething method, such as myObj.TrySave(), and use it where applicable. (Of course, catch only exceptions that you know are caused by specific things; let the exception go if it is due to a bug.) TryDoSomething() methods should be the exception, not the rule.

Friday, March 12, 2010

Dynamic and static typing are not entirely mutually exclusive

Most programming languages are classified as being statically typed or dynamically typed. I think of static and dynamic typing as features (which can be used together in a single language, if desired), and weak typing as lack of either.

Static typing is a feature where the compiler checks for type mismatch-related errors.

Dynamic typing is a feature where the compiled program checks types. The compiler is involved only in generating executable code that does the check at runtime. In this scenario, trying to call aPig.Quack() compiles, but throws an exception at runtime.

Weak typing is lack of type checking--e.g., calling aPig.Quack() will run with undefined behavior.

In this view, polymorphism is a dynamic typing feature that works well with statically-typed languages: The compiler may ensure that all aDuck really is a Duck, but the runtime environment will check to see what kind of Duck aDuck is--Mallard, WoodenDecoy, or something else--to know which implementation of the virtual method Quack() to call. Hence we have an example of static and dynamic typing working together.