Implicit type conversion

From Rosetta Code
Implicit type conversion 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.

Some programming languages have Implicit type conversion(wp). 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 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 following code sample demonstrates the various type conversions in each language, and gives an example of a implicit type conversion path from the smallest possible variable size to the largest possible variable size. (Where the size of the underlying variable's data strictly increases).

In strong typed languages some types actually mutually incompatible. In this case the language may have disjoint type conversion paths, or even branching type conversion paths. (Where it occurs in a specific language, it is demonstrated in the code samples below.)

Languages that don't support any implicit type conversion are detailed in the /Omit categories at the bottom of this page.

Indicate if the language supports user defined type conversion definitions. And give an example of such a definition. (E.g. define an implicit type conversion from real to complex numbers, or from char to an array of char of length 1.)

ALGOL 68

Works with: ALGOL 68 version Revision 1 - one minor extension to language used - PRAGMA READ, similar to C's #include directive.
Works with: ALGOL 68G version Any - tested with release algol68g-2.6.

File: implicit_type_conversion.a68<lang algol68>#!/usr/bin/a68g --script #

  1. -*- coding: utf-8 -*- #

main:(

  1. a representitive sample of builtin types #
   BOOL b; INT bool width = 1;
   BITS bits; LONG BITS lbits;
   BYTES bytes; LONG BYTES lbytes; # lbytes := bytes is not illegal #
   [bits width]BOOL array bool;
   [long bits width]BOOL long array bool;
   CHAR c; INT char width = 1;
   STRING array char;
   SHORT SHORT INT ssi; SHORT INT si; INT i; LONG INT li; LONG LONG INT lli;
   SHORT SHORT REAL ssr; SHORT REAL sr; REAL r; LONG REAL lr; LONG LONG REAL llr;
   SHORT SHORT COMPL ssz; SHORT COMPL sz; COMPL z; LONG COMPL lz; LONG LONG COMPL llz;
   INT long long compl width = 2 * long long real width;
   
   STRUCT (BOOL b, CHAR c, INT i, REAL r, COMPL z)cbcirz;  # NO implicit casting #
   REF []INT rai;
   FORMAT long long real fmt = $g(-0,long long real width-2)$;
   FORMAT long long compl fmt = $f(long long real fmt)"+"f(long long real fmt)"i"$;
  1. type conversion stating points #
   b := TRUE;
   c := "1"; 
   ssi := SHORT SHORT 1234; i := 1234;
  1. a representitive sample of implied casts for subtypes of personality INT/REAL/COMPL #
    si:=ssi;
     i:=ssi;  i:=si; 
    li:=ssi; li:=si;  li:=i;  
   lli:=ssi;lli:=si; lli:=i;  lli:=li; 
   ssr:=ssi;
    sr:=ssr; sr:=ssi; sr:=si; 
     r:=ssr;  r:=sr;   r:=ssi;  r:=si;   r:=i;  
    lr:=ssr; lr:=sr;  lr:=r;   lr:=ssi; lr:=si;  lr:=i;   lr:=li; 
   llr:=ssr;llr:=sr; llr:=r;  llr:=lr; llr:=ssi;llr:=si; llr:=i;  llr:=li; llr:=i;  
   ssz:=ssi;ssz:=ssr;
    sz:=ssz; sz:=ssi; sz:=si;  sz:=ssr; sz:=sr; 
     z:=ssz;  z:=sz;   z:=ssi;  z:=si;   z:=i;    z:=ssr;  z:=sr;   z:=r;  
    lz:=ssz; lz:=sz;  lz:=z;   lz:=ssi; lz:=si;  lz:=i;   lz:=li;  lz:=ssr; lz:=sr;  lz:=r;   lz:=lr; 
   llz:=ssz;llz:=sz; llz:=z;  llz:=lz; llz:=ssi;llz:=si; llz:=i;  llz:=li; llz:=i;  llz:=ssr;llz:=sr; llz:=r;  llz:=lr; llz:=llr;
  1. conversion branch SHORT SHORT INT => LONG LONG COMPL #
  2. a summary result, using the longest sizeof increasing casting path #
   printf((long long compl fmt,llz:=(llr:=(lr:=(i:=(si:=ssi)))),  
           $" was increasingly cast"$,
           $" from "g(-0)$, long long compl width, long long real width, long real width, 
                           int width, short int width, short short int width, $" digits"$,
           $" and was '"g(-0)"'"l$,ssi ));
  1. conversion branch BITS => []BOOL #
   bits := 16rf0f0ff00;
   lbits := bits;
   printf(($g$,"[]BOOL := LBITS := BITS: ",array bool := bits, $l$));
  1. conversion branch BYTES => []CHAR #
   bytes := bytes pack("0123456789ABCDEF0123456789abcdef");
   long array bool := LONG 2r111;
   printf(($g$,"[]CHAR := BYTES: ",array char := bytes, $l$));
  1. conversion branch PROC PROC PROC INT => INT #
   PROC pi = INT: i;
   PROC ppi = PROC INT: pi;
   PROC pppi = PROC PROC INT: ppi;
   printf(($g$,"implicit deprocceduring^3: ",pppi, $l$));
  1. conversion branch REF REF REF INT => INT #
   REF INT ri := i;
   REF REF INT rri := ri;
   REF REF REF INT rrri := rri;
   printf(($g$,"implicit dereferencing^3: ",rrri, $l$));
  1. conversion branch INT => []INT => [,]INT #
  2. a representitive sample of implied casts, type pointer #
   rai := ai; # starts at the first element of ai #
   rai := i;  # an array of length 1 #
   FLEX[0]INT ai := i;
   FLEX[0,0]INT aai := ai;
   FLEX[0,0,0]INT aaai := aai;
   printf(($g$,"implicit rowing^3: ",aaai, $l$));
  1. conversion branch UNION(INT => UNION(INT => UNION(INT,REAL) => UNION(INT,REAL,COMPL) #
   UNION(VOID,INT) ui := i;
   UNION(VOID,INT,REAL) uui := ui;
   UNION(VOID,INT,REAL,COMPL) uuui := uui;
   printf(($g$,"implicit uniting^3: ",(uuui|(INT i):i), $l$));
 SKIP

)</lang>Output:

1234.0000000000000000000000000000000000000000000000000000000000000+.0000000000000000000000000000000000000000000000000000000000000i was increasingly cast from 126 from 63 from 28 from 10 from 10 from 10 digits and was '1234'
[]BOOL := LBITS := BITS: TTTTFFFFTTTTFFFFTTTTTTTTFFFFFFFF
[]CHAR := BYTES: 0123456789ABCDEF0123456789abcdef
implicit deprocceduring^3:       +1234
implicit dereferencing^3:       +1234
implicit rowing^3:       +1234
implicit uniting^3:       +1234

C

<lang c>#include <stdio.h> main(){ /* a representative sample of builtin types */

   unsigned char uc; char c;
   enum{e1, e2, e3}e123;
   short si; int i; long li;
   unsigned short su; unsigned u; unsigned long lu;
   float sf; float f; double lf; long double llf;
   union {char c; unsigned u; int i; float f; }ucuif;  /* manual casting only */
   struct {char c; unsigned u; int i; float f; }scuif; /* manual casting only */
   int ai[99];
   int (*rai)[99];
   int *ri;
   uc = '1';

/* a representitive sample of implied casts for subtypes of personality int/float */

   c=uc;
   si=uc; si=c;
   su=uc; su=c; su=si;
   i=uc;  i=c;  i=si;  i=su;
   e123=i; i=e123;
   u=uc;  u=c;  u=si;  u=su;  u=i;
   li=uc; li=c; li=si; li=su; li=i; li=u;
   lu=uc; lu=c; lu=si; lu=su; lu=i; lu=u; lu=li;
   sf=uc; sf=c; sf=si; sf=su; sf=i; sf=u; sf=li; sf=lu;
   f=uc;  f=c;  f=si;  f=su;  f=i;  f=u;  f=li;  f=lu;  f=sf;
   lf=uc; lf=c; lf=si; lf=su; lf=i; lf=u; lf=li; lf=lu; lf=sf; lf=f;
   llf=uc;llf=c;llf=si;llf=su;llf=i;llf=u;llf=li;llf=lu;llf=sf;llf=f;llf=lf;

/* ucuif = i; no implied cast; try: iucuif.i = i */ /* ai = i; no implied cast; try: rai = &i */ /* a representitive sample of implied casts, type pointer */

   rai = ai; /* starts at the first element of ai */
   ri = ai;  /* points to the first element of ai */

/* a summary result, using the longest sizeof increasing casting path */

   printf("%LF was increasingly cast from %d from %d from %d from %d from %d bytes and was '%c'\n",
          llf=(lf=(i=(si=c))), sizeof llf, sizeof lf, sizeof i, sizeof si,sizeof c, c);

}</lang>