Operator (computer programming)
This article needs additional citations for verification. (January 2019) |
In
Common simple examples include arithmetic (e.g. addition with +
), comparison (e.g. "greater than" with >
), and logical operations (e.g. AND
, also written &&
in some languages). More involved examples include assignment (usually =
or :=
), field access in a record or object (usually .
), and the scope resolution operator (often ::
or .
). Languages usually define a set of built-in operators, and in some cases allow users to add new meanings to existing operators or even define completely new operators.
Syntax
Func(a)
(or (Func a)
in LispThe position of the operator with respect to its operands may be
a ? b : c
– indeed, since this is the only common example, it is often referred to as the ternary operator. Prefix and postfix operations can support any desired arity, however, such as 1 2 3 4 +
.
Occasionally
The specification of a language will specify the syntax the operators it supports, while languages, such as Prolog that support programmer-defined operators require that the syntax be defined by the programmer.
Semantics
The semantics of operators particularly depends on value, evaluation strategy, and argument passing mode (such as boolean short-circuiting). Simply, an expression involving an operator is evaluated in some way, and the resulting value may be just a value (an r-value), or may be an object allowing assignment (an l-value).
In simple cases this is identical to usual function calls; for example, addition x + y
is generally equivalent to a function call add(x, y)
and less-than comparison x < y
to lt(x, y)
, meaning that the arguments are evaluated in their usual way, then some function is evaluated and the result is returned as a value. However, the semantics can be significantly different. For example, in assignment a = b
the target a
is not evaluated, but instead its location (address) is used to store the value of b
– corresponding to
Use of l-values as operator operands is particularly notable in unary increment and decrement operators. In C, for instance, the following statement is legal and well-defined, and depends on the fact that array indexing returns an l-value:
x = ++a[i];
An important use is when a left-associative binary operator modifies its left argument (or produces a
cout << "Hello" << " " << "world!" << endl;
User-defined operators
A language may contain a fixed number of built-in operators (e.g. +, -, *, <, <=, !, =, etc. in
Most languages have a built-in set of operators, but do not allow user-defined operators, as this significantly complicates parsing.[b] Many languages only allow operators to be used for built-in types, but others allow existing operators to be used for user-defined types; this is known as operator overloading. Some languages allow new operators to be defined, however, either at compile time or at run time. This may involve meta-programming (specifying the operators in a separate language), or within the language itself. Definition of new operators, particularly runtime definition, often makes correct static analysis of programs impossible, since the syntax of the language may be Turing-complete, so even constructing the syntax tree may require solving the halting problem, which is impossible. This occurs for Perl, for example, and some dialects of Lisp.
Examples
Common examples that differ syntactically are mathematical
gt
or greater_than
and called as a function, as gt(x, y)
. Instead, the operation uses the special character >
(which is tokenized separately during lexical analysisx > y
.
Common examples that differ semantically (by argument passing mode) are boolean operations, which frequently feature short-circuit evaluation: e.g. a short-circuiting conjunction (X AND Y) that only evaluates later arguments if earlier ones are not false, in a language with strict call-by-value functions. This behaves instead similarly to if/then/else.
Less common operators include:
- Comma operator:
e, f
- Dereference operator:
*p
and address-of operator:&x
- ?:or ternary operator:
number = spell_out_numbers ? "forty-two" : 42
- Elvis operator:
x ?: y
- Elvis operator:
- Null coalescing operator:
x ?? y
- Spaceship operator (for three-way comparison):
x <=> y
- fused multiply-add (FMA) and some high-performance software libraries support functions like cis x = cos x + i sin xto boost processing speed or reduce code size.
Compilation
A compiler can implement operators and functions with
Operator overloading
In some programming languages an operator may be ad hoc polymorphic, that is, have definitions for more than one kind of data, (such as in Java where the +
operator is used both for the addition of numbers and for the concatenation of strings). Such an operator is said to be overloaded. In languages that support operator overloading by the programmer (such as C++) but have a limited set of operators, operator overloading is often used to define customized uses for operators.
In the example IF ORDER_DATE > "12/31/2011" AND ORDER_DATE < "01/01/2013" THEN CONTINUE ELSE STOP
, the operators are: >
(greater than), AND
and <
(less than).
Operand coercion
Some languages also allow for the operands of an operator to be implicitly converted, or coerced, to suitable data types for the operation to occur. For example, in Perl coercion rules lead into 12 + "3.14"
producing the result of 15.14
. The text "3.14"
is converted to the number 3.14 before addition can take place. Further, 12
is an integer and 3.14
is either a floating or fixed-point number (a number that has a decimal place in it) so the integer is then converted to a floating point or fixed-point number respectively.
JavaScript follows opposite rules—finding the same expression above, it will convert the integer 12
into a string "12"
, then concatenate the two operands to form "123.14"
.
In the presence of coercions in a language, the programmer must be aware of the specific rules regarding operand types and the operation result type to avoid subtle programming mistakes.
Operator features in programming languages
The following table shows the operator features in several programming languages:
Programming language | Nonalphanumeric operator symbols | Alphanumeric operator symbols | Prefix | Infix | Postfix | Precedence | Associativity | |||
---|---|---|---|---|---|---|---|---|---|---|
ALGOL 68 | +* ** * / % %* %× - + < <= >= > = /= & -:= +:= *:= /:= %:= %*:= +=: :=: :/=:
(All operators have bold Alphanumeric equivalents, c.f. next column. Some have non ASCII equivalents, c.f. below.) ¬ +× ⊥ ↑ ↓ ⌊ ⌈ × ÷ ÷× ÷* □ ≤ ≥ ≠ ∧ ∨ ×:= ÷:= ÷×:= ÷*:= %×:= :≠: |
not abs arg bin entier leng level odd repr round shorten i shl shr up down lwb upb lt le ge gt eq ne and or over mod elem minusab plusab timesab divab overab modab plusto is isnt | Yes | Yes | No | Yes (prefix operators always have priority 10) | Infix operators are left associative, prefix operators are right associative | Yes | Yes | Yes |
APL | + - × ÷ ⌈ ⌊ * ⍟ | ! ○ ~ ∨ ∧ ⍱ ⍲ < ≤ = ≥ > ≠ . @ ≡ ≢ ⍴ , ⍪ ⍳ ↑ ↓ ? ⍒ ⍋ ⍉ ⌽ ⊖ ∊ ⊥ ⊤ ⍎ ⍕ ⌹ ⊂ ⊃ ∪ ∩ ⍷ ⌷ ∘ → ← / ⌿ \ ⍀ ¨ ⍣ & ⍨ ⌶ ⊆ ⊣ ⊢ ⍠ ⍤ ⌸ ⌺ ⍸ | Alphanumeric symbols need a ⎕ before the keyword | Yes (first-order functions only) | Yes | Yes (higher-order functions only) | Higher-order functions precede first-order functions | Higher-order functions are left associative, first-order functions are right associative | Yes | Yes | Yes (alphanumeric only) |
C | () [] -> . ! ~ ++ -- + - * & / % << >> < <= > >= == != ^ | && || ?: = += -= *= /= %= &= ^=
|
sizeof | Yes | Yes | Yes | Yes | Yes | Yes | No | No |
C++ (more) | const_cast
|
Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | |
C# (more )
|
Same as C/C++, along with ?. ?[] ?? ??=
|
sizeof nameof new stackalloc await throw checked unchecked is as delegate default true false LINQ: from select where group...by group...by...into join...in...on...equals join...in...on...equals...into orderby orderby...descending Roslyn-only: __makeref __refvalue __reftype |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | No |
Java | Same as C/C++ | instanceof
|
Yes | Yes | Yes | Yes | Yes | Yes | No | No |
Eiffel | [] + - * / // = /= | not and or implies "and then" "or else" | Yes | Yes | No | Yes | Yes | No | Yes | Yes |
Haskell
|
+ - * / ^ ^^ ** == /= > < >= <= && || >>= >> $ $! . ++ !! : Many more in common libraries | The function's name must be put into backticks | Yes | Yes | No | Yes | Yes | Yes, using Type classes | Yes | |
Pascal | * / + - = < > <> <= >= := | in | Yes | Yes | No | Yes | Yes | Yes | No | No |
Perl | -> ++ -- ** ! ~ \ + - . =~ !~ * / % < > <= >= == != <=> ~~ & | ^ && || ' | print sort chmod chdir rand and or not xor lt gt le ge eq ne cmp x | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No |
PHP | [] ** ++ -- ~ @! ?: = += -= *= **= /= .= %= &= |= ^= <<= >>=
|
clone new unset print echo isset | Yes | Yes | Yes | Yes | Yes | No | No | No |
PL/I | ( ) -> + - * / ** > ¬> >= = ¬= <= < ¬< ¬ & | || | Yes | Yes | No | Yes | Yes | No | No | No | |
Prolog | :- ?- ; , . =.. = \= < =< >= > == \== - + / * | spy nospy not is mod | Yes | Yes | Yes | Yes | Yes | No | No | Yes |
Raku | ++ -- ** ! ~ ~~ * / + - . < > <= >= == != <=> & | ^ && || // [8] | print sort chmod chdir rand and or not xor lt gt le ge eq ne leg cmp x xx | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes[9] |
Seed7 | {} [] -> ** ! + - * / << >> & >< | = <> > >= < <= <& := +:= -:= *:= /:= <<:= >>:= &:= @:= | conv varConv parse digits lpad rpad lpad0 | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Smalltalk | (yes - Up to two characters[10]) | Alphanumeric symbols need a colon after the keyword | No | Yes | Yes | No | No | Yes | Yes | Yes |
Swift | Any Unicode symbol string except ., including ! ~ + - * / % =+ =- =* =/ =% &+ &- &* =&+ =&- =&* && || << >> & | ^ == != < <= > >= ?? ... ..< in standard library | is as as? | Yes | Yes | Yes | Yes (defined as partial order in precedence groups) | Yes (defined as part of precedence groups) | Yes | Yes | Yes |
Visual Basic .NET
|
() . ! ?() ?. ?! + - * / \ & << >> < <= > >= ^ <> = += -= *= /= \= &= ^= <<= >>= | New Await Mod Like Is IsNot Not And AndAlso Or OrElse Xor If(...,...) If(...,...,...) GetXmlNamespace(...) GetType(...) NameOf(...) TypeOf...Is TypeOf...IsNot DirectCast(...,...) TryCast(...,...) CType(...,...) CBool(...) CByte(...) CChar(...) CDate(...) CDec(...) CDbl(...) CInt(...) CLng(...) CObj(...) CSByte(...) CShort(...) CSng(...) CStr(...) CUInt(...) CULng(...) CUShort(...) LINQ: From Aggregate...Into Select Distinct Where <Order By>...[Ascending|Descending] Take <Take While> Skip <Skip While> Let Group...By...Into Join...On <Group Join...On...Into> |
Yes | Yes | Yes | Yes | Yes | Yes | Yes | No |
See also
Notes
- ^ Conversely a right-associative operator with its right argument, though this is rarer.
- lexical specification of the language, which changes the lexical analysis. The arity and precedence of the operator is then part of the phrase syntax of the language, which changes the phrase-level analysis. For example, adding an operator
@
requires lexing and tokenizing this character, and the phrase structure (syntax tree) depends on the arity and precedence of this operator.
References
- ^ "Operator Input Forms—Wolfram Language Documentation". reference.wolfram.com.
- ^ "Maxima 5.42.0 Manual: 7. Operators". maxima.sourceforge.net.
- ^ "Prefix, Postfix and Circumfix Operators". mythryl.org.
- ^ "Operators". doc.perl6.org.
- ^ "SWI-Prolog -- op/3". www.swi-prolog.org.
- ^ "Declare an operator". seed7.sourceforge.net.
- ^ "PHP: Error Control Operators - Manual". php.net.
- ^ "Operators". docs.perl6.org.
- ^ "Functions". docs.perl6.org.
- ^ Goldberg, Adele. "Smalltalk-80: The Language and its Implementation, p. 27, ISBN 0-201-11371-6" (PDF).