Switch Case List Versus Hof

Using a Switch/Case List Versus HigherOrderFunctions

Continued from CustomBusinessApplicationDefinition.

Use a CASE list instead, as described. You imply case lists are somehow fragile. They are not unless you are Michael J. Fox without his meds. I doubt there is a need to keep adding yet more functions because the managers have to understand what the algorithms are, and they are not going to want 30 different scheduling algorithms. The work world doesn't work that way. They'll settle a few they are comfortable with and almost rarely add a new one. (There may be parameter/setting variations, but this is not part of [affected by] your pattern.) Thus, your "mass new HOF factory" is likely a myth. You are exaggerating a certain change pattern. It's as unrealistic as your sort comparer HOF injecter. It's a nice "lab toy" example, but doesn't fit real world change patterns. If you claim 30 is realistic, then describe all 30 of them to prove it! Otherwise I call "hogwash". -t

CASE lists are fragile because they require modifying the algorithm code every time a new implementation of the algorithm is needed. Only one algorithm implementation may be needed per application, but there may be many applications that use the same algorithm. That could practically mean recompiling a DLL or library for each new application that uses the DLL or library. Is that reasonable? The same applies to the canonical C/C++ sort() implementation. Should we have to recompile the C standard library for each application that needs sort()? As for parameter/setting variations, that is covered in my example on HofPattern. See the part that starts, "Now what if we need to customise based on some dynamic data, i.e., we require a data-dependent series of customisations?

I doubt there is a realistic biz situation where a developer is adding a new algorithm once a month or more. Like I said, most of the algorithms, such as the employee shift scheduling, are usually vetted and selected and chosen by management or the customer in the design process and are relatively stable there after. I doubt more than two new algorithms will be requested in an entire decade, and probably it would average around 1.0. So adding a new "look-up" line (function call) to the CASE list twice a decade is a big deal? I sounds like a ridiculous complaint to me.

It's not about adding a new algorithm. It's about adding a new implementation, i.e., a new application, of an existing algorithm. If you only need employee scheduling once, my argument for HOFs is inapplicable. You won't even need a "CASE list". However...

What if you maintain one employee scheduling application so the secretaries can resource meeting rooms, and another so the researchers can book access to the fume hoods in the labs, and another for the warehouse team so they can arrange extra cover for oversize loads? What if you develop a reputation for employee scheduling and become a "profit centre" selling your employee scheduling to two of your company's clients? Now you've got five applications that use the same basic scheduling algorithm, four of them use different SQL DBMSs with different schemas and the fifth uses a NoSql database. Do you really want to embed case statements -- one case per application -- in the same algorithm? Do you really want to maintain linkage to every application in the algorithm's source code? Do you really want to risk breaking the algorithm for everyone when one application changes?

Or, would you rather inject one HOF per application into the algorithm, and possibly never again have to look into the scheduling algorithm's source code, whilst you maintain entirely independent applications that use the algorithm and trivially support the "parameter/setting variations" you mentioned?

For me, it was an easy decision -- this was inspired by a real situation -- the HOF approach won.

      // Example: Bertha-63
      Set Processing Setup Screen
      Employee set: Foo7  [*Select or create a different set*]
      Please select scheduling algorithm to use for this set
      [Astar-Search     |v]      // pulldown list
As far as sorting and compiling, that's a language-specific issue. Static languages are going to be pickier about new stuff than dynamic ones and there are many diff strategies a language can take. Usually such a change would accompany other changes anyhow, such as a new screen with the parameters/settings for the new algorithm usage or sub-instance (at least in the emp. scheduler app). Thus, recompilation would likely be needed anyhow.

If the basic algorithm is designed properly, it will never need recompilation. C/C++'s qsort() function is used in thousands of applications, on all the canonical data types and hundreds of custom types and data structures, and it never needs recompilation. More complex algorithms used in business -- like employee scheduling, logistics routing, costing, financial calculations of all kinds, etc. -- can use exactly the same HofPattern.

Long or frequently-changing switch/case lists are usually a sign that the application is designed wrong, most commonly that something should be put into the database or a config list instead of hard-coded. Non-trivial feature additions usually "touch" many other aspects and parts of the application, and one cannot know which they will touch in advance because each change request is different. Things just don't grow in the plug-and-play-a-HOF HofPattern kind of way in the real biz world (unless you are doing something really wrong). Of course, you can prove me wrong by producing actual or realistic HOF "lists". It looks to me like yet another case of a snazzy lab toy choking on reality, like those OOP shape & animal examples that used to trick naive IT managers into producing really goofed-up OOP apps by forcing everything into a tree taxonomy (until GOF came along with even screwier OO patterns to "fix" the trees).

Yes, long or frequently-changing switch/case lists are bad. HOFs make it possible to avoid this problem, as I described above. Also see above for a realistic example which is based on suitably-anonymised actual business events.

Usually you don't have 30 very different "algorithms", but rather start to see commonality among algorithms such that it starts to resemble example "Pete-82" shown in HofPattern. It's then re-factored for the various sub-features to be triggered from configuration "switches" in ControlTables that are maintained by users or power-users (usually via GUI/CRUD screens in mature apps). This is how most biz "algorithms" grow in my experience, not "straight out" as you seem to assume or pretend. They grow "wide" as much as they grow "tall".

Maybe you are just a poor algorithm factorer, or somehow end up serving the role of "power user" instead of let an actual power user control the sub-features (stored in the database). It may be possible to control such sub-features by using combinations of HOF's, but that's not the proper way to design biz software unless job-security is the primary goal and you want to put power-users out of a job so that you are paid instead of PU.

It's been pointed out very clearly above that there aren't "30 very different 'algorithms'". This has all been discussed in detail and at great length in HofPattern.

(Complaints about writing style have been moved to HomelessContent, and some of the wording of the above has been adjusted in an attempt to compensate for the removed content. If I accidentally altered the meaning, my apologies.)

In HofPattern, you seem to dismiss the Pete-82 pattern as "data-driven", "reports only", and "non-algorithm-oriented" (paraphrased). In other words, if the programmer is controlling the sub-features via combo's of HOF's, then it's "high level algorithms"; but if a power user is controlling it via feature screens or ControlTable(s), then it's "grunt data-driven stuff" (paraphrased). Please review and clarify your stance.

I see no problem with HOFs internally executing scripts or other direct-able content defined by power users. I see no problem with power users writing scripts that use HOFs. I know power users who happily write sophisticated Javascript. At some point, the distinction between programmer and power user isn't distinguishable.

There you appear to be at first suggesting that one use combo's of functions and/or HOF's to make use of or share the commonality of the algorithms in the "list". (See where you stated, "and compose functionality as and where needed from behaviourCommonToAll(), blah(), moof(), znig(), grob(), and fibble()") However, what I am proposing is that you make it possible for power-users to control the switching on/off and/or the order of these sub-parts rather than a programmer. Your group of functions is essentially a DomainSpecificLanguage. I'm simply moving the business of re-composing of those sub-elements to the power user instead of the programmer (this "config" is stored in the DB). It's not "less algorithmic" or "less ComputerScience", it's just differently algorithm-atized.

I don't see how providing scripting to end users changes anything.

See above regarding level of "power user".

Note that C-style switch/case statements are unnecessarily complicated and fragile. See IsBreakStatementArchaic.



EditText of this page (last edited March 18, 2013) or FindPage with title or text search