Wednesday, December 17, 2008

Why Functional Programming Matters - Part I of ?

The title of this blog entry, "Why Functional Programming Matters" is the title of a paper that can be found online here. I was inspired to write about functional programming due to an article in the recent issue of Dr. Dobb's Journal. The title of the article is, "It's Time to Get Good at Functional Programming". Seeing the title of the article on the cover of my current issue made me smile.

My interest in functional programming began around 2001 when I was working as a J2EE developer (my title was engineer, but I'm not an engineer) and developing a somewhat complicated Palm based web-app. The complication stemmed from a screen that a user could reach through more than five different use cases (logic flows), and depending upon the outcome of their action there was something like seven exit flows.

My initial attempts at the logic for the application had a lot of if-then-else logic and was pretty ugly. I knew there had to be a better solution. I had used a finite-state-machine model when working in the C language a few years before and went down that path for a while. However, at the time, Java did not support function objects and the implementation seemed a little stilted. Upon further investigation I came upon the notion of a rules-based system used in Artificial Intelligence programming.

I implemented my rules-based system along the lines of Fusebox. That model has since been called a Front Controller pattern. My code was pretty straightforward and used the notion of a rule-set made up of rules, which were evaluated in order. Each rule evaluated to a binary decision and could set a flag to continue processing the rules or to exit based upon success or failure. An example ruleset is shown below:

// ---- Email Payment Rule Sets ----
if( page.equals("S"))
{
ruleSet.add(new Rule( new AlwaysTrue(),
new ClearPageData() ));

ruleSet.add( new Rule( new AlwaysTrue(),
new ClearHelpText() ));

ruleSet.add( new Rule( new UserPressedCancel(),
new ClearPageData() ));

ruleSet.add( new Rule( new UserPressedCancel(),
new Navigation("B") ));

ruleSet.add( new Rule( new AlwaysTrue(),
new StorePageData("S") ));

ruleSet.add( new Rule( new UserChoseNickName(),
new Navigation("T") ));

ruleSet.add( new Rule( new InvalidEmailAddress(),
new Navigation("ZE")) );

ruleSet.add( new Rule( new InvalidLastName(),
new Navigation("ZE")) );

ruleSet.add( new Rule( new AlwaysTrue(),
new GetEmailStatus() ));

ruleSet.add( new Rule( new LastActionFail(),
new Navigation("ZE") ));

ruleSet.add( new Rule( new LastNameEmailMissMatch(),
new Navigation("S1") ));

ruleSet.add( new Rule( new OnNickNameList(),
new Navigation("ZE")) );

ruleSet.add( new Rule( new AlwaysTrue(),
new Navigation("T") ));
}

Each rule consists of a 'condition' and an 'action', which were both a Java Interface and implemented for each condition and action. If a condition evaluated to true, then the action fired. Simple as that. While the paradigm is pretty simple and straightforward, there are numerous opportunities to improve the code. For example, each action in each rule above has a boolean function named, "shouldContinue" that accepts no parameters and is hard-coded. Looking at the above rule-set, it is not explicit when firing an action results in the exiting the rule-set.

Another obvious improvement would be to move the rule-sets to an external representation such as XML. That way a rule-set could be updated without re-compiling the app; perhaps without even restarting the app! While investigating using XML as an expression of the rule-sets, the XML I was generating began to look a lot like the (then) XML for configuring Struts. This similarity coupled with external pressures forced me to drop the notion of an external representation. NOTE: A few years later I had the opportunity to discuss this with a researcher from the (now former) Bell Labs in Murray Hill and his opinion was that external representations (also thought of as a mini-language) are not all that useful because invariably the program has to be recompiled to add new functionality to the external representation. Interesting viewpoint and probably true.

I used the model above in a later web-app implemented in PHP. This model has worked pretty well for me as a 'Front Controller'. This sequence of events is what led me to start looking into general AI programming for deeper answers on complicated programming logic... and AI led me to the notion of 'search' as a programming paradigm.

No comments:

Post a Comment