Implicit type conversion: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(20 intermediate revisions by 13 users not shown)
Line 2:
Some programming languages have [[wp:Type conversion#Implicit type conversion|implicit type conversion]]. Type conversion is also known as ''coercion''.
 
For example: <langsyntaxhighlight lang="algol68">COMPL z := 1;</langsyntaxhighlight>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).
Line 16:
Indicate if your language supports ''user defined'' type conversion definitions and give an example of such a definition. &nbsp; (E.g. define an ''implicit type conversion'' from '''real''' to '''complex''' numbers, or from '''char''' to an array of '''char''' of length 1.)
<br><br>
 
=={{header|6502 Assembly}}==
There is no implicit type conversion in the "modern" sense. However, you are free to interpret any bit pattern to mean whatever you want, when you want. A few language constructs help with this.
 
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.
<syntaxhighlight lang="6502asm">memcpy:
LDA ($00),y ;load from (the address stored at $0000) + y
STA ($02),y ;write to (the address stored at $0002) + y
iny
bne memcpy ;loop until y = 0
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>.
 
=={{header|68000 Assembly}}==
If an instruction operand is smaller than the instruction "length", then it gets typecast to that length.
 
For data registers, the operands are '''not''' sign-extended.
<syntaxhighlight lang="68000devpac">MOVE.L #$FFFF,D0 ;MOVE.L #$0000FFFF,D0
MOVE.W #$23,D1 ;MOVE.W #$0023,D1
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.
<syntaxhighlight lang="68000devpac">MOVEQ #$34,D0 ;MOVE.L #$00000034,D0
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.''
<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 #$7FFF,A2 ;same result as MOVEA.L #$00007FFF,A2</syntaxhighlight>
 
=={{header|ALGOL 68}}==
Line 21 ⟶ 51:
{{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''.}}
'''File: implicit_type_conversion.a68'''<langsyntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
Line 110 ⟶ 140:
printf(($g$,"INT => UNION(VOID, INT) => UNION(VOID,INT,REAL,COMPL) - implicit uniting^3: ",(uuui|(INT i):i), $l$));
SKIP
)</langsyntaxhighlight>
{{out}}
<pre>
Line 123 ⟶ 153:
</pre>
 
