<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.artinsoft.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Carlos Loría-Sáenz Blog : rules, pattern-matching</title><link>http://blogs.artinsoft.net/carlosloria/archive/tags/rules/pattern-matching/default.aspx</link><description>Tags: rules, pattern-matching</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>ADTs, OOP, rules and Pattern-matching (1)</title><link>http://blogs.artinsoft.net/carlosloria/archive/2008/06/06/adts-oop-rules-and-pattern-matching-1.aspx</link><pubDate>Sat, 07 Jun 2008 00:57:00 GMT</pubDate><guid isPermaLink="false">871fd81c-a111-489f-851d-e9637b8e2ce4:1625</guid><dc:creator>CarlosLoria</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.artinsoft.net/carlosloria/rsscomments.aspx?PostID=1625</wfw:commentRss><comments>http://blogs.artinsoft.net/carlosloria/archive/2008/06/06/adts-oop-rules-and-pattern-matching-1.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;Abstract (or algebraic) Data Types (&lt;b&gt;ADT&lt;/b&gt;s) are well-known modeling techniques for specification of data structures in an algebraic style. &lt;br /&gt;Such specifications result useful because they allow formal reasoning on Software at the specification level. That opens the possibility of automated verification and code generation for instance as we may find within the field of &lt;b&gt;program transformation&lt;/b&gt; (&lt;b&gt;refactoring&lt;/b&gt;, modernization, etc.).&amp;nbsp; However, ADTs are more naturally associated with a declarative programming languages (functional (FP) and logic programming (LP)) style than an object-oriented programming one (OOP).&amp;nbsp; A typical ADT for a tree data structure could be as follows using some hypothetical formalism (we simplify the model to keep things simple):&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;adt &lt;/b&gt;TreeADT&amp;lt;Data&amp;gt;{&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;import &lt;/b&gt;Integer, Boolean, String;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;signature&lt;/b&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;sort &lt;/b&gt;Tree;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;oper &lt;/b&gt;Empty : -&amp;gt; Tree;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;oper &lt;/b&gt;Node : Data, Tree, Tree|-&amp;gt; Tree;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;oper &lt;/b&gt;isEmpty, isNode : Tree-&amp;gt; Boolean;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;oper &lt;/b&gt;mirror : Tree -&amp;gt; Tree&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;&amp;nbsp;oper &lt;/b&gt;toString : -&amp;gt; String&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;semantics&lt;/b&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;isEmpty(Empty()) = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;isEmpty(Node(_,_,_)) = false;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;mirror(Empty()) = Empty()&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;mirror(Node(i, l, r)) = Node(i, mirror(r), mirror(l))&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;As we see in this example, ADTs strongly exploit the notion of rules and pattern-matching based programming as a concise way to specify requirements for functionality.&amp;nbsp; The signature part is the interface of the type (also called sort in this jargon) by means of operators; the semantics part indicates which equalities are invariant over operations for every implementation of this specification. Semantics allows recognizing some special kinds of operations. For instance, &lt;i&gt;Empty &lt;/i&gt;and &lt;i&gt;Node &lt;/i&gt;are free, in the sense that no equation reduces them. They are called &lt;b&gt;constructors&lt;/b&gt;. &lt;br /&gt;If we read equations from left to right, we can consider them declarations of functions where the formals are allowed to be complex structures. We also use wildcards (‘_’) to discard those parts of the parameters which are irrelevant in context. It is evident that a normal declaration without using patterns would probably require more code and consequently obscure the original intention expressed by the ADT. In general, we would need &lt;b&gt;destructors &lt;/b&gt;(getters), that is, functions to access ADT parts. Hence, operation mirror might look like as follows:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Tree mirror(Tree t){&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;if&lt;/b&gt;(t.isEmpty()) &lt;b&gt;return &lt;/b&gt;t;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;return new &lt;/b&gt;Node(&amp;nbsp; t.getInfo(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; t.getRight().mirror(),&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; t.getLeft().mirror() );&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;Thus, some clarity usually could get lost when generating code OOP from ADTs: among other things, because navigation (term destruction, decomposition) needs to be explicit in the implementation.&lt;br /&gt;&lt;br /&gt;Rules and pattern-matching has not yet been standard in main stream OOP languages with respect to processing general data objects.&amp;nbsp; It has been quite common the use of regular expressions over strings as well as pattern-matching over semi structured data especially querying and transforming XML data. Such processing tends to occur via APIs and external tools outside of the proper language. Hence, the need for rules does exist in very practical applications, thus, during the last years several proposals have been developed to extend OOP languages with rules and pattern-matching. Some interesting attempts to integrate ADTs with OOP which are worthy to mention are Tom (&lt;a href="http://tom.loria.fr/%20" title="TOM Home Page"&gt;http://tom.loria.fr/ &lt;/a&gt;) and Scala (&lt;a href="http://www.scala-lang.org/" title="Scala Home page"&gt;http://www.scala-lang.org/&lt;/a&gt; ). An interesting place to look at with quite illustrating comparative examples is &lt;a href="http://langexplr.blogspot.com/" title="Luis D Fallas Blog"&gt;http://langexplr.blogspot.com/&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;We will start in this blog a sequence of posts studying these two models of integration of rules, pattern-matching and OOP in some detail. We first start with a possible version of the ADT above using Scala. In this case the code generation has to be done manually by the implementer. But the language for modeling and implementing is the same which can be advantageous. Scala explicit support (generalized) ADTs, so we practically obtain a direct translation. &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;object &lt;/b&gt;TreeADT{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;trait &lt;/b&gt;Tree{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;def &lt;/b&gt;isEmpty:&lt;b&gt;boolean &lt;/b&gt;= false&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;override def &lt;/b&gt;toString() = &amp;quot;&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;def &lt;/b&gt;mirror : Tree = this &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;def &lt;/b&gt;height : int = 0&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;case class &lt;/b&gt;Node(info:Any, left:Tree, right:Tree)&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;extends &lt;/b&gt;Tree{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;override def &lt;/b&gt;toString() = &lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;(&amp;quot;+info+left.toString() + right.toString()+&amp;quot;)&amp;quot;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;object &lt;/b&gt;Empty &lt;b&gt;extends &lt;/b&gt;Tree{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;override def&lt;/b&gt; isEmpty = true&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;def &lt;/b&gt;isEmpty(t : Tree) : &lt;b&gt;boolean &lt;/b&gt;=&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t &lt;b&gt;match &lt;/b&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;case &lt;/b&gt;Empty =&amp;gt; true&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;case &lt;/b&gt;_ &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; =&amp;gt; false&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;def &lt;/b&gt;mirror(t : Tree):Tree =&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; t &lt;b&gt;match&lt;/b&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;case &lt;/b&gt;Empty&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt; t&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;case &lt;/b&gt;Node(i, l, r) =&amp;gt; Node(i,mirror(r), mirror(l))&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://blogs.artinsoft.net/aggbug.aspx?PostID=1625" width="1" height="1"&gt;</description><category domain="http://blogs.artinsoft.net/carlosloria/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://blogs.artinsoft.net/carlosloria/archive/tags/rules/default.aspx">rules</category><category domain="http://blogs.artinsoft.net/carlosloria/archive/tags/ADT/default.aspx">ADT</category><category domain="http://blogs.artinsoft.net/carlosloria/archive/tags/pattern-matching/default.aspx">pattern-matching</category></item></channel></rss>