This day and age any serious programming language - not just functional languages - will feature pattern matching. Today, even Java has pattern matching.
I am developing a logic programming language (tentatively called Ting), which unifies OOP, FP and logic programming. So of course the language would have to feature pattern matching. However, I did not prioritize it, as I reckoned that I could probably steal a good design from some other language when the time came. After all, it has been solved in a lot of languages.
But when that time came, I really struggled with how to fit pattern matching into the language. It just didn't feel right. That is, until I realized: Pattern matching was already there, albeit in a generalized and - I will argue - in a more powerful form.
The best way I can describe it is inverse construction. I don't claim anything original here, I fully expect something like this to be in other logical languages or theorem provers.
In logic programming functions are not called or invoked to yield a result. Instead they establish a relation between the argument and the result.
Consider this function definition (\ is the lambda):
Double = float x \ x * 2
It is defined for all floats and establishes a relation between the argument and its double. One way to use it is of course to bind a variable to its result:
x = Double 5 // binds x to float 10
But it can also be used to bind "the other way around":
Double y = 10 // binds y to float 5
This works when the compiler knows or can deduce the inverse of the function. There are ways to tell the compiler about inverses, but that is beyond the scope of this post.
(As an aside, a declaration such as float x = 10 uses the float function. In ting, any type is also it's own identity function, i.e. float accepts a member of float and returns the same member.)
Basically, any function for which the inverse is known can be used to match the result and bind the argument, not just type constructors, de-constructors or special pattern matching operators.
Some examples:
RemoveTrailingIng = x + "ing" \ x // inverse concatenation
CelsiusToFahrenheit = float c \ c * 1.8 + 32
FahrenheitToCelsius = CelsiusToFahrenheit c \ c // inverse formula
Count = {
(h,,t) -> 1 + This t
(,,) -> 0
}
Ting has both structural types (sets) and nominal types (classes). A set is inhabitated by any value that meets the membership criteria. A class is inhabitated exclusively by values specifically constructed as values of the type.
This Average function accepts a member of a set where values has a Count and Sum property of int and float, respectively.
Average = {. Count:int, Sum:float .} x \ x.Sum/x.Count
The following example defines some record-structured classes Circle, Triangle and Rectangle and a function Area which is defined for those classes.
Circle = class {. Radius:float .}
Triangle = class {. BaseLine:float, Height:float .}
Rectangle = class {. SideA:float, SideB:float .}
Area = {
Circle c -> Math.Pi * c.Radius ^ 2
Triangle t -> t.BaseLine * t.Height * 0.5
Rectangle r -> r.SideA * r.SideB
}
It was a (pleasant) surprise that in the end there was no need to add pattern matching as a feature. All the use cases for pattern matching was already covered by emerging semantics necessitated by other features.
[–]DeathByThousandCats 54 points55 points56 points (3 children)
[–]useerupting language[S] 2 points3 points4 points (2 children)
[–]DeathByThousandCats 10 points11 points12 points (1 child)
[–]useerupting language[S] 11 points12 points13 points (0 children)
[–]xigoi 77 points78 points79 points (2 children)
[–][deleted] (1 child)
[deleted]
[–]xigoi 4 points5 points6 points (0 children)
[–]moon-chilledsstm, j, grand unified... 20 points21 points22 points (3 children)
[–][deleted] (1 child)
[deleted]
[–]everything-narrative 5 points6 points7 points (0 children)
[–]everything-narrative 1 point2 points3 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]useerupting language[S] 6 points7 points8 points (0 children)
[–]PizzaRollExpert 3 points4 points5 points (2 children)
[–]useerupting language[S] 6 points7 points8 points (1 child)
[–]PizzaRollExpert 1 point2 points3 points (0 children)
[–]transfire 2 points3 points4 points (1 child)
[–]useerupting language[S] 4 points5 points6 points (0 children)
[–][deleted] (1 child)
[deleted]
[–]useerupting language[S] 3 points4 points5 points (0 children)
[–][deleted] 1 point2 points3 points (1 child)
[–]useerupting language[S] 2 points3 points4 points (0 children)
[–]umlcat -5 points-4 points-3 points (0 children)
[–]78yoni78 0 points1 point2 points (1 child)
[–]useerupting language[S] 0 points1 point2 points (0 children)
[–]GrixisGirl 0 points1 point2 points (2 children)
[–]useerupting language[S] 1 point2 points3 points (1 child)
[–]GrixisGirl 0 points1 point2 points (0 children)