Implicit type conversion: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added personal tag)
m (syntax highlighting fixup automation)
Line 2: Line 2:
Some programming languages have [[wp:Type conversion#Implicit type conversion|implicit type conversion]]. Type conversion is also known as ''coercion''.
Some programming languages have [[wp:Type conversion#Implicit type conversion|implicit type conversion]]. Type conversion is also known as ''coercion''.


For example: <lang algol68>COMPL z := 1;</lang>Here the assignment "''':='''" implicitly converts the '''integer''' 1, to the '''complex''' number <math>1+0i</math> in the programming language [[ALGOL 68]].
For example: <syntaxhighlight lang="algol68">COMPL z := 1;</syntaxhighlight>Here the assignment "''':='''" implicitly converts the '''integer''' 1, to the '''complex''' number <math>1+0i</math> in the programming language [[ALGOL 68]].


The alternative would be to ''explicitly'' convert a value from one type to another, using a ''function'' or some other mechanism (e.g. an explicit cast).
The alternative would be to ''explicitly'' convert a value from one type to another, using a ''function'' or some other mechanism (e.g. an explicit cast).
Line 21: Line 21:


The X and Y registers can be used as loop counters, or as an indexed offset into memory. It's very common for both to be true in the same procedure.
The X and Y registers can be used as loop counters, or as an indexed offset into memory. It's very common for both to be true in the same procedure.
<lang 6502asm>memcpy:
<syntaxhighlight lang="6502asm">memcpy:
LDA ($00),y ;load from (the address stored at $0000) + y
LDA ($00),y ;load from (the address stored at $0000) + y
STA ($02),y ;write to (the address stored at $0002) + y
STA ($02),y ;write to (the address stored at $0002) + y
iny
iny
bne memcpy ;loop until y = 0
bne memcpy ;loop until y = 0
rts</lang>
rts</syntaxhighlight>


Any 16-bit value stored at a pair of consecutive zero-page memory addresses can be treated as a pointer to memory. The above example demonstrated this with the use of <code>($nn),y</code>.
Any 16-bit value stored at a pair of consecutive zero-page memory addresses can be treated as a pointer to memory. The above example demonstrated this with the use of <code>($nn),y</code>.
Line 34: Line 34:


For data registers, the operands are '''not''' sign-extended.
For data registers, the operands are '''not''' sign-extended.
<lang 68000devpac>MOVE.L #$FFFF,D0 ;MOVE.L #$0000FFFF,D0
<syntaxhighlight lang="68000devpac">MOVE.L #$FFFF,D0 ;MOVE.L #$0000FFFF,D0
MOVE.W #$23,D1 ;MOVE.W #$0023,D1
MOVE.W #$23,D1 ;MOVE.W #$0023,D1
MOVE.W #$80,D2 ;MOVE.W #$0080,D2</lang>
MOVE.W #$80,D2 ;MOVE.W #$0080,D2</syntaxhighlight>


The only exception to this is the <code>MOVEQ</code> instruction, which does sign-extend the value.
The only exception to this is the <code>MOVEQ</code> instruction, which does sign-extend the value.
<lang 68000devpac>MOVEQ #$34,D0 ;MOVE.L #$00000034,D0
<syntaxhighlight lang="68000devpac">MOVEQ #$34,D0 ;MOVE.L #$00000034,D0
MOVEQ #-1,D1 ;MOVE.L #$FFFFFFFF,D1</lang>
MOVEQ #-1,D1 ;MOVE.L #$FFFFFFFF,D1</syntaxhighlight>


Address registers mostly work the same way, unless you use <code>MOVEA.W</code>, in which the address ''is sign-extended.''
Address registers mostly work the same way, unless you use <code>MOVEA.W</code>, in which the address ''is sign-extended.''
<lang 68000devpac>MOVEA.L #$A01000,A0 ;assembled as MOVE.L #$00A01000,A0
<syntaxhighlight lang="68000devpac">MOVEA.L #$A01000,A0 ;assembled as MOVE.L #$00A01000,A0
MOVEA.W #$8000,A1 ;same result as MOVEA.L #$FFFF8000,A1
MOVEA.W #$8000,A1 ;same result as MOVEA.L #$FFFF8000,A1
MOVEA.W #$7FFF,A2 ;same result as MOVEA.L #$00007FFF,A2</lang>
MOVEA.W #$7FFF,A2 ;same result as MOVEA.L #$00007FFF,A2</syntaxhighlight>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Line 51: Line 51:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: implicit_type_conversion.a68'''<lang algol68>#!/usr/bin/a68g --script #
'''File: implicit_type_conversion.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 140: Line 140:
printf(($g$,"INT => UNION(VOID, INT) => UNION(VOID,INT,REAL,COMPL) - implicit uniting^3: ",(uuui|(INT i):i), $l$));
printf(($g$,"INT => UNION(VOID, INT) => UNION(VOID,INT,REAL,COMPL) - implicit uniting^3: ",(uuui|(INT i):i), $l$));
SKIP
SKIP
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 155: Line 155:
=={{header|Applesoft BASIC}}==
=={{header|Applesoft BASIC}}==
There are 7 types: reals, integers, strings, defined functions, floating point arrays, integer arrays, and arrays of strings. Implicitly there are only floating point (real) and strings.
There are 7 types: reals, integers, strings, defined functions, floating point arrays, integer arrays, and arrays of strings. Implicitly there are only floating point (real) and strings.
<lang gwbasic> 100 LET M$ = CHR$ (13)
<syntaxhighlight lang="gwbasic"> 100 LET M$ = CHR$ (13)
110 PRINT M$"SIMPLE VARIABLES"M$
110 PRINT M$"SIMPLE VARIABLES"M$
120 LET AB = 6728.0
120 LET AB = 6728.0
Line 179: Line 179:
320 PRINT "REAL TO STRING CONVERSION: ";AB$
320 PRINT "REAL TO STRING CONVERSION: ";AB$
330 LET AB = VAL("6728.0")
330 LET AB = VAL("6728.0")
340 PRINT "STRING TO REAL CONVERSION: ";AB</lang>
340 PRINT "STRING TO REAL CONVERSION: ";AB</syntaxhighlight>
=={{header|AWK}}==
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f IMPLICIT_TYPE_CONVERSION.AWK
# syntax: GAWK -f IMPLICIT_TYPE_CONVERSION.AWK
BEGIN {
BEGIN {
Line 194: Line 194:
exit(0)
exit(0)
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 203: Line 203:


=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
main(){
main(){
/* a representative sample of builtin types */
/* a representative sample of builtin types */
Line 238: Line 238:
printf("%LF was increasingly cast from %d from %d from %d from %d from %d bytes from '%c'\n",
printf("%LF was increasingly cast from %d from %d from %d from %d from %d bytes from '%c'\n",
llf=(lf=(i=(si=c))), sizeof llf, sizeof lf, sizeof i, sizeof si,sizeof c, c);
llf=(lf=(i=(si=c))), sizeof llf, sizeof lf, sizeof i, sizeof si,sizeof c, c);
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 246: Line 246:
=={{header|C sharp}}==
=={{header|C sharp}}==
C# has built-in implicit conversions for primitive numerical types. Any value can be implicitly converted to a value of a larger type. Many non-primitive types also have implicit conversion operators defined, for instance the '''BigInteger''' and '''Complex''' types.
C# has built-in implicit conversions for primitive numerical types. Any value can be implicitly converted to a value of a larger type. Many non-primitive types also have implicit conversion operators defined, for instance the '''BigInteger''' and '''Complex''' types.
<lang csharp>byte aByte = 2;
<syntaxhighlight lang="csharp">byte aByte = 2;
short aShort = aByte;
short aShort = aByte;
int anInt = aShort;
int anInt = aShort;
Line 256: Line 256:
BigInteger b = 5;
BigInteger b = 5;
Complex c = 2.5; // 2.5 + 0i
Complex c = 2.5; // 2.5 + 0i
</syntaxhighlight>
</lang>
Users are able to define implicit (and also explicit) conversion operators. To define a conversion from A to B, the operator must be defined inside either type A or type B. Therefore, we cannot define a conversion from '''char''' to an array of '''char'''.
Users are able to define implicit (and also explicit) conversion operators. To define a conversion from A to B, the operator must be defined inside either type A or type B. Therefore, we cannot define a conversion from '''char''' to an array of '''char'''.
<lang csharp>public class Person
<syntaxhighlight lang="csharp">public class Person
{
{
//Define an implicit conversion from string to Person
//Define an implicit conversion from string to Person
Line 270: Line 270:
Console.WriteLine(p);
Console.WriteLine(p);
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 279: Line 279:
C++ supports almost all of the same implicit conversions as the [[Implicit_type_conversion#C|C]] example above. However it does not allow implicit conversions to enums and is more strict with some pointer conversions. C++ allows implicit conversions on user defined
C++ supports almost all of the same implicit conversions as the [[Implicit_type_conversion#C|C]] example above. However it does not allow implicit conversions to enums and is more strict with some pointer conversions. C++ allows implicit conversions on user defined
types. The example below shows implicit conversions between polar and Cartesian points.
types. The example below shows implicit conversions between polar and Cartesian points.
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <math.h>
#include <math.h>


Line 335: Line 335:
std::cout << "rho=" << pp1.rho << ", theta=" << pp1.theta << "\n";
std::cout << "rho=" << pp1.rho << ", theta=" << pp1.theta << "\n";
std::cout << "x=" << cp2.x << ", y=" << cp2.y << "\n";
std::cout << "x=" << cp2.x << ", y=" << cp2.y << "\n";
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 344: Line 344:
=={{header|D}}==
=={{header|D}}==
This covers a large sample of built-in types and few library-defined types.
This covers a large sample of built-in types and few library-defined types.
<lang d>void main() {
<syntaxhighlight lang="d">void main() {
import std.stdio, std.typetuple, std.variant, std.complex;
import std.stdio, std.typetuple, std.variant, std.complex;


Line 426: Line 426:
void function() f6 = &spam; // OK.
void function() f6 = &spam; // OK.
//void function() f7 = &foo; // Not allowed.
//void function() f7 = &foo; // Not allowed.
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>On a 32 bit system:
<pre>On a 32 bit system:
Line 498: Line 498:
Delphi has in implicit conversions for primitive numerical types. Any value can be implicitly converted to a value of a larger type.
Delphi has in implicit conversions for primitive numerical types. Any value can be implicitly converted to a value of a larger type.
Upsize conversions:
Upsize conversions:
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueByte : Byte := 2; // (8 bits size)
ValueByte : Byte := 2; // (8 bits size)
ValueWord : Word := ValueByte; // 2 (16 bits size)
ValueWord : Word := ValueByte; // 2 (16 bits size)
ValueDWord : DWord := ValueWord; // 2 (32 bits size)
ValueDWord : DWord := ValueWord; // 2 (32 bits size)
ValueUint64 : Uint64 := ValueWord; // 2 (64 bits size)
ValueUint64 : Uint64 := ValueWord; // 2 (64 bits size)
</syntaxhighlight>
</lang>
Unsigend-signed conversions
Unsigend-signed conversions
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueInteger : Integer := ValueDWord; // -1 (two complement conversion) (signed)
ValueInteger : Integer := ValueDWord; // -1 (two complement conversion) (signed)
ValueDWord := ValueInteger; // 4294967295 (convert back, unsigned)
ValueDWord := ValueInteger; // 4294967295 (convert back, unsigned)
</syntaxhighlight>
</lang>
Unsigned variables will not convert literal negative values
Unsigned variables will not convert literal negative values
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueByte := -1; // this not work, and raise a error
ValueByte := -1; // this not work, and raise a error
ValueByte := byte(-1); // this work, and assign 255 (max byte value)
ValueByte := byte(-1); // this work, and assign 255 (max byte value)
</syntaxhighlight>
</lang>
Float points can convert integers values, may lose precision for large integers
Float points can convert integers values, may lose precision for large integers
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueDouble : Double := ValueDWord; // 4.29496729500000E+0009
ValueDouble : Double := ValueDWord; // 4.29496729500000E+0009
</syntaxhighlight>
</lang>
Integers can not convert float values implicity
Integers can not convert float values implicity
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDouble := 1.6;
ValueDouble := 1.6;
ValueByte := ValueDouble; // this not work, and raise a error
ValueByte := ValueDouble; // this not work, and raise a error
ValueByte : Trunc(ValueDouble); // this work, and assign 1
ValueByte : Trunc(ValueDouble); // this work, and assign 1
ValueByte : Round(ValueDouble); // this work, and assign 2
ValueByte : Round(ValueDouble); // this work, and assign 2
</syntaxhighlight>
</lang>
Strings can convert chars, but not convert back
Strings can convert chars, but not convert back
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueChar: Char := #10;
ValueChar: Char := #10;
ValuesString: String := ValueChar;
ValuesString: String := ValueChar;
</syntaxhighlight>
</lang>
Boolean can not convert any type implicity, except it self
Boolean can not convert any type implicity, except it self
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueBoolean: Boolean := True; // this work, and assign True
ValueBoolean: Boolean := True; // this work, and assign True
ValueBoolean: Boolean := 1; // this not work, and raise a error
ValueBoolean: Boolean := 1; // this not work, and raise a error
Line 541: Line 541:
ValueBoolean := Boolean(-1); // this work, and assign true
ValueBoolean := Boolean(-1); // this work, and assign true
ValueBoolean := Boolean( 0); // this work, and assign false
ValueBoolean := Boolean( 0); // this work, and assign false
</syntaxhighlight>
</lang>
Variant types can implicit convert allmost types, and convert back, if possible:
Variant types can implicit convert allmost types, and convert back, if possible:
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueVariant: Variant := -20;
ValueVariant: Variant := -20;
ValueVariant := 3.1416;
ValueVariant := 3.1416;
Line 550: Line 550:
ValueVariant := True;
ValueVariant := True;
...
...
</syntaxhighlight>
</lang>
Class and Record can implement implicit operator
Class and Record can implement implicit operator
<syntaxhighlight lang="delphi">
<lang Delphi>
program Implicit_type_conversion;
program Implicit_type_conversion;


Line 632: Line 632:


readln;
readln;
end.</lang>
end.</syntaxhighlight>
=={{header|Déjà Vu}}==
=={{header|Déjà Vu}}==


The only implicit conversion currently permitted is boolean to number:
The only implicit conversion currently permitted is boolean to number:


<lang dejavu><1:1> #interactive session
<syntaxhighlight lang="dejavu"><1:1> #interactive session
<2:1> !. + 3 true #boolean true is equal to 1
<2:1> !. + 3 true #boolean true is equal to 1
4
4
<3:1> !. * 2 false #boolean false is equal to 0
<3:1> !. * 2 false #boolean false is equal to 0
0</lang>
0</syntaxhighlight>




Line 650: Line 650:


All ZString expressions, including string literals and dereferenced ZString Ptrs, will be given the String variable type.
All ZString expressions, including string literals and dereferenced ZString Ptrs, will be given the String variable type.
<lang freebasic>Var a = Cast(Byte, 1)
<syntaxhighlight lang="freebasic">Var a = Cast(Byte, 1)
Var b = Cast(Short, 1)
Var b = Cast(Short, 1)
Var c = Cast(Integer, 1)
Var c = Cast(Integer, 1)
Line 682: Line 682:
Print
Print
Print "Integer: "; ii
Print "Integer: "; ii
Print "Double: "; id</lang>
Print "Double: "; id</syntaxhighlight>
{{out}}
{{out}}
<pre>Byte: 1
<pre>Byte: 1
Line 726: Line 726:


Some simple examples may help to make this clearer.
Some simple examples may help to make this clearer.
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 766: Line 766:
m := 0.3 + float64(l) + 0.7
m := 0.3 + float64(l) + 0.7
fmt.Printf("m : type %-7T value %g\n", m, m)
fmt.Printf("m : type %-7T value %g\n", m, m)
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 781: Line 781:
Idris provides the "[http://docs.idris-lang.org/en/latest/tutorial/miscellany.html#implicit-conversions implicit]" keyword which enables the implicit conversion from one type to another.
Idris provides the "[http://docs.idris-lang.org/en/latest/tutorial/miscellany.html#implicit-conversions implicit]" keyword which enables the implicit conversion from one type to another.


<lang idris>implicit
<syntaxhighlight lang="idris">implicit
boolToInt : Bool -> Int
boolToInt : Bool -> Int
boolToInt True = 1
boolToInt True = 1
Line 790: Line 790:


two : Int
two : Int
two = one + True</lang>
two = one + True</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
Line 818: Line 818:


The rich j datatypes:
The rich j datatypes:
<syntaxhighlight lang="j">
<lang J>
datatype NB. data type identification verb
datatype NB. data type identification verb
3 : 0
3 : 0
Line 869: Line 869:
2 2 │ 2
2 2 │ 2
3 3 │ 2
3 3 │ 2
</syntaxhighlight>
</lang>


J has verbs causing explicit conversion. Some appear in the above examples.
J has verbs causing explicit conversion. Some appear in the above examples.
Line 892: Line 892:
=={{header|Java}}==
=={{header|Java}}==
The Java Language Specification includes several varieties of implicit type conversion. This code illustrates: <ul><li>widening conversions of primitives</li><li>boxing and unboxing conversions</li><li>string conversions (with the + operator)</li></ul>
The Java Language Specification includes several varieties of implicit type conversion. This code illustrates: <ul><li>widening conversions of primitives</li><li>boxing and unboxing conversions</li><li>string conversions (with the + operator)</li></ul>
<lang java>public class ImplicitTypeConversion{
<syntaxhighlight lang="java">public class ImplicitTypeConversion{
public static void main(String...args){
public static void main(String...args){
System.out.println( "Primitive conversions" );
System.out.println( "Primitive conversions" );
Line 931: Line 931:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 968: Line 968:


However, if one were to define "is_integer" as follows:
However, if one were to define "is_integer" as follows:
<lang jq>def is_integer: type == "number" and . == floor;</lang>
<syntaxhighlight lang="jq">def is_integer: type == "number" and . == floor;</syntaxhighlight>


then one would find:
then one would find:
<lang jq>(1/3) | is_integer # yields false
<syntaxhighlight lang="jq">(1/3) | is_integer # yields false


(1/3 + 1/3 + 1/3) | is_integer # yields true</lang>
(1/3 + 1/3 + 1/3) | is_integer # yields true</syntaxhighlight>


For reference, jq's builtin types are "number", "boolean", "null", "object" and "array".
For reference, jq's builtin types are "number", "boolean", "null", "object" and "array".
Line 979: Line 979:
=={{header|Julia}}==
=={{header|Julia}}==
In general, Julia will promote a smaller sized datatype to a larger one when needed for a calculation involving mixed data types. Julia also accepts type annotations on variable declarations as shown below, though such type declarations are usually only allowed for variables that are declared within a function.
In general, Julia will promote a smaller sized datatype to a larger one when needed for a calculation involving mixed data types. Julia also accepts type annotations on variable declarations as shown below, though such type declarations are usually only allowed for variables that are declared within a function.
<lang julia>
<syntaxhighlight lang="julia">
julia> function testme()
julia> function testme()
ui8::UInt8 = 1
ui8::UInt8 = 1
Line 992: Line 992:
julia> testme()
julia> testme()
(0x01, 1, 0x0001, 2, 0x00000001, 4, 0x0000000000000001, 8, 1.0, 8)
(0x01, 1, 0x0001, 2, 0x00000001, 4, 0x0000000000000001, 8, 1.0, 8)
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 998: Line 998:


If follows from this that there are no implicit conversions (even 'widening' conversions) between the numeric types because there is no inheritance relationship between them. However, there is one exception to this - integer literals, which would normally be regarded as of type Int (4 bytes) can be assigned to variables of the other integral types provided they are within the range of that type. This is allowed because it can be checked statically by the compiler.
If follows from this that there are no implicit conversions (even 'widening' conversions) between the numeric types because there is no inheritance relationship between them. However, there is one exception to this - integer literals, which would normally be regarded as of type Int (4 bytes) can be assigned to variables of the other integral types provided they are within the range of that type. This is allowed because it can be checked statically by the compiler.
<lang scala>// version 1.1.2
<syntaxhighlight lang="scala">// version 1.1.2


open class C(val x: Int)
open class C(val x: Int)
Line 1,015: Line 1,015:
val n : Int? = c.x // OK because Int is a sub-class of its nullable type Int? (c.x is boxed on heap)
val n : Int? = c.x // OK because Int is a sub-class of its nullable type Int? (c.x is boxed on heap)
println(n)
println(n)
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
Line 1,029: Line 1,029:
For the most part, Lua is strongly typed, but there are a few cases where it will coerce if the result would be of a predictable type.
For the most part, Lua is strongly typed, but there are a few cases where it will coerce if the result would be of a predictable type.
Coercions are never performed during comparisons or while indexing an object.
Coercions are never performed during comparisons or while indexing an object.
<lang lua>-- During concatenation, numbers are always converted to strings. arithmetic operations will attempt to coerce strings to numbers, or throw an error if they can't
<syntaxhighlight lang="lua">-- During concatenation, numbers are always converted to strings. arithmetic operations will attempt to coerce strings to numbers, or throw an error if they can't
type(123 .. "123") --> string
type(123 .. "123") --> string
type(123 + "123") --> number
type(123 + "123") --> number
Line 1,042: Line 1,042:


-- As in many languages, all types can be automatically coerced into their boolean value if required. Only nil and false will coerce to false
-- As in many languages, all types can be automatically coerced into their boolean value if required. Only nil and false will coerce to false
print(not not nil, not not false, not not 1, not not "foo", not not { }) --> false false true true true</lang>
print(not not nil, not not false, not not 1, not not "foo", not not { }) --> false false true true true</syntaxhighlight>


The only two explicit conversion functions offered by Lua are <code>tonumber</code> and <code>tostring</code>.
The only two explicit conversion functions offered by Lua are <code>tonumber</code> and <code>tostring</code>.
Line 1,048: Line 1,048:


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Module Checkit {
Long a=12.5
Long a=12.5
Line 1,106: Line 1,106:
}
}
Checkit
Checkit
</syntaxhighlight>
</lang>


=={{header|Nim}}==
=={{header|Nim}}==
Line 1,125: Line 1,125:
Here are some examples:
Here are some examples:


<syntaxhighlight lang="nim">
<lang Nim>
const A = 1 # "1" is considered as as int, so this is the type of "x".
const A = 1 # "1" is considered as as int, so this is the type of "x".
const B: float = 1 # Implicit conversion from int to float done by the compiler.
const B: float = 1 # Implicit conversion from int to float done by the compiler.
Line 1,168: Line 1,168:


echo 1 + true # Displays 2.
echo 1 + true # Displays 2.
if 2: echo "ok" # Displays "ok".</lang>
if 2: echo "ok" # Displays "ok".</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==
Line 1,192: Line 1,192:
Let's create a Complex class with 80 as priority (please note asComplex methods that will be used for conversions) :
Let's create a Complex class with 80 as priority (please note asComplex methods that will be used for conversions) :


<lang Oforth>100 Number Class newPriority: Complex(re, im)
<syntaxhighlight lang="oforth">100 Number Class newPriority: Complex(re, im)
Complex method: re @re ;
Complex method: re @re ;
Line 1,218: Line 1,218:
Complex new(@re n /, @im neg n / ) ;
Complex new(@re n /, @im neg n / ) ;


Complex method: /(c) c self inv * ;</lang>
Complex method: /(c) c self inv * ;</syntaxhighlight>


Usage :
Usage :


<lang Oforth>2 3.2 I * + println
<syntaxhighlight lang="oforth">2 3.2 I * + println
Complex new(2, 3) 1.2 + println
Complex new(2, 3) 1.2 + println
Complex new(2, 3) 1.2 * println
Complex new(2, 3) 1.2 * println
2 Complex new(2, 3) / println</lang>
2 Complex new(2, 3) / println</syntaxhighlight>


{{out}}
{{out}}
Line 1,244: Line 1,244:


=={{header|Pascal}}==
=={{header|Pascal}}==
<lang pascal>program implicitTypeConversion;
<syntaxhighlight lang="pascal">program implicitTypeConversion;
var
var
i: integer;
i: integer;
Line 1,251: Line 1,251:
i := 42;
i := 42;
r := i { integer → real }
r := i { integer → real }
end.</lang>
end.</syntaxhighlight>
{{works with|Extended Pascal}}
{{works with|Extended Pascal}}
<lang pascal>program additionalImplicitTypeConversionInExtendedPascal;
<syntaxhighlight lang="pascal">program additionalImplicitTypeConversionInExtendedPascal;
var
var
c: char;
c: char;
Line 1,269: Line 1,269:
r := 123.456;
r := 123.456;
x := r { real → complex }
x := r { real → complex }
end.</lang>
end.</syntaxhighlight>
All available implicit conversions are applicable when providing parameters to a routine call.
All available implicit conversions are applicable when providing parameters to a routine call.
For instance the Extended Pascal function <tt>im</tt> intended to return the imaginary part of a <tt>complex</tt> number can be called with an <tt>integer</tt> value.
For instance the Extended Pascal function <tt>im</tt> intended to return the imaginary part of a <tt>complex</tt> number can be called with an <tt>integer</tt> value.
Line 1,278: Line 1,278:
=={{header|Perl}}==
=={{header|Perl}}==
Perl is the original DWIM language, implicit type conversion is the default mode of operation. Perl does not have static types; the concept of distinct integers/strings/floats is not present. Instead, operators defines how the operands will behave. An operator that requires a string coerces its operand into a string, an operator that requires an integer coerces its operand into an integer, and so forth.
Perl is the original DWIM language, implicit type conversion is the default mode of operation. Perl does not have static types; the concept of distinct integers/strings/floats is not present. Instead, operators defines how the operands will behave. An operator that requires a string coerces its operand into a string, an operator that requires an integer coerces its operand into an integer, and so forth.
<lang perl>print 1 + '2'; # 3
<syntaxhighlight lang="perl">print 1 + '2'; # 3
print '1' + '2'; # 3
print '1' + '2'; # 3
print 1 . 1; # 11
print 1 . 1; # 11
Line 1,287: Line 1,287:


# Even if you intentionally jumble the expected roles of numbers and strings, thing just work out
# Even if you intentionally jumble the expected roles of numbers and strings, thing just work out
say hex int( (2 . 0 x '2') ** substr 98.5, '2', '2' ) . 'beef'; # 1359599</lang>
say hex int( (2 . 0 x '2') ** substr 98.5, '2', '2' ) . 'beef'; # 1359599</syntaxhighlight>


On the other hand, since Perl gives you a lot of rope, you have to be careful what you do with it. The expression
On the other hand, since Perl gives you a lot of rope, you have to be careful what you do with it. The expression
Line 1,299: Line 1,299:
If a string character (or slice) is replaced with any value that will not fit in a byte, it is automatically
If a string character (or slice) is replaced with any value that will not fit in a byte, it is automatically
converted to a dword_sequence, eg
converted to a dword_sequence, eg
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"this"</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"this"</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">PI</span> <span style="color: #000080;font-style:italic;">-- s is now {'t','h',3.1415926,'s'}</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">PI</span> <span style="color: #000080;font-style:italic;">-- s is now {'t','h',3.1415926,'s'}</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
Phix does not, or at least tries very hard not to "drop bits" or "clock round". 1/3 is 0.333333 not 0, 0-1 is
Phix does not, or at least tries very hard not to "drop bits" or "clock round". 1/3 is 0.333333 not 0, 0-1 is
-1 not +#FFFFFFFF, in all cases, with a plain english fatal run-time error should a type check occur, as would occur above were s defined as a string instead of a sequence.
-1 not +#FFFFFFFF, in all cases, with a plain english fatal run-time error should a type check occur, as would occur above were s defined as a string instead of a sequence.
Line 1,308: Line 1,308:
=={{header|Python}}==
=={{header|Python}}==
Python does do some automatic conversions between different types but is still considered a strongly typed language. Allowed automatic conversions include between numeric types (where it makes sense), and the general rule that empty container types as well as zero are considered False in a boolean context.
Python does do some automatic conversions between different types but is still considered a strongly typed language. Allowed automatic conversions include between numeric types (where it makes sense), and the general rule that empty container types as well as zero are considered False in a boolean context.
<lang python>from fractions import Fraction
<syntaxhighlight lang="python">from fractions import Fraction
from decimal import Decimal, getcontext
from decimal import Decimal, getcontext
getcontext().prec = 60
getcontext().prec = 60
Line 1,356: Line 1,356:
except BaseException:
except BaseException:
ans = 'EXCEPTION RAISED!'
ans = 'EXCEPTION RAISED!'
print('%-60s -> %r' % ('%s(%r)' % (f.__name__, e), ans))</lang>
print('%-60s -> %r' % ('%s(%r)' % (f.__name__, e), ans))</syntaxhighlight>


{{out}} (Elided due to size)
{{out}} (Elided due to size)
Line 1,482: Line 1,482:
=={{header|Racket}}==
=={{header|Racket}}==
The only automatic conversions are in the numeric tower. The common case is in some operations like <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, when one of the arguments is of a different type of the other argument. For example, in all the following cases the fixnum <code>1</code> is added to more general kinds of numbers.
The only automatic conversions are in the numeric tower. The common case is in some operations like <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, when one of the arguments is of a different type of the other argument. For example, in all the following cases the fixnum <code>1</code> is added to more general kinds of numbers.
<lang Racket>#lang racket
<syntaxhighlight lang="racket">#lang racket


(+ 1 .1) ; ==> 1.1
(+ 1 .1) ; ==> 1.1
Line 1,488: Line 1,488:
(+ 1 1/2) ; ==> 3/2
(+ 1 1/2) ; ==> 3/2
(+ 1 (expt 10 30)) ; ==> 1000000000000000000000000000001
(+ 1 (expt 10 30)) ; ==> 1000000000000000000000000000001
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
Line 1,505: Line 1,505:
The type of object contained in a scalar depends on how you assign it and how you use it.
The type of object contained in a scalar depends on how you assign it and how you use it.


<lang perl6>my $x;
<syntaxhighlight lang="raku" line>my $x;


$x = 1234; say $x.WHAT; # (Int) Integer
$x = 1234; say $x.WHAT; # (Int) Integer
Line 1,519: Line 1,519:
$x = {1, 2}; say $x.WHAT; # (Block)
$x = {1, 2}; say $x.WHAT; # (Block)
$x = sub {1}; say $x.WHAT; # (Sub) Code Reference
$x = sub {1}; say $x.WHAT; # (Sub) Code Reference
$x = True; say $x.WHAT; # (Bool) Boolean</lang>
$x = True; say $x.WHAT; # (Bool) Boolean</syntaxhighlight>




Objects may be converted between various types many times during an operation. Consider the following line of code.
Objects may be converted between various types many times during an operation. Consider the following line of code.


<lang perl6>say :16(([+] 1234.ords).sqrt.floor ~ "beef");</lang>
<syntaxhighlight lang="raku" line>say :16(([+] 1234.ords).sqrt.floor ~ "beef");</syntaxhighlight>


In English: Take the floor of the square root of the sum of the ordinals of the digits of the integer 1234, concatenate that number with the string 'beef', interpret the result as a hexadecimal number and print it.
In English: Take the floor of the square root of the sum of the ordinals of the digits of the integer 1234, concatenate that number with the string 'beef', interpret the result as a hexadecimal number and print it.
Line 1,530: Line 1,530:
Broken down step by step:
Broken down step by step:


<lang perl6>my $x = 1234; say $x, ' ', $x.WHAT; # 1234 (Int)
<syntaxhighlight lang="raku" line>my $x = 1234; say $x, ' ', $x.WHAT; # 1234 (Int)
$x = 1234.ords; say $x, ' ', $x.WHAT; # 49 50 51 52 (List)
$x = 1234.ords; say $x, ' ', $x.WHAT; # 49 50 51 52 (List)
$x = [+] 1234.ords; say $x, ' ', $x.WHAT; # 202 (Int)
$x = [+] 1234.ords; say $x, ' ', $x.WHAT; # 202 (Int)
Line 1,536: Line 1,536:
$x = ([+] 1234.ords).sqrt.floor; say $x, ' ', $x.WHAT; # 14 (Int)
$x = ([+] 1234.ords).sqrt.floor; say $x, ' ', $x.WHAT; # 14 (Int)
$x = ([+] 1234.ords).sqrt.floor ~ "beef"; say $x, ' ', $x.WHAT; # 14beef (Str)
$x = ([+] 1234.ords).sqrt.floor ~ "beef"; say $x, ' ', $x.WHAT; # 14beef (Str)
$x = :16(([+] 1234.ords).sqrt.floor ~ "beef"); say $x, ' ', $x.WHAT; # 1359599 (Int)</lang>
$x = :16(([+] 1234.ords).sqrt.floor ~ "beef"); say $x, ' ', $x.WHAT; # 1359599 (Int)</syntaxhighlight>




Line 1,543: Line 1,543:
(A normal Rat number has a denominator that is limited to 64 bits, with underflow to floating point to prevent performance degradation; a FatRat, in contrast, has an unlimited denominator size, and can chew up all your memory if you're not careful.)
(A normal Rat number has a denominator that is limited to 64 bits, with underflow to floating point to prevent performance degradation; a FatRat, in contrast, has an unlimited denominator size, and can chew up all your memory if you're not careful.)


<lang perl6>my $x;
<syntaxhighlight lang="raku" line>my $x;
$x = (-1).sqrt; say $x, ' ', $x.WHAT; # NaN (Num)
$x = (-1).sqrt; say $x, ' ', $x.WHAT; # NaN (Num)
$x = (-1).Complex.sqrt; say $x, ' ', $x.WHAT; # 6.12323399573677e-17+1i (Complex)
$x = (-1).Complex.sqrt; say $x, ' ', $x.WHAT; # 6.12323399573677e-17+1i (Complex)
Line 1,554: Line 1,554:
$x /= 10**10; say $x, ' ', $x.WHAT; # 0.000000000629 (FatRat)
$x /= 10**10; say $x, ' ', $x.WHAT; # 0.000000000629 (FatRat)
$x /= 10**10; say $x, ' ', $x.WHAT; # 0.0000000000000000000629 (FatRat)
$x /= 10**10; say $x, ' ', $x.WHAT; # 0.0000000000000000000629 (FatRat)
</syntaxhighlight>
</lang>


User defined types will support implicit casting if the object has Bridge method that tells it how to do so, or if the operators in question supply multiple dispatch variants that allow for coercions.
User defined types will support implicit casting if the object has Bridge method that tells it how to do so, or if the operators in question supply multiple dispatch variants that allow for coercions.
Line 1,591: Line 1,591:
╚═══════════════════════════════════════════════════════════════════════════════════╝
╚═══════════════════════════════════════════════════════════════════════════════════╝
</pre>
</pre>
<lang rexx>/*REXX program demonstrates various ways REXX can convert and/or normalize some numbers.*/
<syntaxhighlight lang="rexx">/*REXX program demonstrates various ways REXX can convert and/or normalize some numbers.*/
digs=digits() ; say digs /* 9, the default.*/
digs=digits() ; say digs /* 9, the default.*/


Line 1,610: Line 1,610:
a=1e+003 ; b=0 ; x=a+b ; say x /* 1000 */
a=1e+003 ; b=0 ; x=a+b ; say x /* 1000 */
a=12345678912 ; say a /* 123456789012 */
a=12345678912 ; say a /* 123456789012 */
a=12345678912 ; b=0 ; x=a+b ; say x /* 1.23456789E+10 */</lang>
a=12345678912 ; b=0 ; x=a+b ; say x /* 1.23456789E+10 */</syntaxhighlight>
'''output'''
'''output'''
<pre>
<pre>
Line 1,638: Line 1,638:
=={{header|Sidef}}==
=={{header|Sidef}}==
Since version 3.00, all the number types (int, rat, float and complex) are unified in the ''Number'' class and all the needed conversions are done implicitly. Methods from other classes also make implicit conversions where possible.
Since version 3.00, all the number types (int, rat, float and complex) are unified in the ''Number'' class and all the needed conversions are done implicitly. Methods from other classes also make implicit conversions where possible.
<lang ruby>> 1+"2" #=> 3
<syntaxhighlight lang="ruby">> 1+"2" #=> 3
> "1"+2 #=> 12
> "1"+2 #=> 12
> sqrt(-4) #=> 2i
> sqrt(-4) #=> 2i
> ("a" + [1,2]) #=> a[1,2]
> ("a" + [1,2]) #=> a[1,2]
> ('ha' * '3') #=> hahaha
> ('ha' * '3') #=> hahaha
> ('ha' * true) #=> ha</lang>
> ('ha' * true) #=> ha</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
Line 1,650: Line 1,650:
The only true explicit type conversion operations are some of the functions in the expression sub-language (<code>int()</code>, <code>double()</code>, etc.).
The only true explicit type conversion operations are some of the functions in the expression sub-language (<code>int()</code>, <code>double()</code>, etc.).


;Integer conversion:<lang tcl>set value "123"
;Integer conversion:<syntaxhighlight lang="tcl">set value "123"
incr someVar $value
incr someVar $value
# $value will now hold an integer (strictly, one of many integer-related types) with value 123</lang>
# $value will now hold an integer (strictly, one of many integer-related types) with value 123</syntaxhighlight>


;Float conversion:<lang tcl>set value "1.23"
;Float conversion:<syntaxhighlight lang="tcl">set value "1.23"
expr {$value + 3.5}
expr {$value + 3.5}
# $value will now hold a double-precision IEEE floating point number that is (approx.) 1.23</lang><!-- IEEE binary floats can't hold the value exactly -->
# $value will now hold a double-precision IEEE floating point number that is (approx.) 1.23</syntaxhighlight><!-- IEEE binary floats can't hold the value exactly -->


;String conversion:<lang tcl>set value [expr {123 + 456}]
;String conversion:<syntaxhighlight lang="tcl">set value [expr {123 + 456}]
string length $value
string length $value
# $value will now hold a string (of length 3)</lang>
# $value will now hold a string (of length 3)</syntaxhighlight>


;List conversion:<lang tcl>set value {a b c d}
;List conversion:<syntaxhighlight lang="tcl">set value {a b c d}
llength $value
llength $value
# $value will now hold a list (of length 4)</lang>
# $value will now hold a list (of length 4)</syntaxhighlight>


;Dictionary conversion:<lang tcl>set value {a b c d}
;Dictionary conversion:<syntaxhighlight lang="tcl">set value {a b c d}
dict size $value
dict size $value
# $value will now hold a dictionary (of size 2)</lang>
# $value will now hold a dictionary (of size 2)</syntaxhighlight>
There are many other value types (command names, variable names, subcommand index names, etc.) but user code would not normally seek to explicitly convert to those.
There are many other value types (command names, variable names, subcommand index names, etc.) but user code would not normally seek to explicitly convert to those.


Line 1,684: Line 1,684:


However, you can define implicit conversions for user defined types. For example, BigInts can be generated from integral Nums or Strings and, when doing operations on BigInts, values of these types are automatically converted to BigInts so the operations can succeed.
However, you can define implicit conversions for user defined types. For example, BigInts can be generated from integral Nums or Strings and, when doing operations on BigInts, values of these types are automatically converted to BigInts so the operations can succeed.
<lang ecmascript>import "./big" for BigInt
<syntaxhighlight lang="ecmascript">import "./big" for BigInt


var b1 = BigInt.new(32)
var b1 = BigInt.new(32)
Line 1,690: Line 1,690:


var b3 = b1 + b2 + 2 + "2"
var b3 = b1 + b2 + 2 + "2"
System.print(b3) // 100</lang>
System.print(b3) // 100</syntaxhighlight>


=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
Line 1,697: Line 1,697:
When a constant or 16-bit register is used as an operand and is in parentheses, it is treated as a pointer to memory for that instruction only. The type of the data pointed to depends on the instruction.
When a constant or 16-bit register is used as an operand and is in parentheses, it is treated as a pointer to memory for that instruction only. The type of the data pointed to depends on the instruction.


<lang z80>LD HL,$4000 ;load HL with the number 0x4000
<syntaxhighlight lang="z80">LD HL,$4000 ;load HL with the number 0x4000
LD A,(HL) ;load the byte stored at memory address 0x4000 into A.
LD A,(HL) ;load the byte stored at memory address 0x4000 into A.


LD DE,($C000) ;load DE with the 16-bit value stored at $C000.</lang>
LD DE,($C000) ;load DE with the 16-bit value stored at $C000.</syntaxhighlight>


'''Note:''' The Game Boy cannot use 16-bit constant pointers, with two exceptions:
'''Note:''' The Game Boy cannot use 16-bit constant pointers, with two exceptions:
Line 1,710: Line 1,710:


The individual 8-bit registers that form a register pair can be operated on separately, or as a single 16-bit value.
The individual 8-bit registers that form a register pair can be operated on separately, or as a single 16-bit value.
<lang z80>LD BC,$1234
<syntaxhighlight lang="z80">LD BC,$1234
INC B ;BC = $1334
INC B ;BC = $1334
INC C ;BC = $1335
INC C ;BC = $1335
INC BC ;BC = $1336</lang>
INC BC ;BC = $1336</syntaxhighlight>


=={{header|zkl}}==
=={{header|zkl}}==
Type conversions usually just happen (ie the object knows what it wants and attempts to convert) but sometimes the conversion needs to be explicit (ie the conversion is ambiguous, the object doesn't know about the other type or is too lazy to convert).
Type conversions usually just happen (ie the object knows what it wants and attempts to convert) but sometimes the conversion needs to be explicit (ie the conversion is ambiguous, the object doesn't know about the other type or is too lazy to convert).
<lang zkl>zkl: 1+"2"
<syntaxhighlight lang="zkl">zkl: 1+"2"
3
3
zkl: "1"+2
zkl: "1"+2
Line 1,731: Line 1,731:
zkl: T("one",1,"two",2).toDictionary().toList().toDictionary()
zkl: T("one",1,"two",2).toDictionary().toList().toDictionary()
D(two:2,one:1)
D(two:2,one:1)
etc</lang>
etc</syntaxhighlight>


{{omit from|6502 Assembly}}
{{omit from|6502 Assembly}}