Operator (computer programming): Difference between revisions

Content deleted Content added
Examples: missed one
Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5
 
(21 intermediate revisions by 8 users not shown)
Line 3:
{{About|operators in computer programming|other uses|Operator (disambiguation)}}
 
In [[computer programming]], an '''operator''' is a [[programming language]] construct that provides functionality that may not be possible to define as a user-defined [[Function (computer programming)|function]] (i.e. [[sizeof]] in [[C (programming language)|C]]) or has [[Syntax (programming languages)|syntax]] different than a function (i.e. [[Infix notation|infix]] addition as in <code>a+b</code>). SomeLike languagesother allowprogramming language concepts, ''operator'' has a generally accepted, although debatable meaning among practitioners while at the same time each language-defined operatorgives toit bespecific overriddenmeaning within user-definedthat behaviorcontext, and sometherefore allowthe formeaning user-definedvaries operatorby symbolslanguage.
 
Some operators are represented with symbols {{endash}} characters typically not allowed for a function [[identifier (computer science)|identifier]] {{endash}} to allow for presentation that is more familiar looking than typical function syntax. For example, a function that tests for greater-than could be named <code>gt</code>, but many languages provide an infix symbolic operator so that code looks more familiar. For example, this:
 
<!--this is pseudocode; do not use syntaxhighlight lang="something"-->
Line 13:
 
<code>if x > y then return</code>
 
Some languages allow a language-defined operator to be overridden with user-defined behavior and some allow for user-defined operator symbols.
 
Operators may also differ semantically from functions. For example, [[short-circuit evaluation|short-circuit]] Boolean operations evaluate later arguments only if earlier ones are not false.
 
== Differences from functions ==
== Syntax ==
 
=== Syntax ===
Many operators differ syntactically from user-defined functions. In most languages, a function is [[prefix notation]] with fixed [[Order of operations|precedence]] level and associativity and often with compulsory [[parentheses]] (e.g. <code>Func(a)</code> or <code>(Func a)</code> in [[Lisp (programming language)|Lisp]]). In contrast, many operators are infix notation and involve different use of delimiters such as parentheses.
 
