Explicit dispatch: New type: A new constructor(s), must be made for the new data type, which will add the necessary fields and attach a new type tag. Each of the functions for the type will need to have a new condition line to check for the new type. New op: The new op will be written in an explicit dispatch style to process all of the preexisting types Data-directed style: New type: A new package will be written, complete with all the necessary functions to process the new type, they will then all be added to a new row in the table New op: Each existing package will have the op added to it, and will also add it to a new column in the table Message-passing style: New type: A new dispatch function will be created, with all of the lines which exist in functions of previous types New op: A new line is added into each of the dispatch functions of the preexisting types If new operations are often added, you may prefer the explicit dispatch style, since it involves only creating/modifying one place in the codebase. If new types are often added, you may instead prefer one of the other two styles, since here, an addition of a new type is done in one place in the code, while adding a new op requires changes in many places. That being said, the data-directed style has the extra advantage that it could (in principle) be written in a way that's more organized for adding new operations, since the table structure itself will work equally well in either case, and it's more of a matter of code organization.