# Pattern matching

**URL:** <https://www.ruby-forum.com/t/pattern-matching/85935>\
**Category:** Ruby\
**Created:** [February 17, 2007, 9:01pm UTC](https://www.ruby-forum.com/t/pattern-matching/85935 "2007-02-17T21:01:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [February 17, 2007, 9:01pm UTC](https://www.ruby-forum.com/t/pattern-matching/85935/1 "2007-02-17T21:01:14Z")

</div>

Hi!

I recently got engaged in a thread on comp.lang.functional about ML and  
Lisp. I posted some simple but efficient OCaml code that is difficult to  
translate into Lisp:

let rec ( +: ) f g = match f, g with  
| `Q n,`Q m -\> `Q (n +/ m) |`Q (Int 0), e | e, `Q (Int 0) -> e | f,`Add(g, h) -\> f +: g +: h  
| f, g -\> `Add(f, g)

let rec ( \*: ) f g = match f, g with  
| `Q n,`Q m -\> `Q (n */ m) |`Q (Int 0), e | e, `Q (Int 0) ->`Q (Int 0)  
| `Q (Int 1), e | e,`Q (Int 1) -\> e  
| f, `Mul(g, h) -> f *: g *: h | f, g ->`Mul(f, g)

let rec simplify = function  
| `Q _ |`Var \_ as e -\> e  
| `Add(f, g) -> simplify f +: simplify g |`Mul(f, g) -\> simplify f \*: simplify g;;

This code does some simple rearrangements of symbolic expressions to  
simplify them, e.g. 2+1\*x+0 -\> 2+x. It works with arbitrary-precision  
rational arithmetic.

Does Ruby have pattern matching? If so, what does the above look like in  
Ruby? If not, how else can you express this elegantly in Ruby?

Lisp doesn’t have pattern matching but Pascal Constanza wrote quite an  
elegant solution in Lisp using dynamic method dispatch:

(defstruct add x y)  
(defstruct mul x y)

(defgeneric simplify-add (x y)  
(:method ((x number) (y number)) (+ x y))  
(:method ((x (eql 0)) y) y)  
(:method (x (y (eql 0))) x)  
(:method (x (y add))  
(simplify-add (simplify-add x (add-x y)) (add-y y)))  
(:method (x y) (make-add :x x :y y)))

(defgeneric simplify-mul (x y)  
(:method ((x number) (y number)) (\* x y))  
(:method ((x (eql 0)) y) 0)  
(:method (x (y (eql 0))) 0)  
(:method ((x (eql 1)) y) y)  
(:method (x (y (eql 1))) x)  
(:method (x (y mul))  
(simplify-mul (simplify-mul x (mul-x y)) (mul-y y)))  
(:method (x y) (make-mul :x x :y y)))

(defgeneric simplify (exp)  
(:method (exp) exp)  
(:method ((exp add))  
(simplify-add (simplify (add-x exp)) (simplify (add-y exp))))  
(:method ((exp mul))  
(simplify-mul (simplify (mul-x exp)) (simplify (mul-y exp)))))

This has the advantage that Lisp optimises the above so that it is only  
10x  
slower than the OCaml. Unlike the OCaml, it can be extended and  
automatically reoptimised at run-time.

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [February 18, 2007, 11:11am UTC](https://www.ruby-forum.com/t/pattern-matching/85935/2 "2007-02-18T11:11:10Z")

</div>

On 17.02.2007 20:47, Jon H. wrote:

> let rec ( \*: ) f g = match f, g with
> 
> This code does some simple rearrangements of symbolic expressions to  
> simplify them, e.g. 2+1\*x+0 → 2+x. It works with arbitrary-precision  
> rational arithmetic.
> 
> Does Ruby have pattern matching? If so, what does the above look like in  
> Ruby? If not, how else can you express this elegantly in Ruby?

Not that I am aware of. Even a quick search on RAA doesn’t reveal  
anything: [http://raa.ruby-lang.org/search.rhtml?search=pattern](http://raa.ruby-lang.org/search.rhtml?search=pattern)

I guess the major issue here between Ruby and Lisp is that you do not  
have access to Ruby expressions natively the same way as you have in  
Lisp. There are no macros that integrate nicely with the language as  
Lisp macros do.

The Ruby solution would likely involve creating a parser for the  
expressions you want to simplify, then simplifying the syntax tree and  
outputting it again. For getting at the Ruby parse tree there are  
indeed libraries, so that parse should not be too hard. In any case I  
guess the solution will only be half as elegant as the other two you  
presented. 🙂

Side note: the feature that comes closest to pattern matching is the  
assignment grouping of expressions:

irb(main):014:0\> a,(b,(c,d),e)=1,[2,[3,4],5]  
=\> [1, [2, [3, 4], 5]]  
irb(main):015:0\> a  
=\> 1  
irb(main):016:0\> b  
=\> 2  
irb(main):017:0\> c  
=\> 3  
irb(main):018:0\> d  
=\> 4  
irb(main):019:0\> e  
=\> 5

> (:method (x (y add))  
> (simplify-mul (simplify-mul x (mul-x y)) (mul-y y)))  
> slower than the OCaml. Unlike the OCaml, it can be extended and  
> automatically reoptimised at run-time.

I have to admit that I am only familiar with very basic Lisp. But it  
does look elegant. 🙂

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [February 18, 2007, 12:28pm UTC](https://www.ruby-forum.com/t/pattern-matching/85935/3 "2007-02-18T12:28:18Z")

</div>

> > | f, g → `Add(f, g) | `Add(f, g) → simplify f +: simplify g  
> > | `Mul(f, g) → simplify f \*: simplify g;;
> > 
> > This code does some simple rearrangements of symbolic expressions to  
> > simplify them, e.g. 2+1\*x+0 → 2+x. It works with arbitrary-precision  
> > rational arithmetic.
> > 
> > Does Ruby have pattern matching? If so, what does the above look like in  
> > Ruby? If not, how else can you express this elegantly in Ruby?

I’ve showed kinda pattern matching for Ruby here:  
[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/224528](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/224528)

I’m now working on more full-fledged library (place for it, but no files  
still at [http://rubyforge.org/projects/pattern-match](http://rubyforge.org/projects/pattern-match)).

V.

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [February 21, 2007, 3:36am UTC](https://www.ruby-forum.com/t/pattern-matching/85935/4 "2007-02-21T03:36:40Z")

</div>

Phil T. wrote:

> check out this article on artima by Topher Cyl:  
> [artima - If It's Not Nailed Down, Steal It](http://www.artima.com/rubycs/articles/patterns_sexp_dsls.html)

Great article. Thanks. 🙂

---

<div class="post-metadata">

**Author:** ![jbhruby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/439d5e/32.png) [@jbhruby](https://www.ruby-forum.com/u/jbhruby)\
**Post date:** [February 21, 2007, 3:07am UTC](https://www.ruby-forum.com/t/pattern-matching/85935/5 "2007-02-21T03:07:35Z")

</div>

On 2/17/07, Jon H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> | f, `Add(g, h) -> f +: g +: h | `Q \_ | `Var _ as e -> e | `Add(f, g) → simplify f +: simplify g  
> | `Mul(f, g) → simplify f \*: simplify g;;
> 
> This code does some simple rearrangements of symbolic expressions to  
> simplify them, e.g. 2+1\*x+0 → 2+x. It works with arbitrary-precision  
> rational arithmetic.
> 
> Does Ruby have pattern matching? If so, what does the above look like in  
> Ruby? If not, how else can you express this elegantly in Ruby?

check out this article on artima by Topher Cyl:  
[http://www.artima.com/rubycs/articles/patterns\_sexp\_dsls.html](http://www.artima.com/rubycs/articles/patterns_sexp_dsls.html)

Phil
