Excellent and succinct article on the use of "Decision Tables". This is a fundamental technique in Software Development but is rarely taught/known nowadays.
Considering that defining functions by sets of pattern matched clauses is a thing in more and more languages, it's rarely known for some values of "rarely".
A key difference between pattern matching and decision tables is the intrinsic flexibility of the latter at the expense of simplicity the former provides. Whereas pattern matching most often encodes branching statically by what is explicitly encoded, decision tables allow for runtime branching based on workflow context.
Both have their strengths and weaknesses and, IMHO, the choice as to which to use is situational.
Another related technique which employs a bit of both of these approaches is the Visitor pattern[0].
If you don't need to codec through English there isn't much of a point. It's easy to work with ctrl-v'd spreadsheet formulas and hard to create a written narrative around them.
> If you don't need to code through English there isn't much of a point.
Disagree. The intent is to think through and write down the requirements unambiguously from problem domain so that it can be mapped easily to solution domain.
You've misquoted me, but I should have written it like CODEC.
I agree on intent, and probably agree on usefulness, but I think my point was more that this is an older process from a time before instant and direct communication. I see it as introducing a layer of thought that doesn't need to exist if I can just ask someone from the source domain to send me their notes and walk me through them. We're probably using the same data format by now.
Again, I'm not saying the method isn't useful or appropriate, just that you won't see it as often now thanks to easier communication.
> You've misquoted me, but I should have written it like CODEC.
My mistake, i thought you meant "code" where you wrote "codec".
> my point was more that this is an older process from a time before instant and direct communication. I see it as introducing a layer of thought that doesn't need to exist if I can just ask someone from the source domain to send me their notes and walk me through them.
Not quite true. No amount of instant/direct communication can help in removing ambiguity from "normal" Human communication. You need to have a method which enforces rigour and precision in the communication technique. That's what Decision Tables and other formal/mathematical methods help you with.
As a non-CS major who had encountered finite state machines in my early teens, it boggles my mind to consider that nowadays someone could successfully get through a CS curriculum without them.
(a trie ain't nothing but a degenerate state machine)
On second thought, this is a wonderful hypothesis, because it would explain so much about the modern software environment...
They are used extensively in embedded software. A device will be in one of several states - running, sleep, configuration, log download and so on. Each state is a C function (for me). I normally have entry/exit functions for each state too so that you set up/tear down the hardware needed for each.
As you add more states, you do not need to edit the existing states - well only the bits where you need to transition to the new state. This makes it much easier to maintain and reason about.
You've certainly used them, but been unaware of it.
Made a menu selection? State Machine.
Interacted with a dialogue box/an HTML form? State Machine.
Used a dropdown/popup suggestions list? State Machine.
Written async code? State Machine.
Used a VM? State Machine.
Used a compiled executable? State Machine.
Any time you don't have all the input available when you start (equivalently, can be interrupted by some other task) either you explicitly, or a tool on your behalf implicitly, will need to reach for a state machine. Even if all the input is in principle available, if it is too large for practical processing, piece-by-piece processing entails a state machine (however rudimentary).
"safety" (nothing bad ever happens) and "liveness" (something good eventually happens) are two key properties for systems, and they both have easy formalisations in state machine terms.
As others have pointed out, FSM's are very useful to formalize/organize behaviour in a stateful workflow. One domain where I think they shine is in implementing structured binary format decoders (such as multimedia streams).
Here is a brief introduction which may be of help:
As the other responder points out you use state machines everyday without knowing it.
A "State Machine" is a mathematical abstraction (i.e. a "computation" model) for the workings of a concrete machine i.e. A real Computer running a Program. When you start to write your programs as state machines you make its operations explicit, unambiguous and clear thus greatly reducing errors and guaranteeing "correctness". This is what makes it "essential".
I highly recommend studying Michael Sipser's Introduction to the Theory of Computation to understand this and other computation models (any edition will do).
So much of what passes for 'requirements gathering' in software development historically has consisted of precisely this kind of heuristic-collecting. Trying to come up with rigorous rules for, as here, 'when should we serve cocktails on planes', so we can build software that enshrines those rules, so that at some point, someone will be refused a cocktail under circumstances when one might help. Congratulations, software engineers. You made someone's day a little worse.
The goal of software engineering isn't to make rules lawyers that implement the same logic as staff do only with less imagination and discretion. That's just a shortcut to reducing staff numbers while making worse decisions and reducing service quality.
The goal of software engineering should be to make systems that can support making better decisions. The rules your staff use today to figure out what flights should serve cocktails are themselves policies that evolved in service of some broader business goal, taking into account behind the scenes information like service costs, customer satisfaction, competitive analysis, brand intentions, etc.
I think the article probably used a bad example. I think the intent was to pick an example that is easy to understand even for non-programmers - the rules behind serving cocktails on flights - rather than imply that this technique is intended for social rules that humans should follow.
If instead imagined to apply toward some of the complicated logic we regularly come across in actual computer programming, it starts to feel more useful. As programmers we've all come across cases of snarly boolean logic that nests multiple levels deep. In those cases, I've found decision trees very useful. I've taken it to the point of literally listing out every combination of conditions, rather than just the ones that seem to apply. Through that you can sometimes discover corner cases that need to be accounted for. Other times, you realize that you can collapse parts of the state so that your end-result conditional logic becomes much simpler. If you've ever had that case where you realized that your third-level internal condition could be moved to the outermost condition, thereby simplifying the code significantly, then that's what the exercise helps with.
The process of "requirements gathering" is by definition heuristic and iterative. The point of encoding it via "Decision Tables" (or any other technique) by a Domain Expert/Software Engineer is to be precise/rigorous so that it can be easily translated into computer code unambiguously.
The usage of the above will vary industry by industry depending upon their needs i.e. "Technical aspects" vs. "Social aspects". Thus a Nuclear Plant Manager/Aeroplane Pilot will be tightly confined within set bounds while Retail industry/Customer care will have a lot more leeway to consider the "Social aspects" involved. This can only be solved by "Human Resources Training" over and above Computer-aided support. The field of "Decision Support Systems" (https://en.wikipedia.org/wiki/Decision_support_system) is well established and supports a wide spectrum of both Computer and Human factors.
It amazes me that there is so little familiarity with Decision Tables. The greatest effort in software development or documenting processes isn’t coding; it’s the effort of covering every possible combination of circumstances – user input, database transaction, or any other events/rules – that the program/process will encounter. If any combination of inputs/events is overlooked, the program will function randomly, or the business process will be incomplete. Here's a couple of tutorial videos on an AI enabled Decision Table Processor, LogicGem. It shows how to build a table representing your Program Logic or Business Rules and then how it can find any missing, redundant, contradictory or ambiguous rules and then automatically fix them. It then shows how it generates documentation in English, French, Spanish and German and even generates source code of the validated and complete set of rules in 25 different programming languages for inserting in your application. Check them out at https://youtube.com/@logicgem
> It amazes me that there is so little familiarity with Decision Tables.
They are just another language, overtly verbose, with no opportunity for a clean presentation of your ideas, that convey the exact same information you encode on your code, and isn't any more clear to laypeople than code.
That stuff has some utility in a place or another, but if you are really thinking about making people fill one up, you should look into letting those people use a real programing language.
Not quite so simple. Computer Programming involves a lot of state management, book keeping and various other intricacies which many don't want/learn to do. A person trying to solve his problem should only focus on his problem domain concepts, their relationships and means of expressing them directly. That is why DSLs are a thing. A decision table is such a natural, simple and yet powerful way to model requirements that anybody can learn to do this by themselves.
If "smart contracts" were decision tables, there would be much less trouble from them. Decision tables are exhaustively testable. But no, they had to be Turing-complete.
Excellent and succinct article on the use of "Decision Tables". This is a fundamental technique in Software Development but is rarely taught/known nowadays.
See also :
1) Hillel Wayne - https://www.hillelwayne.com/post/decision-tables/ and https://www.hillelwayne.com/post/decision-table-patterns/
2) Parnas Tables : A Practical Formalism (pdf) - https://cs.uwaterloo.ca/~jmatlee/Talks/Parnas01.pdf
3) Tabular Expressions and their Relational Semantics (pdf) - http://www.cas.mcmaster.ca/~wassyng/FIJanWas.pdf
Considering that defining functions by sets of pattern matched clauses is a thing in more and more languages, it's rarely known for some values of "rarely".
The article is not just about using decision tables at the code level but as a design methodology right from requirements stage.
A key difference between pattern matching and decision tables is the intrinsic flexibility of the latter at the expense of simplicity the former provides. Whereas pattern matching most often encodes branching statically by what is explicitly encoded, decision tables allow for runtime branching based on workflow context.
Both have their strengths and weaknesses and, IMHO, the choice as to which to use is situational.
Another related technique which employs a bit of both of these approaches is the Visitor pattern[0].
0 - https://en.wikipedia.org/wiki/Visitor_pattern
> but is rarely taught/known nowadays
If you don't need to codec through English there isn't much of a point. It's easy to work with ctrl-v'd spreadsheet formulas and hard to create a written narrative around them.
> If you don't need to code through English there isn't much of a point.
Disagree. The intent is to think through and write down the requirements unambiguously from problem domain so that it can be mapped easily to solution domain.
You've misquoted me, but I should have written it like CODEC.
I agree on intent, and probably agree on usefulness, but I think my point was more that this is an older process from a time before instant and direct communication. I see it as introducing a layer of thought that doesn't need to exist if I can just ask someone from the source domain to send me their notes and walk me through them. We're probably using the same data format by now.
Again, I'm not saying the method isn't useful or appropriate, just that you won't see it as often now thanks to easier communication.
> You've misquoted me, but I should have written it like CODEC.
My mistake, i thought you meant "code" where you wrote "codec".
> my point was more that this is an older process from a time before instant and direct communication. I see it as introducing a layer of thought that doesn't need to exist if I can just ask someone from the source domain to send me their notes and walk me through them.
Not quite true. No amount of instant/direct communication can help in removing ambiguity from "normal" Human communication. You need to have a method which enforces rigour and precision in the communication technique. That's what Decision Tables and other formal/mathematical methods help you with.
And "Decision Tables" often lead one into the wonderful world of Finite State Machines[0], another fundamental concept "rarely taught/known nowadays."
The applicability of both in many problem domains remains a source of pleasant surprise to me to this day.
0 - https://en.wikipedia.org/wiki/Finite-state_machine
As a non-CS major who had encountered finite state machines in my early teens, it boggles my mind to consider that nowadays someone could successfully get through a CS curriculum without them.
(a trie ain't nothing but a degenerate state machine)
On second thought, this is a wonderful hypothesis, because it would explain so much about the modern software environment...
What makes them essential? Never have I encountered them
They are the Turing Machine without the (infinite) tape. What is your favourite abstraction of computer?
About 100kb of carefully crafted yaml configs
They are used extensively in embedded software. A device will be in one of several states - running, sleep, configuration, log download and so on. Each state is a C function (for me). I normally have entry/exit functions for each state too so that you set up/tear down the hardware needed for each.
As you add more states, you do not need to edit the existing states - well only the bits where you need to transition to the new state. This makes it much easier to maintain and reason about.
Each subsystem can be its own state machine too.
You've certainly used them, but been unaware of it.
Any time you don't have all the input available when you start (equivalently, can be interrupted by some other task) either you explicitly, or a tool on your behalf implicitly, will need to reach for a state machine. Even if all the input is in principle available, if it is too large for practical processing, piece-by-piece processing entails a state machine (however rudimentary).
https://lamport.azurewebsites.net/pubs/state-machine.pdf
"safety" (nothing bad ever happens) and "liveness" (something good eventually happens) are two key properties for systems, and they both have easy formalisations in state machine terms.
As others have pointed out, FSM's are very useful to formalize/organize behaviour in a stateful workflow. One domain where I think they shine is in implementing structured binary format decoders (such as multimedia streams).
Here is a brief introduction which may be of help:
https://www.cs.princeton.edu/courses/archive/spr06/cos116/FS...
As the other responder points out you use state machines everyday without knowing it.
A "State Machine" is a mathematical abstraction (i.e. a "computation" model) for the workings of a concrete machine i.e. A real Computer running a Program. When you start to write your programs as state machines you make its operations explicit, unambiguous and clear thus greatly reducing errors and guaranteeing "correctness". This is what makes it "essential".
I highly recommend studying Michael Sipser's Introduction to the Theory of Computation to understand this and other computation models (any edition will do).
So much of what passes for 'requirements gathering' in software development historically has consisted of precisely this kind of heuristic-collecting. Trying to come up with rigorous rules for, as here, 'when should we serve cocktails on planes', so we can build software that enshrines those rules, so that at some point, someone will be refused a cocktail under circumstances when one might help. Congratulations, software engineers. You made someone's day a little worse.
The goal of software engineering isn't to make rules lawyers that implement the same logic as staff do only with less imagination and discretion. That's just a shortcut to reducing staff numbers while making worse decisions and reducing service quality.
The goal of software engineering should be to make systems that can support making better decisions. The rules your staff use today to figure out what flights should serve cocktails are themselves policies that evolved in service of some broader business goal, taking into account behind the scenes information like service costs, customer satisfaction, competitive analysis, brand intentions, etc.
Build software that supports that process.
I think the article probably used a bad example. I think the intent was to pick an example that is easy to understand even for non-programmers - the rules behind serving cocktails on flights - rather than imply that this technique is intended for social rules that humans should follow.
If instead imagined to apply toward some of the complicated logic we regularly come across in actual computer programming, it starts to feel more useful. As programmers we've all come across cases of snarly boolean logic that nests multiple levels deep. In those cases, I've found decision trees very useful. I've taken it to the point of literally listing out every combination of conditions, rather than just the ones that seem to apply. Through that you can sometimes discover corner cases that need to be accounted for. Other times, you realize that you can collapse parts of the state so that your end-result conditional logic becomes much simpler. If you've ever had that case where you realized that your third-level internal condition could be moved to the outermost condition, thereby simplifying the code significantly, then that's what the exercise helps with.
I am not sure i understand your argument.
The process of "requirements gathering" is by definition heuristic and iterative. The point of encoding it via "Decision Tables" (or any other technique) by a Domain Expert/Software Engineer is to be precise/rigorous so that it can be easily translated into computer code unambiguously.
The usage of the above will vary industry by industry depending upon their needs i.e. "Technical aspects" vs. "Social aspects". Thus a Nuclear Plant Manager/Aeroplane Pilot will be tightly confined within set bounds while Retail industry/Customer care will have a lot more leeway to consider the "Social aspects" involved. This can only be solved by "Human Resources Training" over and above Computer-aided support. The field of "Decision Support Systems" (https://en.wikipedia.org/wiki/Decision_support_system) is well established and supports a wide spectrum of both Computer and Human factors.
It amazes me that there is so little familiarity with Decision Tables. The greatest effort in software development or documenting processes isn’t coding; it’s the effort of covering every possible combination of circumstances – user input, database transaction, or any other events/rules – that the program/process will encounter. If any combination of inputs/events is overlooked, the program will function randomly, or the business process will be incomplete. Here's a couple of tutorial videos on an AI enabled Decision Table Processor, LogicGem. It shows how to build a table representing your Program Logic or Business Rules and then how it can find any missing, redundant, contradictory or ambiguous rules and then automatically fix them. It then shows how it generates documentation in English, French, Spanish and German and even generates source code of the validated and complete set of rules in 25 different programming languages for inserting in your application. Check them out at https://youtube.com/@logicgem
> 32. Programmers are not to be measured by their ingenuity and their logic but by the completeness of their case analysis. — AJP
> It amazes me that there is so little familiarity with Decision Tables.
They are just another language, overtly verbose, with no opportunity for a clean presentation of your ideas, that convey the exact same information you encode on your code, and isn't any more clear to laypeople than code.
That stuff has some utility in a place or another, but if you are really thinking about making people fill one up, you should look into letting those people use a real programing language.
Not quite so simple. Computer Programming involves a lot of state management, book keeping and various other intricacies which many don't want/learn to do. A person trying to solve his problem should only focus on his problem domain concepts, their relationships and means of expressing them directly. That is why DSLs are a thing. A decision table is such a natural, simple and yet powerful way to model requirements that anybody can learn to do this by themselves.
If "smart contracts" were decision tables, there would be much less trouble from them. Decision tables are exhaustively testable. But no, they had to be Turing-complete.
Decision Tables are great. If they get too hairy, consider a suitable rules engine or bpmn.