In general, an operator may be prefix, infix, postfix, [[matchfix]], [[circumfix]] or bifix,<ref>{{Cite web|url=https://reference.wolfram.com/language/tutorial/OperatorInputForms.html.en|title=Operator Input Forms—Wolfram Language Documentation|website=reference.wolfram.com}}</ref><ref>{{Cite web|url=httphttps://maxima.sourceforge.net/docs/manual/maxima_7.html|title=Maxima 5.42.0 Manual: 7. Operators|website=maxima.sourceforge.net}}</ref><ref>{{Cite web|url=https://mythryl.org/my-Prefix__Postfix_and_Circumfix_Operators.html|title=Prefix, Postfix and Circumfix Operators|website=mythryl.org}}</ref><ref>{{Cite web|url=http://doc.perl6.org/language/operators#___top|title=Operators|website=doc.perl6.org}}</ref><ref name=Pribavkina>{{cite book conference|ref= Pribavkina| last1 = Pribavkina| last2= Rodaro| date= August 2010| year= 2010| title= State Complexity of Prefix, Suffix, Bifix and Infix Operators on Regular Languages |journal= Lecture Notes in Computer Science| type= Conference Article| series= Developments in Language Theory| language= English| editionconference= 14th International Conference on Developments in Language Theory| ___location= London Ontario| publisher= Springer| publication-place= Germany| publication-date= 2010| issue= 6224| pages= 376–377 | doi= 10.1007/978-3-642-14455-4_34| isbn= 978-3-642-14454-7| issn= 0302-9743}}</ref>, and the syntax of an [[expression (computer science)|expression]] involving an operator depends on its [[arity]] (number of [[operand]]s), precedence, and (if applicable), [[Operator associativity|associativity]]. Most programming languages support [[binary operator]]s and a few [[unary operation|unary operators]], with a few supporting more operands, such as the [[?:]] operator in C, which is ternary. There are prefix unary operators, such as unary minus <code>-x</code>, and postfix unary operators, such as [[post-increment]] <code>x++</code>; and binary operations are infix, such as <code>x + y</code> or <code>x = y</code>. Infix operations of higher arity require additional symbols, such as the [[ternary operator]] ?: in C, written as <code>a ? b : c</code> – 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 <code>1 2 3 4 +</code>.
 
=== Semantics ===
The semantics of an operator may significantly differ from that of a normal function. For reference, addition is evaluated like a normal function. For example, <code>x + y</code> can be equivalent to a function <code>add(x, y)</code> in that the arguments are evaluated and then the functional behavior is applied. However, [[Assignment_(computer_science)|assignment]] is different. For example, given <code>a = b</code> the target <code>a</code> is ''not'' evaluated. Instead its value is replaced with the value of <code>b</code>. The [[scope resolution operator|scope resolution]] and element access operators (as in <code>Foo::Bar</code> and <code>a.b</code>, respectively, in the case of e.g. [[C++]]) operate on identifier names; not values.
The semantics of operators particularly depends on value, evaluation strategy, and argument passing mode (such as Boolean short-circuiting). Simply, an [[Expression (computer science)|expression]] involving an operator is evaluated in some way, and the resulting [[value (computer science)|value]] may be just a value (an r-value), or may be an object allowing assignment (an l-value).
 
In C, for instance, the array indexing operator can be used for both read access as well as assignment. In the following example, the [[increment and decrement operators|increment operator]] reads the element value of an array and then assigns the element value.
In simple cases this is identical to usual function calls; for example, addition <code>x + y</code> is generally equivalent to a function call <code>add(x, y)</code> and less-than comparison <code>x &lt; y</code> to <code>lt(x, y)</code>, 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 <code>a = b</code> the target <code>a</code> is not evaluated, but instead its ''___location'' (address) is used to store the value of <code>b</code> – corresponding to [[call-by-reference]] semantics. Further, an assignment may be a statement (no value), or may be an expression (value), with the value itself either an r-value (just a value) or an l-value (able to be assigned to). As another example, the [[scope resolution operator]] :: and the element access operator . (as in <code>Foo::Bar</code> or <code>a.b</code>) operate not on values, but on ''names'', essentially [[call-by-name]] semantics, and their value is a name.
 
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:
<syntaxhighlight lang=c>
x = ++a[i];
</syntaxhighlight>
 
The C++ <code>&lt;&lt;</code> operator allows for [[fluent interface|fluent]] syntax by supporting a sequence of operators that affect a single argument. For example:
An important use is when a left-associative binary operator modifies its left argument (or produces a [[side effect (computer science)|side effect]]) and then evaluates to that argument as an l-value.{{efn|Conversely a right-associative operator with its right argument, though this is rarer.}} This allows a sequence of operators all affecting the original argument, allowing a [[fluent interface]], similar to [[method cascading]]. A common example is the <code>&lt;&lt;</code> operator in the C++ <code>[[iostream]]</code> library, which allows fluent output, as follows:
<syntaxhighlight lang=cpp>
cout << "Hello" << " " << "world!" << endl;
</syntaxhighlight>
 
== ad hoc polymorphic ==
{{further|Ad hoc polymorphism}}
Conceptually, an operator can be [[Function overloading|overloaded]] in the same way that a function can {{endash}} acting differently based on the type of input. Some languages provide operators that are inherently overloaded (aka '''ad hoc polymorphic'')' {{endash}} inherently overloaded. For example, in [[Java (programming language)|Java]] the {{code|+}} operator sums [[number]]s or [[concatenate]]s [[String (computer science)|strings]]. Some languages support user-defined operator overloading (such as [[C++]]).
 
== Customization ==
Some languages support user-defined [[operator overloading|overloading]] (such as [[C++]] and [[Fortran]]). An operator, defined by the language, can be [[function overloading|overloaded]] to behave differently based on the type of input.
Some languages (e.g. C, C++ and [[PHP]]) define a fixed set of operators, while others (e.g. [[Prolog]],<ref>{{Cite web|url=https://www.swi-prolog.org/pldoc/man?predicate=op/3|title=SWI-Prolog -- op/3|website=www.swi-prolog.org}}</ref> [[Seed7]],<ref>{{Cite web|url=http://seed7.sourceforge.net/examples/operator.htm|title=Declare an operator|website=seed7.sourceforge.net}}</ref> [[F Sharp (programming language)|F#]], [[OCaml]], [[Haskell]]) allow for user-defined operators. Some programming languages restrict operator symbols to special characters like {{mono|1='''[[Addition|+]]'''}} or {{mono|1='''[[Assignment (computer science)|:=]]'''}} while others allow names like <code>[[Integer_division#Division_of_integers|div]]</code> (e.g. [[Pascal (programming language)|Pascal]]).
 
Some languages (e.g. C, C++ and [[PHP]]) define a fixed set of operators, while others (e.g. [[Prolog]],<ref>{{Cite web|url=https://www.swi-prolog.org/pldoc/man?predicate=op/3|title=SWI-Prolog -- op/3|website=www.swi-prolog.org}}</ref> [[Seed7]],<ref>{{Cite web|url=httphttps://seed7.sourceforge.net/examples/operator.htm|title=Declare an operator|website=seed7.sourceforge.net}}</ref> [[F Sharp (programming language)|F#]], [[OCaml]], [[Haskell]]) allow for user-defined operators. Some programming languages restrict operator symbols to special characters like {{mono|1='''[[Addition|+]]'''}} or {{mono|1='''[[Assignment (computer science)|:=]]'''}} while others allow names like <code>[[Integer_division#Division_of_integers|div]]</code> (e.g. [[Pascal (programming language)|Pascal]]), and even arbitrary names (e.g. [[Fortran]] where an upto 31 character long operator name is enclosed between dots<ref name="IntelFortran">{{cite web |title=Defined Operations |url=https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-0/defined-operations.html |publisher=Intel |access-date=6 May 2025}}</ref>).
Most languages do not support user-defined operators since the feature significantly complicates parsing.{{efn|Introducing a new operator changes the [[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 <code>@</code> requires lexing and tokenizing this character, and the phrase structure (syntax tree) depends on the arity and precedence of this operator.}} Many languages only allow operators to be used for built-in types, but some allow operators to be [[operator overloading|overloaded]] for user-defined types. Some languages allow new operators to be defined which may involve meta-programming (specifying the operators in a separate language). 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 (programming language)|Lisp]].
 
Most languages do not support user-defined operators since the feature significantly complicates parsing.{{efn| Introducing a new operator changes the [[lexicalarity specification]]and of the language, which changes theprecedence [[lexical analysisspecification]]. The arity and precedence of the operator is then part of the phrase syntax of the language, which changes theaffects phrase-level analysis. For example, adding an operator <code>@</code> requires lexing and tokenizing this character, and the phrase structure (syntax tree) depends on the arity and precedence of this operator.}} Many languages only allow operators to be used for built-in types, but some allow operators to be [[operatorlexical overloading|overloadedanalysis]] for user-defined types. Some languages allow new operators to be defined which may involve meta-programming (specifying the operators in a separate language). Definition of newCustom operators, particularly via runtime definition, often makesmake correct [[static analysis]] of programsa program 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 (programming language)|Lisp]].
== Overloading ==
{{main|Operator overloading}}
 
If a language does allow for defining new operators, the mechanics of doing so may involve meta-programming {{endash}} specifying the operator in a separate language.
Conceptually, an operator can be [[Function overloading|overloaded]] in the same way that a function can {{endash}} acting differently based on the type of input. Some languages provide operators that are inherently overloaded (aka ''ad hoc polymorphic''). For example, in [[Java (programming language)|Java]] the {{code|+}} operator sums [[number]]s or [[concatenate]]s [[String (computer science)|strings]]. Some languages support user-defined operator overloading (such as [[C++]]).
 
== Operand coercion ==
Line 60 ⟶ 65:
* [[Mathematical logic|Logic]]: such as <code>a {{red|AND}} b</code> or <code>a {{red|&amp;&amp;}} b</code>
* [[Assignment (computer science)|Assignment]]: such as <code>a {{red|&equals;}} b</code> or <code>a {{red|:&equals;}} b</code>
* [[Three-way comparison]] (aka spaceship): <code>x {{red|&lt;&equals;&gt;}} y</code>
 
;OtherProgram symbolicstructure operators
* [[Record (computer science)|Record]] or [[Object (computer science)|object]] [[Field (computer science)|field]] access: such as <code>a{{red|.}}b</code>
* [[scope resolution operator|Scope resolution]]: such as <code>a{{red|::}}b</code> or <code>a{{red|.}}b</code>
 
* [[Comma operator|Comma]]: <code>e{{red|,}} f</code>
;Conditional operators
* [[Dereference operator|Dereference]]: <code>{{red|*}}p</code>
* Address-of operator: <code>{{red|&amp;}}x</code>
* [[Ternary conditional operator|Ternary conditional]]: <code>condition {{red|?}} a {{red|:}} b</code>
* [[Elvis operator|Elvis]]: <code>x {{red|?:}} y</code>
* [[Null coalescing operator|Null coalesing]]: <code>x {{red|??}} y</code>
* [[Three-way comparison]] (aka spaceship): <code>x {{red|&lt;&equals;&gt;}} y</code>
 
;Notable C and C++ operators
<!-- This should probably become a separate article at a later stage ... or a new section ... or deleted -->
* Address-of operator: <code>{{red|&amp;}}x</code>
* [[Dereference operator|Dereference]]: <code>{{red|*}}p</code>
* [[Comma operator|Comma]]: <code>e{{red|,}} f</code>
 
{{anchor|Compound operator|Fused operation}}
;Compound operators
Combining two or more* [[atomiccompound operation]]sassignment into one to simplify [[compound expressionoperator|expression]]s, eases compiler optimizations depending on the underlying hardware implementation, or improve performance for speed or size. An example are the set of [[compoundCompound assignment operator]]s (aka augmented assignmentsassignment) in C/C++: <code>+=</code>, <code>-=</code>, <code>*=</code>, <code>/=</code>, <code>%=</code>, <code><<=</code>, <code>>>=</code>, <code>&=</code>, <code>^=</code>, <code>|=</code> Similarly, some [[digital signal processor]]s provide special [[opcode]]s for [[fused operation]]s<!-- This should probably become a separate article at a later stage, possibly combined with the similar topic on compound operations --> like [[multiply–accumulate]] (MAC/MAD) or [[fused multiply–add]] (FMA) and some high-performance software libraries support functions like [[cis (mathematics)|{{math|1=cis ''x'' = cos ''x'' + ''i'' sin ''x''}}]] to boost processing speed or reduce code size.
* [[fused operation|Fused]]: such as [[cis (mathematics)|{{math|1=cis ''x'' = cos ''x'' + ''i'' sin ''x''}}]]
 
== Operator features in programming languages ==
Line 121 ⟶ 130:
|-
|[[B (programming language)|B]]
|{{code|1=() [] ! ~ ++ -- + - * & / % << >> < <= > >= == != ^ <nowiki>|</nowiki> [[?:]] = =+ =- =* =/ =% =& =^ =<nowiki>|</nowiki>}}<ref>{{Cite web |title=A TUTORIAL INTRODUCTION TO THE LANGUAGE B |url=https://www.bell-labs.com/usr/dmr/www/btut.html |access-date=2024-08-03 |archive-date=2017-04-03 |archive-url=https://web.archive.org/web/20170403063756/https://www.bell-labs.com/usr/dmr/www/btut.html |url-status=dead }}</ref>
|
|{{Yes}}
Line 202 ⟶ 211:
| colspan="2" {{Yes}}, using [[Type class]]es
| {{Yes}}
|-
| [[MultiValue|mvBasic Databasic/Unibasic]]
|<code>+ - * / ^ ** : = ! & [] += -= := # < > <= >= <> >< =< #> => #< </code>
|<code>AND OR NOT EQ NE LT GT LE GE MATCH ADDS() ANDS() CATS() DIVS() EQS() GES() GTS() IFS()</code>
| {{Yes}}
| {{Yes}}
| {{Yes}}
| {{Yes}}
| {{Yes}}
| {{Yes}}
| {{Yes}}
| {{No}}
|-
| [[Pascal (programming language)|Pascal]]
Line 216 ⟶ 237:
|-
| [[Perl]]
| <code>-> ++ -- ** ! ~ \ + - . =~ !~ * / % < > <= >= == != <=> ~~ & <nowiki>|</nowiki> ^ &amp;&amp; <nowiki>||</nowiki> ' ''&apos;&apos; {{Not a typo| // .. ... ?: {{=}} +{{=}} -{{=}} *{{=}} , {{=}}>}} </code>
| <code>print sort chmod chdir rand and or not xor lt gt le ge eq ne cmp x </code>
| {{Yes}}
Line 327 ⟶ 348:
== See also ==
* [[Operators in C and C++]]
* [[Relational operator]]
 
== Notes ==
{{notelist}}
 
== References ==