diff --git a/doc/src/manual/functions.md b/doc/src/manual/functions.md index b2c72cb648d6b..238fd1af886ca 100644 --- a/doc/src/manual/functions.md +++ b/doc/src/manual/functions.md @@ -240,11 +240,11 @@ alone is a matter of coding style. ## Operators Are Functions -In Julia, most operators are just functions with support for special syntax. (The exceptions are -operators with special evaluation semantics like `&&` and `||`. These operators cannot be functions -since [Short-Circuit Evaluation](@ref) requires that their operands are not evaluated before evaluation -of the operator.) Accordingly, you can also apply them using parenthesized argument lists, just -as you would any other function: +In Julia, most [operators](@ref Operator-Precedence-and-Associativity) are just functions with support +for special syntax. (The exceptions are operators with special evaluation semantics like `&&` and `||`. +These operators cannot be functions since [Short-Circuit Evaluation](@ref) requires that their operands +are not evaluated before evaluation of the operator.) Accordingly, you can also apply them using +parenthesized argument lists, just as you would any other function: ```jldoctest julia> 1 + 2 + 3 diff --git a/doc/src/manual/integers-and-floating-point-numbers.md b/doc/src/manual/integers-and-floating-point-numbers.md index 845d42e33abfb..3b05915414fa3 100644 --- a/doc/src/manual/integers-and-floating-point-numbers.md +++ b/doc/src/manual/integers-and-floating-point-numbers.md @@ -683,8 +683,8 @@ julia> 2^2x 64 ``` -The precedence of numeric literal coefficients is slightly lower than that of -unary operators such as negation. +The [precedence](@ref Operator-Precedence-and-Associativity) of numeric literal +coefficients is slightly lower than that of unary operators such as negation. So `-2x` is parsed as `(-2) * x` and `√2x` is parsed as `(√2) * x`. However, numeric literal coefficients parse similarly to unary operators when combined with exponentiation. diff --git a/doc/src/manual/mathematical-operations.md b/doc/src/manual/mathematical-operations.md index 20abf40917a18..8773a7bfd7381 100644 --- a/doc/src/manual/mathematical-operations.md +++ b/doc/src/manual/mathematical-operations.md @@ -402,32 +402,55 @@ Julia applies the following order and associativity of operations, from highest | Category | Operators | Associativity | |:-------------- |:------------------------------------------------------------------------------------------------- |:-------------------------- | -| Syntax | `.` followed by `::` | Left | -| Exponentiation | `^` | Right | -| Unary | `+ - ! ~ ¬ √ ∛ ∜ ⋆ ± ∓ <: >:` | Right[^1] | +| Syntax | `.` followed by `::` followed by `'` | Left | +| Exponentiation | `^` (`↑ ↓ ⇵ ⟰ ⟱ ⤈ ⤉ ⤊ ⤋ ⤒ ⤓`, etc.) | Right[^1] | +| Unary | `+ - ! ~ √ ∛ ∜ <: >:` (`¬ ⋆ ± ∓`) | Right[^2] | +| Juxtaposition | Implicit multiplication by numeric literal coefficients; e.g., `2x` is parsed as `2*x` | Non-associative | | Bitshifts | `<< >> >>>` | Left | | Fractions | `//` | Left | -| Multiplication | `* / % & \ ÷` | Left[^2] | -| Addition | `+ - \| ⊻` | Left[^2] | -| Syntax | `: ..` | Left | +| Multiplication | `* / ÷ % & ∘ \ ∩ ⊼` (`⋅ × ⋆ ⊗ ⊘ ⊠ ⊡ ⊓ ∧`, etc.) | Left[^3] | +| Addition | `+ - \| ∪ ⊻ ⊽` (`± ∓ ⊕ ⊖ ⊞ ⊟ ⊔ ∨`, etc.) | Left[^3] | +| Syntax | `:` (`.. … ⁝ ⋮ ⋱ ⋰ ⋯`) | Left | | Syntax | `\|>` | Left | | Syntax | `<\|` | Right | -| Comparisons | `> < >= <= == === != !== <:` | Non-associative | -| Control flow | `&&` followed by `\|\|` followed by `?` | Right | +| Comparisons | `in isa > < >= ≥ <= ≤ == === ≡ != ≠ !== ≢ ∈ ∉ ∋ ∌ ⊆ ⊈ ⊊ ≈ ≉ ⊇ ⊉ ⊋ <: >:` (`⊂ ⊄ ∝ ∥`, etc.) | Non-associative[^4] | +| Control flow | `&&` followed by `\|\|` | Right | +| Arrows | (`← → ↔ ↚ ↛ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔`, etc.) | Right | +| Control flow | `?` | Right | | Pair | `=>` | Right | -| Assignments | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | Right | +| Assignments | `= += -= *= /= //= \= ^= ÷= %= <<= >>= >>>= \|= &= ⊻= ~` (`≔ ⩴ ≕ :=`) | Right | [^1]: - The unary operators `+` and `-` require explicit parentheses around their argument to disambiguate them from the operator `++`, etc. Other compositions of unary operators are parsed with right-associativity, e. g., `√√-a` as `√(√(-a))`. + Unary operators and juxtaposition of numeric literals *within the exponent* take precedence. For example, `2^-3`, `x^√2`, and `2^3x` are parsed as `2^(-3)`, `x^(√2)`, and `2^(3*x)`; whereas `-2^3`, `√x^2`, `2^3*x`, and `2x^3` are parsed as `-(2^3)`, `√(x^2)`, `(2^3)*x`, and `2*(x^3)`. [^2]: + The unary operators `+` and `-` require explicit parentheses around their argument to disambiguate them from the operator `++`, etc. Other compositions of unary operators are parsed with right-associativity, e.g., `√√-a` as `√(√(-a))`. +[^3]: The operators `+`, `++` and `*` are non-associative. `a + b + c` is parsed as `+(a, b, c)` not `+(+(a, b), c)`. However, the fallback methods for `+(a, b, c, d...)` and `*(a, b, c, d...)` both default to left-associative evaluation. - -For a complete list of *every* Julia operator's precedence, see the top of this file: -[`src/julia-parser.scm`](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm). Note that some of the operators there are not defined -in the `Base` module but may be given definitions by standard libraries, packages or user code. - -You can also find the numerical precedence for any given operator via the built-in function `Base.operator_precedence`, where higher numbers take precedence: +[^4]: + Comparisons can be [chained](@ref "Chaining comparisons"). For example, `a < b < c` is essentially the same as `a < b && b < c`. However, the order of evaluation is undefined. + +Most of these [operators are functions](@ref Operators-Are-Functions). They can also be used with either functional +notation (e.g., `+(a, b)`) or "infix" notation (e.g., `a + b`). Those listed outside of parentheses are already +defined in the `Base` module; those listed inside parentheses are not currently defined in `Base`, but are available +to be defined by standard libraries, packages, or user code. For example, `⋅` and `×` are defined in the standard +library's `LinearAlgebra` package. Some of the latter lists are incomplete; for a complete listing of *every* Julia +operator and its precedence, see the top of this file: +[`src/julia-parser.scm`](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm). + +It is also possible to define additional operators by appending suffixes to most of the binary operators. The valid +suffixes include the Unicode combining characters, along with the subscripts, superscripts, and various primes +(`′ ″ ‴ ⁗ ‵ ‶ ‷`) listed in +[`src/flisp/julia_opsuffs.h`](https://github.com/JuliaLang/julia/blob/master/src/flisp/julia_opsuffs.h). The +resulting operators can be used with either functional or infix notation, and have the same precedence and +associativity as the base operator. For example, `⋆̂ᵝ₁′` could be defined as a function, and used as an infix operator +with the same precedence and associativity as `⋆` and `*`. However, operators ending with a subscript or superscript +letter must be followed by a space when used in infix notation to distinguish them from variable names that begin +with a subscript or superscript letter. For example, if `+ᵃ` is an operator, then `+ᵃx` must be written as `+ᵃ x` +to distinguish it from `+ ᵃx`. + +You can also find the numerical precedence for any binary or ternary operator via the +built-in function `Base.operator_precedence`, where higher numbers take precedence: ```jldoctest julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) diff --git a/doc/src/manual/variables.md b/doc/src/manual/variables.md index 074a7207698d1..140ec0661be46 100644 --- a/doc/src/manual/variables.md +++ b/doc/src/manual/variables.md @@ -108,7 +108,8 @@ digits (0-9 and other characters in categories Nd/No), as well as other Unicode and other modifying marks (categories Mn/Mc/Me/Sk), some punctuation connectors (category Pc), primes, and a few other characters. -Operators like `+` are also valid identifiers, but are parsed specially. In some contexts, operators +[Operators](@ref Operator-Precedence-and-Associativity) like `+` are also valid identifiers, but +are parsed specially. In some contexts, operators can be used just like variables; for example `(+)` refers to the addition function, and `(+) = f` will reassign it. Most of the Unicode infix operators (in category Sm), such as `⊕`, are parsed as infix operators and are available for user-defined methods (e.g. you can use `const ⊗ = kron` @@ -118,7 +119,6 @@ A space is required between an operator that ends with a subscript/superscript l variable name. For example, if `+ᵃ` is an operator, then `+ᵃx` must be written as `+ᵃ x` to distinguish it from `+ ᵃx` where `ᵃx` is the variable name. - A particular class of variable names is one that contains only underscores. These identifiers are write-only. I.e. they can only be assigned values, which are immediately discarded, and their values cannot be used in any way. ```jldoctest