Personal opinion: Clojure’s advantages are that (1) you don’t need operator overloading and (2) you don’t need to remember the infix operator associativity table. No extra fuzz, just use functions with good names.
(1) Operator overloading. In math, you might want to define plus on your own datatype. In Java, you basically can’t touch the plus. In Python, you might have a better chance, but you’d still have to “extend standard plus semantics”. In Clojure, you can just provide your own math namespace, and do
(my.math/+ a b). Optionally, you could just import your own plus and avoid the default provided one.
(2) Some languages allow you to create your own operators. Haskell is one of them. But in Haskell, you have to keep the infix table in mind. Each infix operator has its precedence (higher precedence is “collected together first”) and fixity (whether
a + b + c = (a + b) + c (infixl) or
a + b + c = a + (b + c) (infixr)).
This can become really confusing. You get a bunch of operators where you need to know fixity and precedence. Then you create a super-smart, super-long epressions with a bunch of arrows.
Following is an example of how you can use it. First, we define two “plus-like” operators
$+$ (left-associative) and
$++$ (right-associative). Pay attention to how they combine in the REPL session.
Note: ClojureVerse syntax hightlighting didn’t seem to like Haskell, so I created a gist (same as source below).
-- source file
module Lib where
someFunc :: IO ()
someFunc = putStrLn "someFunc"
data Expr a =
| Plus (Expr a) (Expr a)
deriving (Show, Read)
-- shorthand for number, type constructor for Expr
n = Number
($++++$) :: Num a => a -> a -> a
a $++++$ b = a*a + b*b
($+$) :: Expr a -> Expr a -> Expr a
a $+$ b = Plus a b
infixl 6 $+$
($++$) :: Expr a -> Expr a -> Expr a
a $++$ b = Plus a b
infixr 6 $++$
-- Run this in a `ghci` or `stack ghci` -- this isn't really a file.
*Main> :load Lib
*Lib> n 10 $+$ n 20 $+$ n 30
Plus (Plus (Number 10) (Number 20)) (Number 30)
*Lib> n 10 $++$ n 20 $++$ n 30
Plus (Number 10) (Plus (Number 20) (Number 30))