Which programming languages support operators as first class citizens? eg: Return an operator (+, -, =, ==, etc.) from a function, or store within a variable.

| improve this question | | | | |
  • 7
    What's the difference between an operator and a function, aside from syntax? – CodesInChaos May 12 '16 at 7:12
  • 4
    An operator is not really different From a function. In that spirit all functional languages basically support this. Not all of them have the syntactical idea of making an operator into a function though. The way I see it, at least haskell does support this, I expect there to be more – Vogel612 May 12 '16 at 7:13
  • 1
    @CodesInChaos In many respects there isn't much of a difference, but they are treated differently in many languages. – Jordan Mack May 12 '16 at 8:28
  • 1
    @Vogel612 One of these days I really should play around with Haskell and Lisp. Thanks. – Jordan Mack May 12 '16 at 8:31

In some languages, operators are not very special. Instead, they are merely functions with names made up of symbols, and often don't use the normal function call syntax.

  • Lisp: Operators are just normal functions. (+ 1 2) adds its arguments, (< 1 2 3) checks for an ordering, …. There are no infix operators. There is nothing special about these names, and you can use such operators in higher-order functions.

  • Scala: You can invoke methods without parantheses: foo.bar(baz) and foo bar baz are equivalent. You can also use symbols for method names. The precedence of these operators is determined from the first character in the operator. For example, we can define a method def +-+(x: SomeType) and then invoke it as x +-+ y.

    We can also perform higher-order operations with these operators, but it's important to note that they really are methods not free functions. If we have a sequence and want to combine it, we can't write Seq(…).fold(defaultValue)(+-+) but would have to pass the operator as (_ +-+ _) which is syntactic sugar for ((a, b) -> a.+-+(b)).

  • Haskell: Operators are functions with non-alphabetic names and an associativity and precedence. We can declare a new operator like infixr 0 &, which would declare an right-associative & infix operator with the loosest possible precedence. We can afterwards define it as x & y = ... or (&) x y = .... We don't have to use it as an operator. To use it as a regular function, we can enclose it in parentheses. So I could pass it to foldl like foldl (&) default someList. Otherwise, the syntax would be ambiguous. We can also use regular functions as infix functions, by enclosing the name in backticks: ((&) `foldl` default) someList would also work.

  • C++: Operators are either free functions or member methods. While for example addition on custom types can be invoked as a + b, we could also use operator+(a, b) or a.operator+(b), depending on whether it's a free function. We can also get function pointers to user-defined operators. However, this does not work for built-in types since those operators aren't implemented as functions. The first-class equivalent would be the types in the functional header, e.g. std::plus<T> or std::logical_not<T>. E.g. to flip a vector of booleans, I could std::transform(xs.begin(), xs.end(), xs.begin(), std::logical_not<bool>()).

While some of these languages only make a syntactic difference between functions and operators, any language with higher-order functions can effectively pass operators around by defining a function additionWrapper(x, y) { return x + y }, and then using the additionWrapper as a stand-in. This is the approach C++ uses when it's necessary to use higher-order functions with built-in operators.

| improve this answer | | | | |
  • As the language that can do everything you would ever want it to do, C# supports operator overloading and you can get the methods that handle the operator with reflection: stackoverflow.com/questions/11113259/… – Traubenfuchs May 12 '16 at 8:48
  • @Traubenfuchs: There is more than one lang. that can do everything you would ever want; everybody has a different version "you would ever want". For some, this is "all I want ever to do is webapps". For me, it's "trying out latest CPU instructions, maximum optimization on every level, device drivers, full multithreading controll, offline and realtime hardware accelerated and software based computer graphics, applications, servers, compiler construction, ..." oh that list will become too long. So for my very own version of "everything", C++ would fit better than C#. Apart from that, I like C#. – phresnel Sep 6 '17 at 11:52
  • @Traubenfuchs: And despite my previous post, I am quite dynamic in deciding for a programming language for specific projects. Sometimes I use C#, sometimes C++, Python, Haskell, ... It depends :) – phresnel Sep 6 '17 at 11:54

I know list questions are off-topic here, and that I shouldn't answer off-topic questions, but it's just so tempting! So, here are a number of languages I can think of off the top of my head that support first-class operators, or at least something similar:

  • Apricot:

    (def plus +)
  • Arc:

    (= plus +)
  • Clojure:

    (def plus +)
  • Common Lisp:

    (defvar *plus* #'+)
  • Dylan:

    let plus = \+;
  • Elixir:

    plus = &Kernel.+/2
  • F♯:

    let plus = (+)
  • GOO:

    (def plus +)
  • Haskell:

    let plus = (+)
  • Io:

    plus := Number getSlot("+")
  • Ioke:

    plus = Number Decimal cell(:+)
  • Julia:

    plus = +
  • Lambra:

    (set plus +)
  • LFE:

    (set plus +)
  • Lua: get the __add attribute from the metatable, it contains the function to be called for the + operator, etc.
  • MISC:

    plus: +
  • Newspeak: Methods aren't objects/values, but you can use reflection to get a MethodMirror object (Newspeak uses mirror-based stratified reflection) for a method:

    plus ::= (platform mirrors ClassMirror reflecting: Integer) reflectee methodDictionary at: #+.
  • Nu:

    (set plus +)
  • OCaml:

    let plus = (+)
  • Oz:

    Plus = Number.'+'
  • Perl6:

    my $plus = &infix:<+>
  • Pico:

    plus : +
  • Pike:

    mixed plus = `+
  • Python:

    plus = int.__add__
  • REBOL:

    plus: :+
  • R:

    plus <- `+`
  • Ruby: Methods aren't objects/values, but you can use reflection to get an UnboundMethod object for a method (the public_instance_method method on Module returns an UnboundMethod for the Symbol that was passed in):

    plus = Integer.public_instance_method(:+)
  • Scheme:

    (define plus +)
  • Seph:

    plus = Number Decimal get(:+)
  • Smalltalk: Methods aren't objects/values, but you can use reflection to get a CompiledMethod object for a method (the >> method on Class returns a CompiledMethod for the Symbol that was passed in):

    plus := Number >> #+
  • Standard ML:

    val plus = op +
| improve this answer | | | | |

I believe many functional languages treat operators no differently than any other function.

An example of such a language is Haskell, where operators are essentially functions and can be passed in as parameters to other functions.

| improve this answer | | | | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.