About me

About me

Feeds

RSS feed

Haskell-like patterns in Lisp

27th January 2021

One of the nice features in Haskell is patterns, which provide an alternative to conditionals for expressing functions more elegantly.

For example, here's a recursive definition of factorial in Haskell using patterns:

fac :: Integer -> Integer
fac 0 = 1
fac n = n * fac (n - 1)

It's perhaps a pity that Lisp doesn't provide patterns as an option. But wait a minute, if we consider CLOS part of Common Lisp we can use it to write many problems in a pattern-like way, without conditionals, just like in Haskell. Here's an example:

(defmethod fac ((n (eql 0))) 1)

(defmethod fac (n) (* n (fac (1- n))))

Try it out:

> (fac 12)
479001600

Here's another example, from Learn Haskell Fast and Hard by Yann Esposito [1]:

Given a list of integers, return the sum of the even numbers in the list.

Here's a recursive definition in Haskell using patterns:

evenSum :: [Integer] -> Integer
evenSum [] = 0
evenSum lis = (if even (head lis) then head lis else 0) + evenSum (tail lis)

Again, here's the pattern-like way of doing it in Lisp:

(defmethod evensum ((lis null)) 0)

(defmethod evensum (lis)
  (+ (if (evenp (car lis)) (car lis) 0) (evensum (cdr lis))))

Try it out:

> (evensum '(0 1 2 3 4 5 6 7 8 9))
20

  1. ^ Learn Haskell Fast and Hard on yannesposito.com.

Previous: Shortest quicksort


blog comments powered by Disqus