Overloaded operators: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 16: Line 16:
LDA ($80,x) ;use the values stored at $80+x and $81+x as a 16-bit memory address to load from.
LDA ($80,x) ;use the values stored at $80+x and $81+x as a 16-bit memory address to load from.
LDA ($80),y ;use the values stored at $80 and $81 as a 16-bit memory address to load from. Load from that address + y.</lang>
LDA ($80),y ;use the values stored at $80 and $81 as a 16-bit memory address to load from. Load from that address + y.</lang>


=={{header|Nim}}==
Nim allows overloading of operators. For instance, we may define a vector type and addition of vectors:

<lang Nim>type Vector = tuple[x, y, z: float]

func `+`(a, b: Vector): Vector = (a.x + b.x, a.y + b.y, a.z + b.z)

echo (1.0, 2.0, 3.0) + (4.0, 5.0, 6.0) # print (x: 5.0, y: 7.0, z: 9.0)</lang>

The list of predefined operators with their precedence can be found here: https://rosettacode.org/wiki/Operator_precedence#Nim

Nim allows also user defined operators which must be composed using the following characters:

= + - * / < >
@ $ ~ & % |
! ? ^ . : \

For instance, we may define an operator <code>^^</code> the following way:

<lang Nim>func `^^`(a, b: int): int = a * a + b * b</lang>

To determine the precedence of user-defined operators, Nim defines a set of rules:

Unary operators always bind stronger than any binary operator: <code>$a + b</code> is <code>($a) + b</code> and not <code>$(a + b)</code>.

If an unary operator's first character is <code>@</code> it is a sigil-like operator which binds stronger than a primarySuffix: <code>@x.abc</code> is parsed as <code>(@x).abc</code> whereas <code>$x.abc</code> is parsed as <code>$(x.abc)</code>.

For binary operators that are not keywords, the precedence is determined by the following rules:

Operators ending in either <code>-></code>, <code>~></code> or <code>=></code> are called arrow like, and have the lowest precedence of all operators.

If the operator ends with <code>=</code> and its first character is none of <code><</code>, <code>></code>, <code>!</code>, <code>=</code>, <code>~</code>, <code>?</code>, it is an assignment operator which has the second-lowest precedence.

Otherwise, precedence is determined by the first character.


=={{header|Phix}}==
=={{header|Phix}}==

Revision as of 17:36, 14 September 2021

Overloaded operators is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

An overloaded operator can be used on more than one data type, or represents a different action depending on the context. For example, if your language lets you use "+" for adding numbers and concatenating strings, then one would say that the "+" operator is overloaded.

Task

Demonstrate overloaded operators in your language, by showing the different types of data they can or cannot operate on, and the results of each operation.



6502 Assembly

Many commands have multiple addressing modes, which alter the way a command is executed. On the 6502 most of these are in fact different opcodes, using the same mnemonic. <lang 6502asm>LDA #$80 ;load the value 0x80 (decimal 128) into the accumulator. LDA $80 ;load the value stored at zero page memory address $80 LDA $2080 ;load the value stored at absolute memory address $2080. LDA $80,x ;load the value stored at memory address ($80+x). LDA ($80,x) ;use the values stored at $80+x and $81+x as a 16-bit memory address to load from. LDA ($80),y ;use the values stored at $80 and $81 as a 16-bit memory address to load from. Load from that address + y.</lang>


Nim

Nim allows overloading of operators. For instance, we may define a vector type and addition of vectors:

<lang Nim>type Vector = tuple[x, y, z: float]

func `+`(a, b: Vector): Vector = (a.x + b.x, a.y + b.y, a.z + b.z)

echo (1.0, 2.0, 3.0) + (4.0, 5.0, 6.0) # print (x: 5.0, y: 7.0, z: 9.0)</lang>

The list of predefined operators with their precedence can be found here: https://rosettacode.org/wiki/Operator_precedence#Nim

