The Artima Developer Community
Sponsored Link

Weblogs Forum
In Defense of Pattern Matching

35 replies on 3 pages. Most recent reply: Dec 7, 2012 2:27 AM by Oliver Plow

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 35 replies on 3 pages [ « | 1 2 3 ]
Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: pattern-matching is a bit low-level Posted: Jul 5, 2006 12:57 PM
Reply to this message Reply
Advertisement
@James Watson,

With the multiple dispatch demonstrated in the post above yours you can do what you want. The simplifier methods can be in any class and in any order. The methods can be added to at any time whilst the program is running by loading a class that contains more methods, i.e. referencing a new class, a class from another machine, etc.

damien morton

Posts: 15
Nickname: dmost
Registered: Jan, 2004

Re: In Defense of Pattern Matching Posted: Jul 6, 2006 3:59 AM
Reply to this message Reply
Very interesting stuff.

Ive been working on something similar myself, trying to leverage C# 3.0 features.

Unfortunately, it isnt possible to convert anonymous methods with statement blocks into expression trees, so the following sample wouldnt work with C# 3.0 as it stands.

Its a bit ugly, but heres a sample of how it might look:

Matcher match = new Matcher(
(int a, int b, int c) => Case(Foo(Bar(Baz(a,b,c),4,_))) >>
()=>{
Foo foo = new Foo();
for (int i = a; i < b; i += c)
foo.Add(new Bar(i));
return foo;
}),
(int a) => Case(Foo(Bar(Baz(a,_,_),_,7)))) >> ()=>Foo(a),
(Baz x) => Case(Foo(Bar(x),_,_))) >> ()=>x
);

Mauricio Noda

Posts: 1
Nickname: noda
Registered: Jul, 2006

Re: In Defense of Pattern Matching Posted: Jul 6, 2006 9:48 PM
Reply to this message Reply
<pre class="literal-block">
class Term
case class Num(n: int) extends Term
case class Var(name: String) extends Term
case class Mul(l: Term, r: Term) extends Term
case class Add(l: Term, r: Term) extends Term

def simplify(term: Term) = term match {
case Mul(Num(0), x) => Num(0)
case Mul(Num(1), x) => x
case _ => term
}
</pre>

Extensibility analysis:
If you add another subclass of Term, most patterns associated with Term will need another case and will break.
Poor extensibility.

Encapsulation analysis:
If class Num n field changes, it will affect constructor parameters and the simplify pattern will break.
If class Mul l field changes, it will affect constructor parameters and the simplify pattern will break.
If class Mul r field changes it will affect constructor parameters and the simplify pattern will break.
All other patterns associated with Term using Term subclasses constructors will break too.
If class Term changes everything will break. (an OO issue, not a pattern matching issue)
Poor encapsulation.


Alternative pure OO aproach using polymorphism and true delegation:
<pre class="literal-block">
public class Term {
Term simplify() {return this;}
Term simplifyMul(Mul mul) {return mul;}}

class Num extends Term {int n; Num(int n) {this.n = n;}
Term simplifyMul(Mul mul) {
if (n == 0) {return new Num(0);}
else if (n == 1) {return mul.getR();}
else {return mul;}}}

class Var extends Term {String name; Var(String name) {this.name = name;}}

class Mul extends Term {Term l; Term r; Mul(Term l, Term r) {this.l = l; this.r = r;}
Term getR() {return r;}
Term simplify() {return l.simplifyMul(this);}}

class Add extends Term {Term l; Term r; Add(Term l, Term r) {this.l = l; this.r = r;}}
</pre>

Extensibility analysis:
If you add another subclass of Term, coupling will be done through method overriding and won't break other classes.
Better extensibility.

Encapsulation analysis:
If class Mul r field changes it will break class Num, but thats it.
If class Term changes everything will break.
Encapsulation is not perfect here neither, but is a lot better than the pattern matching example.


The OO example was written in Java and so it has a lot more lines of code than the Scala example, but it is a Java issue, not an OO issue.

And NO, the Visitor pattern is not needed in this case, as it is not needed in most cases. Basic OO is enough most of the time.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: In Defense of Pattern Matching Posted: Jul 6, 2006 10:20 PM
Reply to this message Reply
@Mauricio Noda

> And NO, the Visitor pattern is not needed in this case, as
> it is not needed in most cases. Basic OO is enough most of
> the time.

But you have coded a visitor, if I rewrite:
Term simplify() { return l.simplifyMul( this ); }

As
Term simplify() { return l.accept( this ); }

You can see the visitor pattern, an accept with a this argument. The Term accepts a Mul visitor in the example.

But I agree with you that the Visitor formulation is quite good. Personally I prefer multiple dispatch to both, see my previous post.

Mark Grand

Posts: 1
Nickname: mgrand
Registered: Aug, 2009

Pattern matching is lower level than it needs to be Posted: Aug 1, 2009 8:17 AM
Reply to this message Reply
Scala pattern matching is based on static sequences of pattern constants. There is no good way to reuse sequences of patterns or to compute patterns.

In a dynamic & extensible system, it would be good to be able to drive navigation through a composable collection of computed patterns.

Oliver Plow

Posts: 3
Nickname: oliplow
Registered: Dec, 2012

Re: In Defense of Pattern Matching Posted: Dec 7, 2012 2:27 AM
Reply to this message Reply
> Pattern matching is much maligned by object-oriented
> programmers. I wonder why?

The reason is that some explanation is missing when pattern matching makes sense and when not. It seems like case classes make most sense when you have a finite number of possible cases defined in a simple hierarchy, much like an enumeration. The sample you make fits very well into this category. But when reading your article you get the impression that case classes are considered universal without limitations and the respective OO approach is not only redundant but also inferior.

If I develop a very sophisticated BTree, because I want to implement a database, I have no worries that the OO solution will give me the extensibility I need. I'm not sure here about case classes. I think somethink like this is what many OO programmers think when they read articles that say something like case classes are best. Some explanation is required what case classes are considered good for, pros and cons.

Flat View: This topic has 35 replies on 3 pages [ « | 1  2  3 ]
Topic: Five-minute Multimethods in Python Previous Topic   Next Topic Topic: Service Locator Pattern Revisited, Part 2

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use