views:

81

answers:

3

Mostly out of curiosity: Which languages that are not solely functional (I'm also interested in multi-paradigm languages - I know that Ocaml and F# are ML dialects with OO added, so they inherit the algebraic data types from ML) have algebraic data types (or something similar) and pattern matching?

They can be kind-of emulated using enums and unions (as in C, C++, ...more?) but this soon gets cumbersome and ugly, and the compiler can't warn you if you forget a case in your pattern matching or (much more propable, and much more dangerous) when accessing the union "in wrong ways", i.e. you ask for a field of a Left value when it's actually a Right value (what you get then is a meaningless reinterpretation of the bits that happen to be there).

I've heard that Pascal has something like tagged unions (link) and the Cyclone language supports tagged unions, too. Wikipedia also mentions Ada and Algol. Any other languages?

(In case you never heard of algebraic data types, you can read the accepted answer of "What is 'Pattern Matching' in functional languages?" for an excellent introduction)

A: 

Erlang has a dynamic type system, so it doesn't provide any of the guarantees you cite, but Erlang code does tend to look like the product of an algebraic type system:

count([]) -> 0;
count([H|T]) -> 1 + count(T).

length({rect, X, Y}) -> math:sqrt(X*X + Y*Y);
length({polar, R, _A}) -> R.
Marcelo Cantos
+2  A: 

The logic programming language Mercury calls them discriminated unions. The constraint language CHR, embedded in Prolog, has them too, but there they are entirely optional, general Prolog terms being the default type.

larsmans
Thanks - I have no idea of logic languages, so I propably wouldn't have learned this myself.
delnan
Both are research languages. The LP community has been borrowing a lot from its FP cousins.
larsmans
+3  A: 

In Scala, you'd usually use case classes to emulate the algebraic data types as found in true-blue functional languages like ML and Haskell.

For example, following F# code (taken from here):

type Shape =
| Circle of float
| EquilateralTriangle of double
| Square of double
| Rectangle of double * double

let area myShape =
    match myShape with
    | Circle radius -> Math.PI * radius * radius
    | EquilateralTriangle s -> (sqrt 3.0) / 4.0 * s * s
    | Square s -> s * s
    | Rectangle (h, w) -> h * w

can be roughly translated to Scala as follows:

sealed abstract class Shape
case class Circle(radius: Float) extends Shape
case class EquilateralTriangle(side: Double) extends Shape
case class Square(side: Double) extends Shape
case class Rectangle(height: Double, width: Double) extends Shape

def area(myShape: Shape) = myShape match {
  case Circle(radius) => math.Pi * radius * radius
  case EquilateralTriangle(s) => math.sqrt(3.0) / 4.0 * s * s
  case Square(s) => s * s
  case Rectangle(h, w) => h * w
}

The sealed keyword above is used to have the compiler warn you in case you forget any case in the match expression.

missingfaktor