Nim allows also user defined operators which must be composed using the following characters:

= + - * / < > @ $ ~ &  % | !  ? ^ .  : \

For instance, we may define an operator ^^ the following way:

<lang Nim>func `^^`(a, b: int): int = a * a + b * b</lang>

To determine the precedence of user-defined operators, Nim defines a set of rules:

Unary operators always bind stronger than any binary operator: $a + b is ($a) + b and not $(a + b).

If an unary operator's first character is @ it is a sigil-like operator which binds stronger than a primarySuffix: @x.abc is parsed as (@x).abc whereas $x.abc is parsed as $(x.abc).

For binary operators that are not keywords, the precedence is determined by the following rules:

Operators ending in either ->, ~> or => are called arrow like, and have the lowest precedence of all operators.

If the operator ends with = and its first character is none of <, >, !, =, ~, ?, it is an assignment operator which has the second-lowest precedence.

Otherwise, precedence is determined by the first character.

Phix

Phix does not allow operator overloading and it is not possible to define new operators.

The standard arithmetic operators accept (mixed) integer and floating point values without casting.

The relational operators accept integer, float, string, and sequence values.

The logical operators only accept atoms, however there are 40-something sq_xxx() builtins that can be used
to perform all the builtin operations on any mix of integer, float, string, or sequence values.

Subscripts and concatenation work equivalently on strings and sequences.

Any parameter can be integer, float, string, or sequence if it is declared as an object.

For example printf() can accept [a file number, format string and] a single atom or a sequence of objects,
it being wise to wrap lone strings in {} to ensure you get the whole thing not just the first letter.

Inline assembly mnemonics have multiple implicit addressing modes as per the standard intel syntax.

printf(1,"%g\n",3.5 + 3)                -- 6.5
printf(1,"%t\n",3.5 > 3)                -- true
printf(1,"%t\n","a" = "a")              -- true
printf(1,"%t\n",{1} = {2})              -- false
printf(1,"%V\n",{{1} & {2}})            -- {1,2}
printf(1,"%V\n",{"a" & "b"})            -- "ab"
printf(1,"%V\n",{"AB"[2] & {1,2}[1]})   -- {66,1}

integer i
#ilASM{ lea eax,[i]
        mov [eax],ebx
        mov [i],ebx
        mov [i],0
        mov eax,ebx
        mov eax,1   -- etc
      } 

Wren

Library: Wren-date


All of Wren's operators can be overloaded except: &&, ||, ?: and =. It is not posssible to create new operators from scratch.

When an operator is overloaded it retains the same arity, precedence and associativity as it has when used in its 'natural' sense.

The standard library contains several instances of overloading the + and * operators which are demonstrated below.

Otherwise, operator overloading can be used without restriction in user defined classes.

However, whilst it is very useful for classes representing mathematical objects, it should be used sparingly otherwise as code can become unreadable if it is used inappropriately. <lang ecmascript>import "/date" for Date

var s1 = "Rosetta " var s2 = "code" var s3 = s1 + s2 // + operator used to concatenate two strings System.print("s3 = %(s3)")

var s4 = "a" * 20 // * operator used to provide string repetition System.print("s4 = %(s4)")

var l1 = [1, 2, 3] + [4] // + operator used to concatenate two lists System.print("l1 = %(l1)")

var l2 = ["a"] * 8 // * operator used to create a new list by repeating another System.print("l2 = %(l2)")

// the user defined class Date overloads the - operator to provide the interval between two dates var d1 = Date.new(2021, 9, 11) var d2 = Date.new(2021, 9, 13) var i1 = (d2 - d1).days System.print("i1 = %(i1) days")</lang>

Output:
s3 = Rosetta code
s4 = aaaaaaaaaaaaaaaaaaaa
l1 = [1, 2, 3, 4]
l2 = [a, a, a, a, a, a, a, a]
i1 = 2 days