Fabulous Adventures In Coding

Eric Lippert's Blog

Table Driven Programming

Table driven programming is a technique that can make some programs more readable and maintainable, but is often overlooked by script developers.

Let me give you an example.  Here's a fragment of a VBScript program that I ran into yesterday.  It's perfectly correct, but it could be a lot shorter.

Select Case wmiAce.AceType
Case 0
  OutFile.WriteLine "<ACE type=""Access Allowed"">"
Case 1
  OutFile.WriteLine "<ACE type=""Access Denied"">"
Case 2 
  OutFile.WriteLine "<ACE type=""Audit"">"
End Select
If 1048576 And wmiAce.AccessMask Then 
  OutFile.WriteLine "  <Perm>Synchronize</Perm>"
End If
If 524288 And wmiAce.AccessMask Then
  OutFile.WriteLine "  <Perm>Write Owner</Perm>"
End If

' [... thirty more lines just like that ...]

If 2 And wmiACE.AccessMask Then
 
OutFile.WriteLine "  <Perm>File Write Data</Perm>"
End If
If 1 And wmiACE.AccessMask Then
  OutFile.WriteLine "  <Perm>File Read Data</Perm>"
End If
OutFile.WriteLine "</ACE>"

There's nothing broken about this program, and it's perfectly straightforward.  But it is so redundant!  So repetitive!  It says the same thing over and over.  It has the same pattern again and again.  It just goes on and on with only minor changes on each line.

Ahem. All that redundancy is just plain tiring to the eye, and the potential for typos and other mistakes goes up as the program gets longer.  If I were writing this program, I'd write it like this:

AceType = Array("Access Allowed", "Access Denied", "Audit")
OutFile.WriteLine "<ACE type=""" & AceType(wmiAce.AceType & """>"

Access = Array("File Read Data", "File Write Data", [...] , "Synchronize")
For Flag = LBound(Access) To UBound(Access)
  If 2^Flag And wmiAce.AccessMask Then
    OutFile.WriteLine "  <Perm>" & Access(Flag) & "</Perm>"
  End If
Next
OutFile.WriteLine "</ACE>">

Which reduces a 51 line program to nine much more readable lines. 

Table driven programming is extremely powerful in JScript, because JScript supports sparse associative arrays and first class functions.  It's quite easy to define function tables in JScript.  For example:

function handleRead() { ... }
function handleWrite() { ... }  
// ... etc…

var handlers = new Array();
handlers["Read"] = handleRead;
handlers["Write"] = handleWrite;
// ... etc ...

// later:
var handler = handlers[userInput];
if (handler != null)
      handler();

Which is a lot more compact than the equivalent switch statement. 

Next time you build a really big conditional statement, ask yourself whether you could summarize all of the choices into a table.  It can make a program considerably more readable.

Published Tuesday, February 24, 2004 10:38 AM by Eric Lippert
Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Enjoy Every Sandwich said:

Take Outs: The Digital Doggy Bag of Blog Bits for 24 February 2004
February 24, 2004 9:12 PM
 

Trix said:

Speaking of arrays....

is the new Microsoft Scripting Engine (on Longhorn?) going to have better a better array implementation? The so-called dynamic array ReDim is just a joke. ok, I'm a little biased by the lovlieness of Perl's PUSH and POP (not to mention slicing), but it *works*.

I think that people would make much better use of arrays if they were easier to use!
February 24, 2004 8:13 PM
 

Eric Lippert said:

First off, there will be new scripting technology in Longhorn, but I have absolutely nothing to do with that. I don't know what the features will be, I don't know availability or schedules or anything. The old script team is not working on that project; we are all working on other language and programmng tools.

Second, I agree that arrays in VBScript are pretty 20th century. But as I have mentioned many times in my blog, JScript has sparse, associative object-based arrays rather similar to perl. You can push, pop, slice, sort, etc, a JScript array.

Third, in VBScript you can use the dictionary object as an associative array.

February 24, 2004 11:46 PM
 

Paul Bartlett said:

Note that push, pop, shift, unshift, and all you other friends (and mine) from Perl are only available in JScript as of version 5.6. It's a free download, so it's not a real issue, but it might have been confusing if correct code (must be correct 'cos Eric said so ;) did not work for you.
February 25, 2004 1:17 AM
 

Dan Shappir said:

The BeyondJS library makes extensive use of push, pop, shift, unshift, etc. Consequently, it provides an implementation of these functions for JavaScript versions that don't support them. For example:

if ( typeof(Array.prototype.pop) != "function" )
Array.prototype.pop = function() {
if ( this.length ) {
var item = this[this.length-1];
--this.length;
return item;
}
}

You can find BeyondJS at:
http://w3future.com/html/beyondJS/
February 25, 2004 8:22 AM
 

Alex Angelopoulos said:

This could make an interesting way to do state machines in script, especially using GetRef:

Dim a(2)
Set a(0) = GetRef("a0")
Set a(1) = GetRef("a1")
Set a(2) = GetRef("a2")

Sub a0
'...
End Sub

Sub a1
'...
End Sub

Sub a2
'...
End Sub
March 1, 2004 6:03 PM
 

Eric Lippert said:

State machines are an excellent example of a good use of table-driven programs. Even simple state machines.

On page 127 of Writing Solid Code, Steve Maguire gives an example that I quite like. He's got a method that does state cycles, either 0 1 0 1 0 1 or 2 3 4 2 3 4 2 3 4. Which would you rather read? Which one makes more sense?

return ((s<=1)?(s?0:1):(s==4)?2(s+1));

or

next[] = {1, 0, 3, 4, 2};
return next[s];

March 1, 2004 6:09 PM
 

JonYates's Random Writings said:

March 23, 2004 2:19 PM
 

Glenn Johnson said:

Why call it table driven programming? Why not array-driven programming? When I think of table driven programming, I think of the real thing: eDeveloper. http://www.magicsoftware.com/edeveloper

March 3, 2007 11:45 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit

About Eric Lippert

Eric Lippert is a senior developer on the Microsoft C# compiler team. Before that he worked on the framework of Visual Studio Tools For Office. Before that, he worked on the compilers, runtimes and tools for VBScript, JScript, Windows Script Host and other Microsoft Scripting technologies. He lives in Seattle and spends his free time editing books about programming languages, playing the piano, and trying to keep his tiny sailboat upright in Puget Sound.

This Blog

Syndication


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker