This is just bad technical writing. He is unable or unwilling or simply too lazy to produce a single concrete real-world example of the object of his high praise. He says he has found applications ranging from real-time embedded systems to library loans, so how hard would it be for him to to give a simplified version of one of those applications as an example? Heck, I'll settle for a non-real-world example, as long as it's tangible and concrete.
Contrast this with Jonathan Edwards's presentation on schematic tables (a powerful generalization of state charts) which despite its somewhat academic feel makes a strong case to the reader by employing a significant non-trivial example--an example which is admittedly also elegantly solvable in a lazily evaluated language like Haskell, as I pointed out to Jonathan a while ago: http://alarmingdevelopment.org/?p=366
We are trying to build a system that describes pricing rules for a set of products. After thinking about it for a while we have decided to use a table driven approach for capturing business rules describing the pricng structure. The columns capture the various attributes of the products/order form such as the territory it's sold in, the currency of the order, etc. The results/actions for each rule capture the prices. We choose to implement it this way for precisely the reason mentioned in the article - we want our end users to maintain the rules.
I have built systems like this (ones that worked, not just the anti-pattern described in my other comment). One caveat with EVERY “end users maintain this” system is that workflow rules, tables, DSLs, and everything else they “maintain” is CODE. It may not look like code, but if it drives the behaviour of the system, is code.
I take the view that if it walks like code and talks like code, it must be subject to the same rules as code. It must be checked into version control where it can be diffed and reverted. It must be pushed through staging and production. It must be testable, preferably with some kind of declarative tests.
In one system, we built the DSL for rules AND a DSL for declaring test cases so the analysts could write new rules and write tests for them.
You may have the same approach, or not as you deem appropriate.
Boy have I been bitten by that one before. I've learned after some time that punting the logic into customer-controllable data doesn't absolve it of all the problems that traditional code has.
In one system, we built the DSL for rules AND a DSL for declaring test cases so the analysts could write new rules and write tests for them.
Can you elaborate on how your DSL looks? How does one structure it to be powerful enough to encapsulate logic and simple enough for analysts to use?
Is it just simplified mathematical expressions? Or something more elaborate?
> One caveat with EVERY “end users maintain this” system is that workflow rules, tables, DSLs, and everything else they “maintain” is CODE. It may not look like code, but if it drives the behaviour of the system, is code.
In some ways the problem is much worse than for plain old code written by plain old programmers. Once a problem has been analyzed and the structure of its solution has crystalized, table-driven code can often be the right way to factor out the messy ad-hoc business requirements--there's a cool war story about that in Programming Pearls. But just throwing tables at everything for the business analysts to sort out is almost certain to lead to a combinatorially explosive mess of case analyses that's wholly unmaintainable. As you'd know if you've dealt with end-user programming, whether in the form of tables or visual scripting, non-programmer power users are perfectly willing to crank out reams upon reams of case analysis code when left to their own devices.
I think the argument is that the end users wouldn't be able to manipulate the table in ways other than flipping bits, and that the system should be able to support any combination of bits.
In reality (and I think this is your point) the consequence is that just because a system can support a particular combination doesn't mean it makes any sense for the problem domain. Therefore by exposing this to users without tests, they can screw themselves over, even if the system continues to "work."
Fully agree. The rules have to be versioned and validated. In fact in our use case we have to go a step further and have another dimension to support validation - the notion of the phase/stage the rules are in: work-in-progress rules vs activated rules.
Thinking Forth by Leo Brodie has a good worked-out example of representing rule systems in various ways including several approaches that use tables. I think it's much better motivated than in the linked paper. Starting on page 52:
Hmm, I believe I've seen shades of this idea in Selenium's most basic test script format [1]. It isn't a decision table, per se, but it was designed to be as easy as possible for non-programmers to adjust. That said, I don't think table-driven programming is as widely useful as this author claims. Most of the testing engineers I know immediately moved away from Selenium script tables toward higher level constructs in JavaScript or Python. I don't think a table is great for expressing recursion or iteration.
I think tables can work great for expressing such concepts, but Sturgeon's Law applies here, too: almost all table-based systems do it badly. Subtext has no problem with recursion.
Very cool, I did not know that somebody had already gone and made a programming language like this. In watching the first ~10 minutes of the demo video [1] my thoughts were "Yes, this is a perfect example of where a table could be better than if/else," then when the warning indicators popped up at 5:50 "hmm, boolean algebra is still hard," and then at 7:30 with the demo of fibonacci/recursion "exploded expression trees that must be manipulated by mouse... let's go shopping."
But still, a lot of interesting thinking went into something like this, and it makes you wonder if it would be appropriate to "embed" a similar interface into an IDE for manipulating complex switch case/elseif chains.
I can give an anti-example of a table-driven system, although I am going to come right out and say that the table-driven aspect of this system has nothing to do with why it was such a problem. In reality, the project suffered from Conway’s Law: Its architecture was driven by the way in which management divided up the work of designing and implementing the system.
I've used decision tables before and I don't particularly like them. The only good use for them is if the end-user both understands the rules and has the ability to change them. Otherwise, you're just covering up a code smell (nested if-else blocks) with a different representation without fixing the underlying problem.
Contrast this with Jonathan Edwards's presentation on schematic tables (a powerful generalization of state charts) which despite its somewhat academic feel makes a strong case to the reader by employing a significant non-trivial example--an example which is admittedly also elegantly solvable in a lazily evaluated language like Haskell, as I pointed out to Jonathan a while ago: http://alarmingdevelopment.org/?p=366