{"id":854,"date":"2009-08-24T11:43:58","date_gmt":"2009-08-24T09:43:58","guid":{"rendered":"http:\/\/www.navision-blog.de\/2009\/08\/24\/the-openclosed-principle-c-vs-f\/"},"modified":"2009-09-01T11:46:32","modified_gmt":"2009-09-01T09:46:32","slug":"the-openclosed-principle-c-vs-f","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2009\/08\/24\/the-openclosed-principle-c-vs-f\/","title":{"rendered":"SOLID Part I &#8211; The Open\/Closed-Principle &#8211; C# vs. F#"},"content":{"rendered":"<p>Friday I attended the <a href=\"http:\/\/dotnet-leipzig.de\/materialien\/net-bootcamp-entity-framework-nhibernate\/\">.NET BootCamp \u201cNHibernate vs. Entity Framework\u201d<\/a> in Leipzig and as always it was a pleasure for me being there. Afterwards I had a nice talk with my friend <a href=\"http:\/\/therightstuff.de\/\">Alexander Gro&#223;<\/a> about the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Open\/closed_principle\">Open\/Closed Principle<\/a>. I didn\u2019t really care about this principle before, but now I think it\u2019s really a nice idea:<\/p>\n<blockquote>\n<p>\u201cIn object-oriented programming, the <strong>open\/closed principle<\/strong> states &quot;software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification&quot;; that is, such an entity can allow its behaviour to be modified without altering its source code.\u201d<\/p>\n<p align=\"right\">[<a href=\"http:\/\/en.wikipedia.org\/wiki\/Open\/closed_principle\">Wikipedia<\/a>]<\/p>\n<\/blockquote>\n<p>If we follow this principle we get lot\u2019s of small and testable classes. I want to demonstrate this with a simple spam checker for mails.<\/p>\n<p>Let\u2019s say our mail class has only a sender, a recipient, a subject and the mail body:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">class<\/span> <span style=\"color: #2b91af\">EMail<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; public<\/span> <span style=\"color: blue\">string<\/span> Sender { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">string<\/span> Recipient { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">string<\/span> Subject { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">string<\/span> Body { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">set<\/span>; }<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> EMail(<span style=\"color: blue\">string<\/span> sender, <span style=\"color: blue\">string<\/span> recipient,<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">string <\/span>subject, <span style=\"color: blue\">string<\/span> body)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Sender = sender;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Recipient = recipient;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Subject = subject;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Body = body;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">enum<\/span> <span style=\"color: #2b91af\">SpamResult<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Spam,<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Ok,<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>Unknown<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<p style=\"margin: 0px\">\n<\/p><\/div>\n<p>Now we want to know if a mail is spam or not. Of course we need some rules and some kind of \u201crule checker\u201d to decide this. Here is a very na\u00efve implementation for this:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">class<\/span> <span style=\"color: #2b91af\">RuleChecker<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> CheckMail(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">var<\/span> result = TestRule1(mail);<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">if<\/span>(result != <span style=\"color: #2b91af\">SpamResult<\/span>.Unknown)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">return<\/span> result;<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span>result = TestRule2(mail);<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">if<\/span> (result != <span style=\"color: #2b91af\">SpamResult<\/span>.Unknown)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">return<\/span> result;<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: green\">\/\/ &#8230;<\/span><\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">return<\/span> <span style=\"color: #2b91af\">SpamResult<\/span>.Unknown;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">private<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> TestRule1(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: green\">\/\/ I don\u2019t care about the concrete rules <\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">private<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> TestRule2(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: green\">\/\/ I don\u2019t care about the concrete rules<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<\/p><\/div>\n<p>It is obvious that this implementation breaks the Open\/Closed Principle. Every time someone comes up with a new anti-spam rule or the rule priorities change I have to modify the code in CheckMail(). Another problem here is that I can\u2019t test CheckMail() isolated from the concrete rules.<\/p>\n<p>With the help of the Open\/Closed Principle our implementation could look like this:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\"><\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">interface<\/span> <span style=\"color: #2b91af\">ISpamRule<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: #2b91af\">SpamResult<\/span> CheckMail(<span style=\"color: #2b91af\">EMail<\/span> mail);<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">public<\/span> <span style=\"color: blue\">class<\/span> <span style=\"color: #2b91af\">RuleChecker<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">private<\/span> <span style=\"color: blue\">readonly<\/span> <span style=\"color: #2b91af\">IEnumerable<\/span>&lt;<span style=\"color: #2b91af\">ISpamRule<\/span>&gt; _rules;<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> RuleChecker(<span style=\"color: #2b91af\">IEnumerable<\/span>&lt;<span style=\"color: #2b91af\">ISpamRule<\/span>&gt; rules)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>&#160;&#160;&#160; _rules = rules;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> CheckMail(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">foreach<\/span> (<span style=\"color: blue\">var<\/span> rule <span style=\"color: blue\">in<\/span> _rules)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>&#160;&#160;&#160; {<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">var<\/span> result = rule.CheckMail(mail);<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">if<\/span> (result != <span style=\"color: #2b91af\">SpamResult<\/span>.Unknown)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">return<\/span> result;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>&#160;&#160;&#160; }<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">return<\/span> <span style=\"color: #2b91af\">SpamResult<\/span>.Unknown;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<\/p><\/div>\n<p>Now you could easily write isolated UnitTests for RuleChecker.CheckMail() and for every new rule.<\/p>\n<p>You get the your concrete RuleChecker by calling the constructor with a list of rules:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">class<\/span> <span style=\"color: #2b91af\">MyFirstRule<\/span> : <span style=\"color: #2b91af\">ISpamRule<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> CheckMail(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ I don&#8217;t care about this<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">class<\/span> <span style=\"color: #2b91af\">MySecondRule<\/span> : <span style=\"color: #2b91af\">ISpamRule<\/span><\/p>\n<p style=\"margin: 0px\">{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">public<\/span> <span style=\"color: #2b91af\">SpamResult<\/span> CheckMail(<span style=\"color: #2b91af\">EMail<\/span> mail)<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>{<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: green\">\/\/ I don&#8217;t care about this<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>}<\/p>\n<p style=\"margin: 0px\">}<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: green\">\/\/ &#8230;<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\"><\/span><\/p>\n<\/p><\/div>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\"><\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">var<\/span> ruleChecker =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span><span style=\"color: blue\">new<\/span> <span style=\"color: #2b91af\">RuleChecker<\/span>(<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">new<\/span> <span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">ISpamRule<\/span>&gt;<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; <\/span>&#160;&#160;&#160; {<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/span><span style=\"color: blue\">new<\/span> <span style=\"color: #2b91af\">MyFirstRule<\/span>(),<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new<\/span> <span style=\"color: #2b91af\">MySecondRule<\/span>(),<\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/ &#8230;<\/span><\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; });<\/p>\n<\/p><\/div>\n<p>Alex please correct me if I\u2019m wrong, but I think this is what you had in mind Friday.<\/p>\n<p>As stated before, we end up writing lot\u2019s of very small classes &#8211; mostly with only one (public) method. I think this is some kind of functional approach, the only question is how we glue our code entities together. Let\u2019s look at the corresponding F# implementation:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">type<\/span> EMail =<\/p>\n<p style=\"margin: 0px\">&#160; { Sender: string;<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; Recipient: string;<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; Subject: string;<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; Body: string}<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">type<\/span> SpamResult =<\/p>\n<p style=\"margin: 0px\">&#160; | Spam<\/p>\n<p style=\"margin: 0px\">&#160; | OK<\/p>\n<p style=\"margin: 0px\">&#160; | Unknown<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">let<\/span> checkMail rules (mail:EMail) =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160; let<\/span> <span style=\"color: blue\">rec<\/span> checkRule rules =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; match<\/span> rules <span style=\"color: blue\">with<\/span><\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; | rule::rest <span style=\"color: blue\">-&gt;<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160; match<\/span> rule mail <span style=\"color: blue\">with<\/span><\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160; | Unknown <span style=\"color: blue\">-&gt;<\/span> checkRule rest<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160; | _ <span style=\"color: blue\">as<\/span> other <span style=\"color: blue\">-&gt;<\/span> other<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; | [] \u2013<span style=\"color: blue\">&gt;<\/span> Unknown<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\">&#160; checkRule rules<\/p>\n<\/p><\/div>\n<p>The signature of checkMail is <strong>(EMail -&gt; SpamResult) list -&gt; EMail \u2013&gt; SpamResult<\/strong>, which means it takes a list of rules (as above the order is important) and a EMail and returns the SpamResult. In addition I exchanged the explicit foreach loop with a tail recursion to make it look more functional.<\/p>\n<p>If I want a concrete rule checker I could use <a href=\"http:\/\/www.navision-blog.de\/2009\/06\/17\/f-bootcamp-questions-and-answers-part-ii-currying\/\">partial application<\/a>:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">let<\/span> myFirstRule mail =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\">&#160; \/\/ I don&#8217;t care about this<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\"><\/span><\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">let<\/span> mySecondRule mail =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\">&#160; \/\/ I don&#8217;t care about this<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\"><\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\"><\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: green\">\/\/ val ruleChecker :&#160; (EMail \u2013&gt; SpamResult)<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">let<\/span> ruleChecker =<\/p>\n<p style=\"margin: 0px\">&#160; checkMail<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; [ myFirstRule;<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160; mySecondRule]<\/p>\n<\/p><\/div>\n<p>As you can see the F# implementation is nearly the same as the C# implementation, just without explicitly wrapping our public method in classes. If we would use Reflector we would see that the F# compiler is building the classes around our functions. One could say if we follow the Open\/Closed Principle we come to functional code or the other way around if we write functional code we automatically apply the Open\/Closed Principle. I think that\u2019s why I really didn\u2019t care about this before.<\/p>\n<h5>Appendix<\/h5>\n<p>After thinking about this implementation and the extra type hint (see mail:EMail) I came up with a slightly more generic implementation:<\/p>\n<div style=\"font-family: courier new; background: white; color: black; font-size: 10pt\">\n<p style=\"margin: 0px\"><span style=\"color: blue\"><\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">type<\/span> SpamResult =<\/p>\n<p style=\"margin: 0px\">&#160; | Spam<\/p>\n<p style=\"margin: 0px\">&#160; | OK<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\"><span style=\"color: blue\">let<\/span> checkRules rules element =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160; let<\/span> <span style=\"color: blue\">rec<\/span> checkRule rules =<\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160; match<\/span> rules <span style=\"color: blue\">with<\/span><\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; | rule::rest <span style=\"color: blue\">-&gt;<\/span><\/p>\n<p style=\"margin: 0px\"><span style=\"color: blue\">&#160;&#160;&#160;&#160;&#160; match<\/span> rule element <span style=\"color: blue\">with<\/span><\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160; | None <span style=\"color: blue\">-&gt;<\/span> checkRule rest<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160;&#160;&#160; | _ <span style=\"color: blue\">as<\/span> other <span style=\"color: blue\">-&gt;<\/span> other<\/p>\n<p style=\"margin: 0px\">&#160;&#160;&#160; | [] \u2013<span style=\"color: blue\">&gt;<\/span> None<\/p>\n<p style=\"margin: 0px\">&#160;<\/p>\n<p style=\"margin: 0px\">\n<p style=\"margin: 0px\">&#160; checkRule rules<\/p>\n<\/p><\/div>\n<p>Here I deleted the enum value for SpamResult.Unknown and used the standard None option. As a consequence the signature changed to:&#160; val checkRules : (&#8216;a -&gt; &#8216;b option) list -&gt; &#8216;a -&gt; &#8216;b option. The function still takes a list of rules and a element and returns a option value. Now the checkRules function works with every kind of rule result and takes arbitrary elements.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Friday I attended the .NET BootCamp \u201cNHibernate vs. Entity Framework\u201d in Leipzig and as always it was a pleasure for me being there. Afterwards I had a nice talk with my friend Alexander Gro&#223; about the Open\/Closed Principle. I didn\u2019t really care about this principle before, but now I think it\u2019s really a nice idea: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[12,23,448,6],"tags":[383,565,664,566,567],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/854"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=854"}],"version-history":[{"count":6,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/854\/revisions"}],"predecessor-version":[{"id":860,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/854\/revisions\/860"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=854"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}