=={{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.
<syntaxhighlight lang="gwbasic"> 100 LET M$ = CHR$ (13)
110 PRINT M$"SIMPLE VARIABLES"M$
120 LET AB = 6728.0
130 PRINT "FLOATING POINT: ";AB
140 LET AB% = 6728.0
150 PRINT "INTEGER: ";AB%
160 LET AB$ = "HELLO"
170 PRINT "STRING: ";AB$
180 DEF FN AB(AB) = AB + 6728.0 - VAL (".")
190 PRINT "DEFINED FUNCTION: "; FN AB(0)
200 PRINT M$"ARRAY VARIABLES"M$
210 DIM AB(3,12,7)
220 LET AB(3,12,7) = 6728.0
230 PRINT "FLOATING POINT: ";AB(3,12,7)
240 DIM AB%(3,12,7)
250 LET AB%(3,12,7) = 6728.0
260 PRINT "INTEGER: ";AB%(3,12,7)
270 DIM AB$(3,12,7)
280 LET AB$(3,12,7) = "HELLO"
290 PRINT "STRING: ";AB$(3,12,7)
300 PRINT M$"TYPE CONVERSIONS"M$
310 LET AB$ = STR$(6728.0)
320 PRINT "REAL TO STRING CONVERSION: ";AB$
330 LET AB = VAL("6728.0")
340 PRINT "STRING TO REAL CONVERSION: ";AB</syntaxhighlight>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f IMPLICIT_TYPE_CONVERSION.AWK
BEGIN {
Line 137 ⟶ 194:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 146 ⟶ 203:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
main(){
/* a representative sample of builtin types */
Line 181 ⟶ 238:
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);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 189 ⟶ 246:
=={{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.
<langsyntaxhighlight lang="csharp">byte aByte = 2;
short aShort = aByte;
int anInt = aShort;
Line 199 ⟶ 256:
BigInteger b = 5;
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'''.
<langsyntaxhighlight lang="csharp">public class Person
{
//Define an implicit conversion from string to Person
Line 213 ⟶ 270:
Console.WriteLine(p);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 222 ⟶ 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
types. The example below shows implicit conversions between polar and Cartesian points.
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <math.h>
 
Line 278 ⟶ 335:
std::cout << "rho=" << pp1.rho << ", theta=" << pp1.theta << "\n";
std::cout << "x=" << cp2.x << ", y=" << cp2.y << "\n";
}</langsyntaxhighlight>
{{out}}
<pre>
Line 287 ⟶ 344:
=={{header|D}}==
This covers a large sample of built-in types and few library-defined types.
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.typetuple, std.variant, std.complex;
 
Line 369 ⟶ 426:
void function() f6 = &spam; // OK.
//void function() f7 = &foo; // Not allowed.
}</langsyntaxhighlight>
{{out}}
<pre>On a 32 bit system:
Line 441 ⟶ 498:
Delphi has in implicit conversions for primitive numerical types. Any value can be implicitly converted to a value of a larger type.
Upsize conversions:
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueByte : Byte := 2; // (8 bits size)
ValueWord : Word := ValueByte; // 2 (16 bits size)
ValueDWord : DWord := ValueWord; // 2 (32 bits size)
ValueUint64 : Uint64 := ValueWord; // 2 (64 bits size)
</syntaxhighlight>
</lang>
Unsigend-signed conversions
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueInteger : Integer := ValueDWord; // -1 (two complement conversion) (signed)
ValueDWord := ValueInteger; // 4294967295 (convert back, unsigned)
</syntaxhighlight>
</lang>
Unsigned variables will not convert literal negative values
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueByte := -1; // this not work, and raise a error
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
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDWord := 4294967295; // 4294967295 (Max DWord value (unsigned))
ValueDouble : Double := ValueDWord; // 4.29496729500000E+0009
</syntaxhighlight>
</lang>
Integers can not convert float values implicity
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueDouble := 1.6;
ValueByte := ValueDouble; // this not work, and raise a error
ValueByte : Trunc(ValueDouble); // this work, and assign 1
ValueByte : Round(ValueDouble); // this work, and assign 2
</syntaxhighlight>
</lang>
Strings can convert chars, but not convert back
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueChar: Char := #10;
ValuesString: String := ValueChar;
</syntaxhighlight>
</lang>
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 := 1; // this not work, and raise a error
Line 484 ⟶ 541:
ValueBoolean := Boolean(-1); // this work, and assign true
ValueBoolean := Boolean( 0); // this work, and assign false
</syntaxhighlight>
</lang>
Variant types can implicit convert allmost types, and convert back, if possible:
<syntaxhighlight lang="delphi">
<lang Delphi>
ValueVariant: Variant := -20;
ValueVariant := 3.1416;
Line 493 ⟶ 550:
ValueVariant := True;
...
</syntaxhighlight>
</lang>
Class and Record can implement implicit operator
<syntaxhighlight lang="delphi">
<lang Delphi>
program Implicit_type_conversion;
 
Line 575 ⟶ 632:
 
readln;
end.</langsyntaxhighlight>
=={{header|Déjà Vu}}==
 
The only implicit conversion currently permitted is boolean to number:
 
<langsyntaxhighlight lang="dejavu"><1:1> #interactive session
<2:1> !. + 3 true #boolean true is equal to 1
4
<3:1> !. * 2 false #boolean false is equal to 0
0</langsyntaxhighlight>
 
=={{header|EasyLang}}==
Numbers are automatically converted to strings when used with a string variable.
<syntaxhighlight lang="easylang">
string$ = 32
print string$
</syntaxhighlight>
Same goes for arrays of strings, when they are set to an array of numbers.
<syntaxhighlight lang="easylang">
stringArray$[] = [ 16 32 64 ]
print stringArray$[1]
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
Var declares a variable whose type is implied from the initializer expression. It is illegal to specify an explicit type in a Var declaration. The initializer expression can be either a constant or any variable of any type.
 
Since the type of the variable is inferred from what you assign into it, it's helpful to know how literals work. Any literal number without a decimal point defaults to Integer. A literal number with a decimal point defaults to Double.
 
All ZString expressions, including string literals and dereferenced ZString Ptrs, will be given the String variable type.
<syntaxhighlight lang="freebasic">Var a = Cast(Byte, 1)
Var b = Cast(Short, 1)
Var c = Cast(Integer, 1)
Var d = Cast(Longint, 1)
Var au = Cast(Ubyte, 1)
Var bu = Cast(Ushort, 1)
Var cu = Cast(Uinteger, 1)
Var du = Cast(Ulongint, 1)
Var e = Cast(Single, 1.0)
Var f = Cast(Double, 1.0)
Var g = @c '' integer ptr
Var h = @a '' byte ptr
Var s2 = "hello" '' var-len string
 
Var ii = 6728 '' implicit integer
Var id = 6728.0 '' implicit double
 
Print "Byte: "; a
Print "Short: "; b
Print "Integer: "; c
Print "Longint: "; d
Print "UByte: "; au
Print "UShort: "; bu
Print "UInteger: "; cu
Print "ULongint: "; du
Print "Single: "; e
Print "Double: "; f
Print "Integer Pointer: "; g
Print "Byte Pointer: "; h
Print "Variable String: "; s2
Print
Print "Integer: "; ii
Print "Double: "; id</syntaxhighlight>
{{out}}
<pre>Byte: 1
Short: 1
Integer: 1
Longint: 1
UByte: 1
UShort: 1
UInteger: 1
ULongint: 1
Single: 1
Double: 1
Integer Pointer: 1375536
Byte Pointer: 1375547
Variable String: hello
 
Integer: 6728
Double: 6728</pre>
 
=={{header|Free Pascal}}==
''See [[#Delphi|Delphi]]''
 
=={{header|Furor}}==
Line 608 ⟶ 737:
 
Some simple examples may help to make this clearer.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 648 ⟶ 777:
m := 0.3 + float64(l) + 0.7
fmt.Printf("m : type %-7T value %g\n", m, m)
}</langsyntaxhighlight>
 
{{out}}
Line 663 ⟶ 792:
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.
 
<langsyntaxhighlight lang="idris">implicit
boolToInt : Bool -> Int
boolToInt True = 1
Line 672 ⟶ 801:
 
two : Int
two = one + True</langsyntaxhighlight>
 
=={{header|J}}==
Line 686 ⟶ 815:
Nouns break down into four disjoint collections of subtypes: boxed, literal, numeric and symbolic (which is rarely used).
Most of J's implicit conversions happen within the first three subtypes. (And J supports some "extra conversions" between these types in some cases where no values are involved.
For example a length 0 list which contains no characters (literals) may be used as a list which contains no numbers (numerics)).
 
There is one type of box, three types of literals (8 bit wide, 16 bit wide and 32 bit wide -- each of which are typically interpreted as unicode by the OS), and a variety of types of numerics.
 
There is one type of box, two types of literals (8 bit wide and 16 bit wide), and a variety of types of numerics.
Sparse arrays are also (partially) supported and treated internally as distinct datatypes, implemented under the covers as a sequence of arrays (one to indicate which indices have values, and another to hold the corresponding values, and also a default value to fill in the rest).
 
The primary implicit type conversion in J applies to numeric values.
 
In particular, J tries to present numeric values as "[http://www.jsoftware.com/pipermail/beta/2006-April/000749.html analytic]"; that is, numeric values which are "the same" should presented to the user (J programmer) as "the same" in as many different contexts as is feasible, irrespective of their representation in the the computer's model or layout in memory. So, for example, on a 32-bit machine, `(2^31)-1` is the largest value a signed integer, which is stored in 4 bytes, can represent; in J, incrementing this value (adding 1) causes the underlying representation to switch to IEEE double-precision floating point number.
In particular, J tries to present numeric values as "[http://www.jsoftware.com/pipermail/beta/2006-April/000749.html analytic]"; that is, numeric values which are "the same" should presented to the user (J programmer) as "the same" in as many different contexts as is feasible, irrespective of their representation in the the computer's model or layout in memory. So, for example, on a 32-bit machine, `2147483647` (or `(2^31)-1`) is the largest value a signed integer, which is stored in 4 bytes, can represent; in a 32 bit J implementation, incrementing this value (adding 1) causes the underlying representation to switch to IEEE double-precision floating point number. In a 64 bit J implementation, `9223372036854775807` (or `(2^63)-1`) is the largest value which can be represented as a fixed width integer.
In other words `1+(2^31)-1` doesn't overflow: it represents `2^31` exactly (using double the memory: 8 bytes). Similar comments apply to the two varieties of character values (ASCII and Unicode), though the implications are more straightforward and less interesting.
 
In other words `1+(2^31)-1` doesn't overflow: it represents `2^31` exactly (using double the memory on a 32 bit J implementation: 8 bytes). Similar comments apply to the two varieties of character values (ASCII and Unicode), though the implications are more straightforward and less interesting.
 
Having said that all that, because of the potential performance penalties involved, J does not stretch this abstraction too far. For example, numbers will never be automatically promoted to the (available, but expensive) arbitrary precision format, nor will values be automatically "demoted" (automatic demotion, paired with automatic promotion, has the potential to cause cycles of expansion and contraction during calculation of intermediate values; this, combined with J's homogeneous array-oriented nature, which requires an entire array to be promoted/demoted along with any one of its values, means including automatic demotion would probably hurt programs' performance more often than it benefited them.)
Line 700 ⟶ 832:
 
The rich j datatypes:
<syntaxhighlight lang="j">
<lang J>
datatype NB. data type identification verb
3 : 0
Line 751 ⟶ 883:
2 2 │ 2
3 3 │ 2
</syntaxhighlight>
</lang>
 
J has verbs causing explicit conversion. Some appear in the above examples.
J's lexical notation provides for us to directly specify the datatype as demonstrated in the other samples. The Extended and Rational Arithmetic section of the J dictionary (DOJ) explains the fundamental implicit conversions.
Before quoting this the section here, please note that arrays have the homogeneous data type of the highest atomic data type as shown in the 0 1 2 integer vector---implicit conversion without using the primitive verbs.
 
J's lexical notation let's us specify the datatype of a constant, as demonstrated in these samples. The Extended and Rational Arithmetic section of the J dictionary (DOJ) explains the fundamental implicit conversions.
''Various primitive verbs produce (exact) rational results if the argument(s) are rational; non-rational verbs produce (inexact) floating point or complex results when applied to rationals, if the verb only has a limited number of rational arguments that produce rational results.
 
Various primitive verbs produce (exact) rational results if the argument(s) are rational; non-rational verbs produce (inexact) floating point or complex results when applied to rationals, some verbs which produce irrational results may instead produce rational results when it's possible to do so accurately and the verb's arguments are rational (or are values which can be promoted to rational).
 
(For example, %:y is rational if the atoms of y are perfect squares; ^0r1 is floating point.)
The quotient of two extended integers is an extended integer (if evenly divisible) or rational (if not). Comparisons involving two rationals are exact.
''Dyadic verbs (e.g. + - * % , = <) that require argument type conversions do so according to the following table:''
<pre>
| B I X Q D Z
Line 774 ⟶ 907:
=={{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>
<langsyntaxhighlight lang="java">public class ImplicitTypeConversion{
public static void main(String...args){
System.out.println( "Primitive conversions" );
Line 813 ⟶ 946:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 850 ⟶ 983:
 
However, if one were to define "is_integer" as follows:
<langsyntaxhighlight lang="jq">def is_integer: type == "number" and . == floor;</langsyntaxhighlight>
 
then one would find:
<langsyntaxhighlight lang="jq">(1/3) | is_integer # yields false
 
(1/3 + 1/3 + 1/3) | is_integer # yields true</langsyntaxhighlight>
 
For reference, jq's builtin types are "number", "boolean", "null", "object" and "array".
Line 861 ⟶ 994:
=={{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.
<langsyntaxhighlight lang="julia">
julia> function testme()
ui8::UInt8 = 1
Line 874 ⟶ 1,007:
julia> testme()
(0x01, 1, 0x0001, 2, 0x00000001, 4, 0x0000000000000001, 8, 1.0, 8)
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
Line 880 ⟶ 1,013:
 
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.
<langsyntaxhighlight lang="scala">// version 1.1.2
 
open class C(val x: Int)
Line 897 ⟶ 1,030:
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)
}</langsyntaxhighlight>
{{out}}
Line 911 ⟶ 1,044:
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.
<langsyntaxhighlight 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") --> number
Line 924 ⟶ 1,057:
 
-- 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</langsyntaxhighlight>
 
The only two explicit conversion functions offered by Lua are <code>tonumber</code> and <code>tostring</code>.
Line 930 ⟶ 1,063:
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Long a=12.5
Line 988 ⟶ 1,121:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Line 1,007 ⟶ 1,140:
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 B: float = 1 # Implicit conversion from int to float done by the compiler.
Line 1,050 ⟶ 1,183:
 
echo 1 + true # Displays 2.
if 2: echo "ok" # Displays "ok".</langsyntaxhighlight>
 
=={{header|Oforth}}==
Line 1,074 ⟶ 1,207:
Let's create a Complex class with 80 as priority (please note asComplex methods that will be used for conversions) :
 
<langsyntaxhighlight Oforthlang="oforth">100 Number Class newPriority: Complex(re, im)
Complex method: re @re ;
Line 1,100 ⟶ 1,233:
Complex new(@re n /, @im neg n / ) ;
 
Complex method: /(c) c self inv * ;</langsyntaxhighlight>
 
Usage :
 
<langsyntaxhighlight Oforthlang="oforth">2 3.2 I * + println
Complex new(2, 3) 1.2 + println
Complex new(2, 3) 1.2 * println
2 Complex new(2, 3) / println</langsyntaxhighlight>
 
{{out}}
Line 1,124 ⟶ 1,257:
 
There are no user-defined types and hence no implicit conversion on them.
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">program implicitTypeConversion;
var
i: integer;
r: real;
begin
i := 42;
r := i { integer → real }
end.</syntaxhighlight>
{{works with|Extended Pascal}}
<syntaxhighlight lang="pascal">program additionalImplicitTypeConversionInExtendedPascal;
var
c: char;
s: string(20);
i: integer;
r: real;
x: complex;
begin
c := 'X';
s := c; { char → string(…) }
i := 42;
x := i; { integer → complex }
r := 123.456;
x := r { real → complex }
end.</syntaxhighlight>
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.
Obviously, <tt>im(42)</tt> will always return <tt>0</tt>&nbsp;(zero), but the implicit conversion (<tt>integer</tt> to <tt>complex</tt>) is performed.
This is important to remember, when the conversion could cause a loss in precision.
For instance Extended Pascal’s [[Exponentiation order#Pascal|exponentiation operator]] <tt>**</tt> will promote any <tt>integer</tt> operand to a <tt>real</tt> value first.
 
=={{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.
<langsyntaxhighlight lang="perl">print 1 + '2'; # 3
print '1' + '2'; # 3
print 1 . 1; # 11
Line 1,136 ⟶ 1,302:
 
# 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</langsyntaxhighlight>
 
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,148 ⟶ 1,314:
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
<!--<langsyntaxhighlight Phixlang="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: #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: #000000004600;">PI</span> <span style="color: #000080;font-style:italic;">-- s is now {'t','h',3.1415926,'s'}</span>
<!--</langsyntaxhighlight>-->
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.
Line 1,157 ⟶ 1,323:
=={{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.
<langsyntaxhighlight lang="python">from fractions import Fraction
from decimal import Decimal, getcontext
getcontext().prec = 60
Line 1,205 ⟶ 1,371:
except BaseException:
ans = 'EXCEPTION RAISED!'
print('%-60s -> %r' % ('%s(%r)' % (f.__name__, e), ans))</langsyntaxhighlight>
 
{{out}} (Elided due to size)
Line 1,328 ⟶ 1,494:
dict({1: 'one', 'two': (2+3j), ('RC', 3): None}) -> {1: 'one', 'two': (2+3j), ('RC', 3): None}
</pre>
===alternative===
One case of implicit casting and one quasi-case:
<syntaxhighlight lang="python">>>> 12/3 # Implicit cast from int to float, by / operator.
4.0
>>> (2+4j)/2 # But no implicit cast for complex parts.
(1+2j)
>>> (11.5+12j)/0.5 # Quasi-case, complex parts implicit cast from float to int.
(23+24j)
</syntaxhighlight>
 
=={{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.
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(+ 1 .1) ; ==> 1.1
Line 1,337 ⟶ 1,512:
(+ 1 1/2) ; ==> 3/2
(+ 1 (expt 10 30)) ; ==> 1000000000000000000000000000001
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 1,354 ⟶ 1,529:
The type of object contained in a scalar depends on how you assign it and how you use it.
 
<syntaxhighlight lang="raku" perl6line>my $x;
 
$x = 1234; say $x.WHAT; # (Int) Integer
Line 1,368 ⟶ 1,543:
$x = {1, 2}; say $x.WHAT; # (Block)
$x = sub {1}; say $x.WHAT; # (Sub) Code Reference
$x = True; say $x.WHAT; # (Bool) Boolean</langsyntaxhighlight>
 
 
Objects may be converted between various types many times during an operation. Consider the following line of code.
 
<syntaxhighlight lang="raku" perl6line>say :16(([+] 1234.ords).sqrt.floor ~ "beef");</langsyntaxhighlight>
 
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,379 ⟶ 1,554:
Broken down step by step:
 
<syntaxhighlight lang="raku" perl6line>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; # 202 (Int)
Line 1,385 ⟶ 1,560:
$x = ([+] 1234.ords).sqrt.floor; say $x, ' ', $x.WHAT; # 14 (Int)
$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)</langsyntaxhighlight>
 
 
Line 1,392 ⟶ 1,567:
(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.)
 
<syntaxhighlight lang="raku" perl6line>my $x;
$x = (-1).sqrt; say $x, ' ', $x.WHAT; # NaN (Num)
$x = (-1).Complex.sqrt; say $x, ' ', $x.WHAT; # 6.12323399573677e-17+1i (Complex)
Line 1,403 ⟶ 1,578:
$x /= 10**10; say $x, ' ', $x.WHAT; # 0.000000000629 (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.
Line 1,419 ⟶ 1,594:
@() pluralize
%() hashify</pre>
 
=={{header|RPL}}==
To make basic calculations easier, RPL accepts to mix floating-point real numbers and either complex numbers or binary integers when using <code>+ - * /</code> operations.
(2,3) 2 *
#37h 16 +
{{out}}
<pre>
2: (4,6)
1: #47h
</pre>
 
=={{header|REXX}}==
Line 1,440 ⟶ 1,625:
╚═══════════════════════════════════════════════════════════════════════════════════╝
</pre>
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates various ways REXX can convert and/or normalize some numbers.*/
digs=digits() ; say digs /* 9, the default.*/
 
Line 1,459 ⟶ 1,644:
a=1e+003 ; b=0 ; x=a+b ; say x /* 1000 */
a=12345678912 ; say a /* 123456789012 */
a=12345678912 ; b=0 ; x=a+b ; say x /* 1.23456789E+10 */</langsyntaxhighlight>
'''output'''
<pre>
Line 1,487 ⟶ 1,672:
=={{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.
<langsyntaxhighlight lang="ruby">> 1+"2" #=> 3
> "1"+2 #=> 12
> sqrt(-4) #=> 2i
> ("a" + [1,2]) #=> a[1,2]
> ('ha' * '3') #=> hahaha
> ('ha' * true) #=> ha</langsyntaxhighlight>
 
=={{header|Tcl}}==
Line 1,499 ⟶ 1,684:
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:<langsyntaxhighlight lang="tcl">set value "123"
incr someVar $value
# $value will now hold an integer (strictly, one of many integer-related types) with value 123</langsyntaxhighlight>
 
;Float conversion:<langsyntaxhighlight lang="tcl">set value "1.23"
expr {$value + 3.5}
# $value will now hold a double-precision IEEE floating point number that is (approx.) 1.23</langsyntaxhighlight><!-- IEEE binary floats can't hold the value exactly -->
 
;String conversion:<langsyntaxhighlight lang="tcl">set value [expr {123 + 456}]
string length $value
# $value will now hold a string (of length 3)</langsyntaxhighlight>
 
;List conversion:<langsyntaxhighlight lang="tcl">set value {a b c d}
llength $value
# $value will now hold a list (of length 4)</langsyntaxhighlight>
 
;Dictionary conversion:<langsyntaxhighlight lang="tcl">set value {a b c d}
dict size $value
# $value will now hold a dictionary (of size 2)</langsyntaxhighlight>
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.
 
Defining a new type requires writing an extension to Tcl in [[C]] (or whatever the host programming language is, so [[Java]] for [[JTcl]]); the interfaces for doing this are not directly exposed to the Tcl script level because they require direct memory access, which Tcl normally does not permit in order to promote overall process stability.
 
=={{header|V (Vlang)}}==
A small primitive type can be automatically promoted if it fits completely into the data range of the type on the other side.
 
These are the allowed possibilities:
<syntaxhighlight lang="Vlang">
i8 → i16 → int → i64
↘ ↘
f32 → f64
↗ ↗
u8 → u16 → u32 → u64 ⬎
↘ ↘ ↘ ptr
i8 → i16 → int → i64 ⬏
</syntaxhighlight>
For example, an int value can be automatically promoted to f64 or i64, but not to u32.
 
Note- u32 would mean loss of the sign for negative values.
 
Promotion from int to f32, however, is currently done automatically (but can lead to precision loss).
<syntaxhighlight lang="Vlang">
u := u16(12)
x := f32(45.6)
a := 75
b := 14.7
c := u + a // c is of type `int` - automatic promotion of `u`'s value
println(c) // 87
d := b + x // d is of type `f64` - automatic promotion of `x`'s value
println(d) // 60.2999984741211
</syntaxhighlight>
 
=={{header|Wren}}==
Line 1,530 ⟶ 1,744:
In conditional expressions, 'null' acts like it is false and any other value acts like it is true but these aren't really implicit conversions to Bool; it's just the way the language works.
 
Also adding implicit conversions to the built-in types is not really asan option, as inheriting from these types is not recommended for technical reasonsallowed.
 
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.
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
 
var b1 = BigInt.new(32)
Line 1,539 ⟶ 1,753:
 
var b3 = b1 + b2 + 2 + "2"
System.print(b3) // 100</langsyntaxhighlight>
 
=={{header|XPL0}}==
XPL0 doesn't have implicit type conversions. It only has two basic data
types: integer and real. Conversions must be done explicitly. For
example:
<syntaxhighlight lang "XPL0">
int I;
real R;
I:= fix(R);
R:= float(I);
</syntaxhighlight>
 
There is a third declaration type called 'character' (usually abbreviated
'char'). Its variables are the same as integers except when they are
indexed, as for arrays. An indexed character variable accesses bytes,
whereas an indexed integer variable accesses integers.
 
Strings are one-dimensional arrays consisting of bytes containing ASCII
characters.
 
Booleans are represented by integers. Zero is false, and non-zero is
true.
 
Real literals are distinguished from integers by including a decimal point or exponent. For example: 12. or 6e12
 
=={{header|Z80 Assembly}}==
As with other assembly languages, types don't really exist in the sense that we're used to thinking about them. All the functionality is there but there are no "rules" forbidding you from doing anything particular with data. Type "conversion" doesn't happen by itself, but there is sort of "type casting" if you will, in the sense that the programmer can decide whether a particular bit pattern represents an integer, a pointer, etc. whenever the programmer wants. Type conversion in the "modern" sense (such as an integer becoming a float or a string) will have to be done manually.
 
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.
 
<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 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:
* Reading/writing in the $FF00-$FFFF memory range.
* Storing the stack pointer at a constant 16-bit address. (The stack pointer can only be saved this way, it cannot be loaded this way.)
 
 
 
 
The individual 8-bit registers that form a register pair can be operated on separately, or as a single 16-bit value.
<syntaxhighlight lang="z80">LD BC,$1234
INC B ;BC = $1334
INC C ;BC = $1335
INC BC ;BC = $1336</syntaxhighlight>
 
=={{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).
<langsyntaxhighlight lang="zkl">zkl: 1+"2"
3
zkl: "1"+2
Line 1,557 ⟶ 1,818:
zkl: T("one",1,"two",2).toDictionary().toList().toDictionary()
D(two:2,one:1)
etc</langsyntaxhighlight>
 
{{omit from|6502 Assembly}}
{{omit from|6800 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|8080 Assembly}}
{{omit from|8086 Assembly}}
{{omit from|ARM Assembly}}
{{omit from|AArch64 Assembly}}
{{omit from|MIPS Assembly}}
{{omit from|X86 Assembly}}
{{omit from|Z80 Assembly}}
9,476

edits