Type detection: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(→‎PHP: Added zkl)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(95 intermediate revisions by 37 users not shown)
Line 1:
{{draft task|Type detection}}
{{Alertbox|pink|This page is scheduled for deletion after 09-Oct-2015. - See discussion page'}}
 
{{draft task|FIXME}}
This draft task needs a purpose, a description and some way to tell whether examples satisfy or do not satisfy it.
== Task Description ==
Show a function/procedure that, when given an object of type Any (or just unknown type), performs a common task.
 
For example: you want to process a block of text. The function takes a parameter that is, or somehow describes, the block of text (and provides a method or call to access and return that block of text). The task is then to show how function gets the text from the parameter (but not show the text processing).
 
;Task:
== JavaScript ==
Show a function/procedure that processes a block of text by printing it.
 
The function takes one parameter (ideally) that describes the text.
 
Demonstrate by calling the function twice, each time passing in a different type.
 
 
This can be done with pattern matching, multi-methods, dynamic type detection, structure(s) with a tag, etc.
 
The objective is write a [e.g. library] function that processes text from multiple sources (such as a string/char *, socket, file, etc).
 
If not practical, show how the caller would coerce a type that can be passed to the library function.
<br><br>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">print type 2
print type "hello world"
print type [1 2 3]
 
print is? :integer 4
print is? :integer "hello world"
 
print is? :string "hello world"
print is? :string 7
 
print string? "boom"
print logical? true
print block? ["one" "two" "three"]</syntaxhighlight>
 
{{out}}
 
<pre>:integer
:string
:block
true
false
true
false
true
true
true</pre>
 
=={{header|ATS}}==
===Using garbage collection and '''datatype'''===
<syntaxhighlight lang="ats">#include "share/atspre_staload.hats"
 
datatype source_t =
| source_t_string of string
| source_t_FILEref of FILEref
 
extern fun
print_text (source : source_t) : void
 
implement
print_text (source) =
case+ source of
| source_t_string s => print! (s)
| source_t_FILEref f =>
let
var c : int = fileref_getc (f)
in
while (0 <= c)
begin
fileref_putc (stdout_ref, c);
c := fileref_getc (f)
end
end
 
implement
main0 () =
let
val f = fileref_open_exn ("type_detection-postiats.dats",
file_mode_r)
in
print_text (source_t_string "This\nis a\ntext.\n");
print_text (source_t_FILEref f)
end</syntaxhighlight>
 
{{out}}
$ patscc -DATS_MEMALLOC_GCBDW type_detection-postiats.dats -lgc && ./a.out
<pre>This
is a
text.
#include "share/atspre_staload.hats"
 
datatype source_t =
| source_t_string of string
| source_t_FILEref of FILEref
 
extern fun
print_text (source : source_t) : void
 
implement
print_text (source) =
case+ source of
| source_t_string s => print! (s)
| source_t_FILEref f =>
let
var c : int = fileref_getc (f)
in
while (0 <= c)
begin
fileref_putc (stdout_ref, c);
c := fileref_getc (f)
end
end
 
implement
main0 () =
let
val f = fileref_open_exn ("type_detection-postiats.dats",
file_mode_r)
in
print_text (source_t_string "This\nis a\ntext.\n");
print_text (source_t_FILEref f)
end</pre>
 
===Using a linear '''dataviewtype'''===
 
In this implementation, '''print_text''' consumes its argument; the argument’s value cannot be used again. However, the object wrapped in the '''source_vt''' might be reusable.
 
<syntaxhighlight lang="ats">#include "share/atspre_staload.hats"
 
dataviewtype source_vt =
| source_vt_string of string
| source_vt_FILEref of FILEref
 
extern fun
print_text (source : source_vt) : void
 
implement
print_text (source) =
case+ source of
| ~ source_vt_string s => print! (s)
| ~ source_vt_FILEref f =>
let
var c : int = fileref_getc (f)
in
while (0 <= c)
begin
fileref_putc (stdout_ref, c);
c := fileref_getc (f)
end
end
 
implement
main0 () =
let
val f_opt = fileref_open_opt ("type_detection-postiats-2.dats",
file_mode_r)
in
print_text (source_vt_string "This\nis a\ntext.\n");
case+ f_opt of
| ~ Some_vt f => print_text (source_vt_FILEref f)
| ~ None_vt () => fprintln! (stderr_ref, "Failed to open the file.")
end</syntaxhighlight>
{{out}}
$ patscc -DATS_MEMALLOC_LIBC type_detection-postiats-2.dats && ./a.out
<pre>This
is a
text.
#include "share/atspre_staload.hats"
 
dataviewtype source_vt =
| source_vt_string of string
| source_vt_FILEref of FILEref
 
extern fun
print_text (source : source_vt) : void
 
implement
print_text (source) =
case+ source of
| ~ source_vt_string s => print! (s)
| ~ source_vt_FILEref f =>
let
var c : int = fileref_getc (f)
in
while (0 <= c)
begin
fileref_putc (stdout_ref, c);
c := fileref_getc (f)
end
end
 
implement
main0 () =
let
val f_opt = fileref_open_opt ("type_detection-postiats-2.dats",
file_mode_r)
in
print_text (source_vt_string "This\nis a\ntext.\n");
case+ f_opt of
| ~ Some_vt f => print_text (source_vt_FILEref f)
| ~ None_vt () => fprintln! (stderr_ref, "Failed to open the file.")
end</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: TAWK -f TYPE_DETECTION.AWK
# uses Thompson Automation's TAWK 5.0c
BEGIN {
arr[0] = 0
print(typeof(arr))
print(typeof(0.))
print(typeof(0))
print(typeof(/0/))
print(typeof("0"))
print(typeof(x))
print(typeof(addressof("x")))
print(typeof(fopen("x","r")))
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
array
float
int
regular_expression
string
uninitialized
address
fileid
</pre>
 
=={{header|C}}==
The closest C comes to meeting this task, short of building it into the compiler or accessing memory segments via pointers, which is not guaranteed to be portable, is the ctype.h header file. It is part of the C Standard Library and provides 11 methods for detecting the type of a character, out of which the following 7 called in the wrapper function below can be called to be unique. The function accepts a string, but it actually checks the first character. An if ladder is used instead of if-else so that all function calls which return a non-zero value for the character are satisfied and the information is printed.
<syntaxhighlight lang="c">
#include<stdio.h>
#include<ctype.h>
 
void typeDetector(char* str){
if(isalnum(str[0])!=0)
printf("\n%c is alphanumeric",str[0]);
if(isalpha(str[0])!=0)
printf("\n%c is alphabetic",str[0]);
if(iscntrl(str[0])!=0)
printf("\n%c is a control character",str[0]);
if(isdigit(str[0])!=0)
printf("\n%c is a digit",str[0]);
if(isprint(str[0])!=0)
printf("\n%c is printable",str[0]);
if(ispunct(str[0])!=0)
printf("\n%c is a punctuation character",str[0]);
if(isxdigit(str[0])!=0)
printf("\n%c is a hexadecimal digit",str[0]);
}
 
int main(int argC, char* argV[])
{
int i;
if(argC==1)
printf("Usage : %s <followed by ASCII characters>");
else{
for(i=1;i<argC;i++)
typeDetector(argV[i]);
}
return 0;
}
</syntaxhighlight>
Output, shown for multiple inputs, as well as single ones:
<pre>
C:\rosettaCode>typeDetector.exe s 3 $ f ! as 3
 
s is alphanumeric
s is alphabetic
s is printable
3 is alphanumeric
3 is a digit
3 is printable
3 is a hexadecimal digit
$ is printable
$ is a punctuation character
f is alphanumeric
f is alphabetic
f is printable
f is a hexadecimal digit
! is printable
! is a punctuation character
a is alphanumeric
a is alphabetic
a is printable
a is a hexadecimal digit
3 is alphanumeric
3 is a digit
3 is printable
3 is a hexadecimal digit
 
C:\rosettaCode>typeDetector.exe a
 
a is alphanumeric
a is alphabetic
a is printable
a is a hexadecimal digit
C:\rosettaCode>typeDetector.exe $
 
$ is printable
$ is a punctuation character
C:\rosettaCode>typeDetector.exe 3
 
3 is alphanumeric
3 is a digit
3 is printable
3 is a hexadecimal digit
</pre>
 
===Dispatch by ''tagged union''===
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
 
typedef enum {
STRING,
INPUT_FILE
} tag_t;
 
typedef struct {
tag_t tag;
union {
char *string;
FILE *input_file;
} value;
} source_t;
 
void
print_text (source_t source)
{
switch (source.tag)
{
case STRING:
fputs (source.value.string, stdout);
break;
case INPUT_FILE:
{
int c;
c = getc (source.value.input_file);
while (c != EOF)
{
putc (c, stdout);
c = getc (source.value.input_file);
}
}
break;
default:
assert (false);
}
}
 
int
main ()
{
source_t source;
 
source.tag = STRING;
source.value.string = "This\nis a\ntext.\n";
print_text (source);
 
source.tag = INPUT_FILE;
source.value.input_file = fopen ("type_detection-c.c", "r");
print_text (source);
}</syntaxhighlight>
{{out}}
$ cc type_detection-c.c && ./a.out
<pre>This
is a
text.
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
 
typedef enum {
STRING,
INPUT_FILE
} tag_t;
 
typedef struct {
tag_t tag;
union {
char *string;
FILE *input_file;
} value;
} source_t;
 
void
print_text (source_t source)
{
switch (source.tag)
{
case STRING:
fputs (source.value.string, stdout);
break;
case INPUT_FILE:
{
int c;
c = getc (source.value.input_file);
while (c != EOF)
{
putc (c, stdout);
c = getc (source.value.input_file);
}
}
break;
default:
assert (false);
}
}
 
int
main ()
{
source_t source;
 
source.tag = STRING;
source.value.string = "This\nis a\ntext.\n";
print_text (source);
 
source.tag = INPUT_FILE;
source.value.input_file = fopen ("type_detection-c.c", "r");
print_text (source);
}</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
namespace TypeDetection {
class C { }
struct S { }
enum E {
NONE,
}
 
class Program {
static void ShowType<T>(T t) {
Console.WriteLine("The type of '{0}' is {1}", t, t.GetType());
}
 
static void Main() {
ShowType(5);
ShowType(7.5);
ShowType('d');
ShowType(true);
ShowType("Rosetta");
ShowType(new C());
ShowType(new S());
ShowType(E.NONE);
ShowType(new int[] { 1, 2, 3 });
}
}
}</syntaxhighlight>
{{out}}
<pre>The type of '5' is System.Int32
The type of '7.5' is System.Double
The type of 'd' is System.Char
The type of 'True' is System.Boolean
The type of 'Rosetta' is System.String
The type of 'TypeDetection.C' is TypeDetection.C
The type of 'TypeDetection.S' is TypeDetection.S
The type of 'NONE' is TypeDetection.E
The type of 'System.Int32[]' is System.Int32[]</pre>
 
=={{header|C++}}==
{{trans|D}}
<syntaxhighlight lang="cpp">#include <iostream>
 
template <typename T>
auto typeString(const T&) {
return typeid(T).name();
}
 
class C {};
struct S {};
 
int main() {
std::cout << typeString(1) << '\n';
std::cout << typeString(1L) << '\n';
std::cout << typeString(1.0f) << '\n';
std::cout << typeString(1.0) << '\n';
std::cout << typeString('c') << '\n';
std::cout << typeString("string") << '\n';
std::cout << typeString(C{}) << '\n';
std::cout << typeString(S{}) << '\n';
std::cout << typeString(nullptr) << '\n';
}</syntaxhighlight>
{{out}}
<pre>int
long
float
double
char
char [7]
class C
struct S
std::nullptr_t</pre>
 
=={{header|Crystal}}==
<syntaxhighlight lang="ruby">def print_type(x)
puts "Compile-time type of #{x} is #{typeof(x)}"
puts " Actual runtime type is #{x.class}" if x.class != typeof(x)
end
 
print_type 123
print_type 123.45
print_type rand < 0.5 ? "1" : 0
print_type rand < 1.5
print_type nil
print_type 'c'
print_type "str"
print_type [1,2]
print_type({ 2, "two" })
print_type({a: 1, b: 2})
print_type ->(x : Int32){ x+2 > 0 }
</syntaxhighlight>
{{out}}
<pre>Compile-time type of 123 is Int32
Compile-time type of 123.45 is Float64
Compile-time type of 0 is (Int32 | String)
Actual runtime type is Int32
Compile-time type of true is Bool
Compile-time type of is Nil
Compile-time type of c is Char
Compile-time type of str is String
Compile-time type of [1, 2] is Array(Int32)
Compile-time type of {2, "two"} is Tuple(Int32, String)
Compile-time type of {a: 1, b: 2} is NamedTuple(a: Int32, b: Int32)
Compile-time type of #<Proc(Int32, Bool):0x5645695ab9f0> is Proc(Int32, Bool)
</pre>
 
=={{header|D}}==
<syntaxhighlight lang="d">import std.stdio;
 
auto typeString(T)(T _) {
return T.stringof;
}
 
class C {}
struct S {}
 
void main() {
writeln(typeString(1));
writeln(typeString(1L));
writeln(typeString(1.0f));
writeln(typeString(1.0));
writeln(typeString('c'));
writeln(typeString("string"));
writeln(typeString(new C()));
writeln(typeString(S()));
writeln(typeString(null));
}</syntaxhighlight>
 
{{out}}
<pre>int
long
float
double
char
string
C
S
typeof(null)</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
printfn "%A" (3.14.GetType())
let inline fN g=g.GetType()|>string
printfn "%s" (fN "Nigel")
printfn "%s" (fN 23)
</syntaxhighlight>
{{out}}
<pre>
System.Double
System.String
System.Int32
</pre>
=={{header|Factor}}==
Using dynamic dispatch:
<syntaxhighlight lang="text">USING: arrays formatting io kernel math prettyprint sequences
strings ;
IN: rosetta-code.type-detection
 
GENERIC: myprint ( object -- )
 
M: object myprint drop "I don't know how to print this." print ;
M: string myprint "I'm a string: \"%s\"\n" printf ;
M: fixnum myprint "I'm a fixnum: " write . ;
M: array myprint "I'm an array: { " write
[ pprint bl ] each "}" print ;
"Hello world." myprint
{ 1 2 3 4 5 } myprint
123 myprint
3.1415 myprint</syntaxhighlight>
{{out}}
<pre>
I'm a string: "Hello world."
I'm an array: { 1 2 3 4 5 }
I'm a fixnum: 123
I don't know how to print this.
</pre>
 
=={{header|Fortran}}==
 
Fortran 2008 and later can do this with general types, using the unlimited polymorphic class ''class(*)''.
 
Polymorphism involving types derived from a base type can be done in Fortran 2003 and later.
 
There is also, in modern Fortran, an overload mechanism that can be used to give procedures that take different types the same name.
 
Legacy versions of Fortran have ways to store data of one type in a variable declared as some other type, and this mechanism could be employed.
 
===Unlimited procedure polymorphism===
Below I use ‘class(*)’. The ‘print_text’ subroutine is used to print a string, an array of strings, and an input file.
 
<syntaxhighlight lang="fortran">program input_type_detection_demo
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
type(text_block_t) :: text_block
integer :: i
 
call print_text ('Print me.')
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text (source)
class(*), intent(in) :: source
 
select type (source)
 
type is (character(len = *))
! Print a single character string.
write (*, '(A)') source
 
class is (text_block_t)
! Print an array of lines.
block
integer :: i
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end block
 
type is (integer)
! Print a file.
block
character(len = 10000) :: line_buffer
integer :: stat
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end block
 
class default
! There is no handler for the type.
error stop
 
end select
end subroutine print_text
 
end program input_type_detection_demo</syntaxhighlight>
 
{{out}}
$ gfortran type_detection-fortran.f90 && ./a.out
<pre>Print me.
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
program input_type_detection_demo
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
type(text_block_t) :: text_block
integer :: i
 
call print_text ('Print me.')
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text (source)
class(*), intent(in) :: source
 
select type (source)
 
type is (character(len = *))
! Print a single character string.
write (*, '(A)') source
 
class is (text_block_t)
! Print an array of lines.
block
integer :: i
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end block
 
type is (integer)
! Print a file.
block
character(len = 10000) :: line_buffer
integer :: stat
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end block
 
class default
! There is no handler for the type.
error stop
 
end select
end subroutine print_text
 
end program input_type_detection_demo</pre>
 
===Generic procedures (overloading)===
In the following, the name ''print_text'' refers to two distinct subroutines. Which of the two is called depends on the type of the argument in the call; the decision is made ''at compile time''.
 
(To use this mechanism in a library, one would want to use modules. Nevertheless, the program below illustrates the principle more simply.)
 
<syntaxhighlight lang="fortran">program type_detection_demo
 
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
interface print_text
procedure print_text_text_block_t
procedure print_text_file_unit
end interface print_text
 
type(text_block_t) :: text_block
integer :: i
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran-2.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text_text_block_t (source)
class(text_block_t), intent(in) :: source
 
integer :: i
 
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end subroutine print_text_text_block_t
 
subroutine print_text_file_unit (source)
integer, intent(in) :: source
 
character(len = 10000) :: line_buffer
integer :: stat
 
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end subroutine print_text_file_unit
 
end program type_detection_demo</syntaxhighlight>
{{out}}
$ gfortran type_detection-fortran-2.f90 && ./a.out
<pre>i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
program type_detection_demo
 
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
interface print_text
procedure print_text_text_block_t
procedure print_text_file_unit
end interface print_text
 
type(text_block_t) :: text_block
integer :: i
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran-2.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text_text_block_t (source)
class(text_block_t), intent(in) :: source
 
integer :: i
 
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end subroutine print_text_text_block_t
 
subroutine print_text_file_unit (source)
integer, intent(in) :: source
 
character(len = 10000) :: line_buffer
integer :: stat
 
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end subroutine print_text_file_unit
 
end program type_detection_demo</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">'Rosetta Code problem: https://rosettacode.org/wiki/Type_detection
'by Jjuanhdez, 02/2023
 
#macro typeDetector(arg)
#if TypeOf(foo) = TypeOf(Byte)
Print arg; " -> It's a Byte!"
#elseif TypeOf(foo) = TypeOf(Short)
Print arg; " -> It's a Short!"
#elseif TypeOf(foo) = TypeOf(Integer)
Print arg; " -> It's a Integer!"
#elseif TypeOf(foo) = TypeOf(LongInt)
Print arg; " -> It's a LongInt!"
#elseif TypeOf(foo) = TypeOf(UByte)
Print arg; " -> It's a UByte!"
#elseif TypeOf(foo) = TypeOf(UShort)
Print arg; " -> It's a UShort!"
#elseif TypeOf(foo) = TypeOf(UInteger)
Print arg; " -> It's a UInteger!"
#elseif TypeOf(foo) = TypeOf(ULongInt)
Print arg; " -> It's a ULongInt!"
#elseif TypeOf(foo) = TypeOf(Single)
Print arg; " -> It's a Single!"
#elseif TypeOf(foo) = TypeOf(Double)
Print arg; " -> It's a Double!"
#elseif TypeOf(foo) = TypeOf(integer ptr)
Print arg; " -> It's a Integer ptr!"
#elseif TypeOf(foo) = TypeOf(byte ptr)
Print arg; " -> It's a Byte ptr!"
#elseif TypeOf(foo) = TypeOf(String)
Print arg; " -> It's a String!"
#endif
#endmacro
 
'Var declares a variable whose type is implied from the initializer expression.
'Var foo = -6728 '' implicit integer
'Var foo = 1.985766472453666 '' implicit double
Var foo = "Rosetta Code" '' var-len string
 
typeDetector (foo)
Sleep</syntaxhighlight>
 
=={{header|Go}}==
Note that Go doesn't really have a character type. A single quoted character (such as 'd') is by default a ''rune'' (or 32 bit integer) literal representing its Unicode code-point.
<syntaxhighlight lang="go">package main
 
import "fmt"
 
type any = interface{}
 
func showType(a any) {
switch a.(type) {
case rune:
fmt.Printf("The type of '%c' is %T\n", a, a)
default:
fmt.Printf("The type of '%v' is %T\n", a, a)
}
}
 
func main() {
values := []any{5, 7.5, 2 + 3i, 'd', true, "Rosetta"}
for _, value := range values {
showType(value)
}
}</syntaxhighlight>
 
{{out}}
<pre>
The type of '5' is int
The type of '7.5' is float64
The type of '(2+3i)' is complex128
The type of 'd' is int32
The type of 'true' is bool
The type of 'Rosetta' is string
</pre>
 
=={{header|Goaldi}}==
{{trans|Icon}}
 
<syntaxhighlight lang="goaldi">procedure main() {
print_text("This\nis a\ntext.\n")
print_text(file("type_detection-goaldi.gd"))
}
 
procedure print_text(source) {
case type(source) of {
string : writes(source)
file : while write(read(source))
}
}</syntaxhighlight>
 
{{out}}
$ goaldi type_detection-goaldi.gd
<pre>This
is a
text.
procedure main() {
print_text("This\nis a\ntext.\n")
print_text(file("type_detection-goaldi.gd"))
}
 
procedure print_text(source) {
case type(source) of {
string : writes(source)
file : while write(read(source))
}
}</pre>
 
=={{header|Icon}}==
 
This should work with the Unicon compiler, but I currently have only the Arizona Icon compiler to test it with.
 
See also [[#ObjectIcon|ObjectIcon]] and [[#Goaldi|Goaldi]].
 
<syntaxhighlight lang="icon">procedure main()
print_text("This\nis\na text.\n")
print_text(open("type_detection-icon.icn"))
end
 
procedure print_text(source)
case type(source) of {
"string" : writes(source)
"file" : while write(read(source))
}
end</syntaxhighlight>
{{out}}
$ icont -u -s type_detection-icon.icn && ./type_detection-icon
<pre>This
is
a text.
procedure main()
print_text("This\nis\na text.\n")
print_text(open("type_detection-icon.icn"))
end
 
procedure print_text(source)
case type(source) of {
"string" : writes(source)
"file" : while write(read(source))
}
end</pre>
 
=={{header|J}}==
 
Presumably this satisfies the task requirements...
 
<syntaxhighlight lang="j"> echo 'one'
one
echo 1
1</syntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">public class TypeDetection {
private static void showType(Object a) {
if (a instanceof Integer) {
System.out.printf("'%s' is an integer\n", a);
} else if (a instanceof Double) {
System.out.printf("'%s' is a double\n", a);
} else if (a instanceof Character) {
System.out.printf("'%s' is a character\n", a);
} else {
System.out.printf("'%s' is some other type\n", a);
}
}
 
public static void main(String[] args) {
showType(5);
showType(7.5);
showType('d');
showType(true);
}
}</syntaxhighlight>
{{out}}
<pre>'5' is an integer
'7.5' is a double
'd' is a character
'true' is some other type</pre>
 
=={{header|JavaScript}}==
 
[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Ftypeof]
Line 16 ⟶ 1,070:
</pre>
 
=={{header|jq}}==
== OASYS Assembler ==
In jq, the function that returns the JSON type of a JSON entity is
<code>type/0</code>. It returns "object", "array", "boolean", "string", or "number".
 
Given arbitrary UTF-8 input, it could be used like so:
<lang oasys_oaa>
 
try type catch "invalid JSON"
 
Given some text of unknown type, a "typeof" function could be
written to determine whether the string could be interpreted as a
JSON document, and if so, what JSON type it would have, as follows:
 
def typeof:
try (fromjson | type) catch "string" ;
 
Here is an illustrative transcript from an interactive session showing input and output on alternate lines:
<pre>
$ jq -R 'try (fromjson | type) catch "string"'
abc
"string"
{"a":1,"b":2}
"object"
[1,"a"]
"array"
</pre>
 
=={{header|Julia}}==
In Julia, the function that returns the type of an object is the
<code>typeof</code> function, and the function <code>isa</code> tests
whether an object is of that type.
<syntaxhighlight lang="julia">
 
julia> a = 1
1
 
julia> typeof(a)
Int32
 
julia> b = 1.0
1.0
 
julia> typeof(b)
Float64
 
julia> 1.0 isa Number
true
 
julia> 1.0 isa Int
false
 
julia> 1 isa Int
true
 
julia> typeof("hello")
String
 
julia> typeof(typeof("hello"))
DataType
 
julia> typeof(Set([1,3,4]))
Set{Int64}
 
julia> 1 isa String
false
 
julia> "1" isa Number
false
 
julia> "1" isa String
true
 
julia> isa(1.0,Float32)
false
 
julia> isa(1.0,Float64)
true
 
</syntaxhighlight>
 
=={{header|OASYS Assembler}}==
 
<syntaxhighlight lang="oasys_oaa">
; The following method checks if a global variable or property is an
; object type. Does not work with locals and arguments.
Line 29 ⟶ 1,162:
/>1RF ; It is clear
:>0RF ; It is not clear
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
== PHP ==
<syntaxhighlight lang="scala">// version 1.0.6
fun showType(a: Any) = when (a) {
is Int -> println("'$a' is an integer")
is Double -> println("'$a' is a double")
is Char -> println("'$a' is a character")
else -> println("'$a' is some other type")
}
 
fun main(args: Array<String>) {
showType(5)
showType(7.5)
showType('d')
showType(true)
}</syntaxhighlight>
 
{{out}}
<pre>
'5' is an integer
'7.5' is a double
'd' is a character
'true' is some other type
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function writeValue(v)
local t = type(v)
if t == "number" then
io.write(v)
elseif t == "string" then
io.write("`" .. v .. "`")
elseif t == "table" then
local c = 0
io.write("{")
for k,v in pairs(v) do
if c > 0 then
io.write(", ")
end
writeValue(k)
io.write(" => ")
writeValue(v)
c = c + 1
end
io.write("}")
elseif t == "function" then
io.write("`" .. tostring(v) .. "`")
else
io.write("Unhandled type: " .. t)
end
end
 
function printType(v)
io.write("The value ")
writeValue(v)
print(" is of type " .. type(v))
end
 
function main()
printType(42)
printType(3.14)
printType("hello world")
printType({1, 2, 3, 4, 5})
printType(main)
end
 
main()</syntaxhighlight>
{{out}}
<pre>The value 42 is of type number
The value 3.14 is of type number
The value `hello world` is of type string
The value {1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5} is of type table
The value `function: 00C6C4A8` is of type function</pre>
 
=={{header|Nim}}==
As Nim is a statically typed language, there is no way to detect the type at runtime. But it is possible to write a procedure which writes text in ways depending on the type of a parameter.
 
===Using a generic procedure===
All is done at compile time. The generated code depends on the type of the parameter. We accept here any type, but only provide code to display text from a string and from a file and we emit an error for the other types.
<syntaxhighlight lang="nim">proc writeText[T](source: T) =
when T is string:
echo source
elif T is File:
echo source.readAll()
else:
echo "Unable to write text for type “", T, "”."
 
writeText("Hello world!")
writeText(stdin)
writeText(3) # Emit an error.</syntaxhighlight>
 
===Using variant objects===
We define a type “Source” which contains a discriminator (tag) which is used to define branches. The code to display the text contains a test on the tag. The only types allowed are those for which a tag value exists. Here, we defined two possible values: “kString” and “kFile”. The “type detection” is done at runtime, but these are not actual types but tag values.
<syntaxhighlight lang="nim">type Kind = enum kString, kFile
 
type Source = object
case kind: Kind
of kString: str: string
of kFile: file: File
 
proc writeText(source: Source) =
case source.kind
of kString: echo source.str
of kFile: echo source.file.readAll()
 
let s1 = Source(kind: kString, str: "Hello world!")
let s2 = Source(kind: kFile, file: stdin)
 
s1.writeText()
s2.writeText()</syntaxhighlight>
 
=={{header|ObjectIcon}}==
{{trans|Icon}}
<syntaxhighlight lang="objecticon">import io
 
procedure main()
print_text("This\nis\na text.\n")
print_text(open("type_detection-oi.icn"))
end
 
procedure print_text(source)
case type(source) of {
"string" : writes(source)
"object" : while write(source.read())
}
end</syntaxhighlight>
{{out}}
$ oit -s type_detection-oi.icn && ./type_detection-oi
<pre>This
is
a text.
import io
 
procedure main()
print_text("This\nis\na text.\n")
print_text(open("type_detection-oi.icn"))
end
 
procedure print_text(source)
case type(source) of {
"string" : writes(source)
"object" : while write(source.read())
}
end</pre>
 
=={{header|Pascal}}==
===Dispatch by ''variant record''===
Pascal has a plethora of dialects, and so I have tried to be as close to ''Algorithms + Data Structures = Programs'' (Wirth) style as I could figure out how, when using the Free Pascal Compiler.
 
<syntaxhighlight lang="pascal">program typedetectiondemo (input, output);
type
sourcetype = record case kind : (builtintext, filetext) of
builtintext : (i : integer);
filetext : (f : file of char);
end;
 
var
source : sourcetype;
input : file of char;
c : char;
 
procedure printtext (source : sourcetype);
begin
case source.kind of
builtintext : case source.i of
1 : writeln ('This is text 1.');
2 : writeln ('This is text 2.')
end;
filetext : while not eof (source.f) do
begin
read (source.f, c);
write (c)
end
end
end;
 
begin
assign (input, 'type_detection-pascal.pas');
reset (input);
with source do
begin
kind := builtintext;
i := 1;
printtext (source);
i := 2;
printtext (source);
kind := filetext;
f := input;
printtext (source)
end
end.</syntaxhighlight>
 
{{out}}
$ fpc -Miso type_detection-pascal.pas && ./type_detection-pascal
<pre>This is text 1.
This is text 2.
program typedetectiondemo (input, output);
type
sourcetype = record case kind : (builtintext, filetext) of
builtintext : (i : integer);
filetext : (f : file of char);
end;
 
var
source : sourcetype;
input : file of char;
c : char;
 
procedure printtext (source : sourcetype);
begin
case source.kind of
builtintext : case source.i of
1 : writeln ('This is text 1.');
2 : writeln ('This is text 2.')
end;
filetext : while not eof (source.f) do
begin
read (source.f, c);
write (c)
end
end
end;
 
begin
assign (input, 'type_detection-pascal.pas');
reset (input);
with source do
begin
kind := builtintext;
i := 1;
printtext (source);
i := 2;
printtext (source);
kind := filetext;
f := input;
printtext (source)
end
end.</pre>
 
=={{header|Perl}}==
The function <code>ref</code> takes a reference to a variable, via '\', and returns the type. Some of the more common are shown here.
In the cases where the value in question is already a reference (<code>$regex</code> and <code>$subref</code>) the '\' is not used.
<syntaxhighlight lang="perl">$scalar = 1;
@array = (1, 2);
%hash = ('a' => 1);
$regex = qr/foo.*bar/;
$reference = \%hash;
sub greet { print "Hello world!" };
$subref = \&greet;
 
$fmt = "%-11s is type: %s\n";
printf $fmt, '$scalar', ref(\$scalar);
printf $fmt, '@array', ref(\@array);
printf $fmt, '%hash', ref(\%hash);
printf $fmt, '$regex', ref( $regex);
printf $fmt, '$reference', ref(\$reference);
printf $fmt, '$subref', ref( $subref);</syntaxhighlight>
{{out}}
<pre>$scalar is type: SCALAR
@array is type: ARRAY
%hash is type: HASH
$regex is type: Regexp
$reference is type: REF
$subref is type: CODE</pre>
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
Phix builtin type tests are: integer(), atom(), string(), sequence(), and object(). The latter returns true unless arg is unassigned, also notice that showtype never even attempts to set t to "object", since it is guaranteed to be one of the other four.
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">procedure</span> <span style="color: #000000;">showtype</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">o</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)?</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"integer"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"atom"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"string"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"sequence"</span><span style="color: #0000FF;">))</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">o</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">showtype</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtype</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7.5</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtype</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"string"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtype</span><span style="color: #0000FF;">({</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7.5</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"string"</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{"integer",5}
{"atom",7.5}
{"string","string"}
{"sequence",{5,7.5,"string"}}
</pre>
 
=={{header|PicoLisp}}==
PicoLisp have only three base data [http://software-lab.de/doc/ref.html#data types].
<pre>
: (num? 123)
-> 123
: (num? (1 2 3))
-> NIL
: (sym? 'a)
-> T
: (sym? 123)
-> NIL
: (lst? NIL)
-> T
: (lst? (1 . 2))
-> T
: (lst? (1 2 3))
-> T
</pre>
 
=={{header|PHP}}==
 
[http://php.net/manual/en/function.gettype.php]
Line 43 ⟶ 1,482:
 
* [http://php.net/manual/en/function.is-array.php is_array()]
 
=={{header|PowerShell}}==
In PowerShell everything is an object and all objects have the GetType() method:
<syntaxhighlight lang="powershell">
[string]$str = "123"
$str.GetType()
</syntaxhighlight>
{{Out}}
<pre>
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
</pre>
<syntaxhighlight lang="powershell">
[int]$int = $str -as [int]
$int.GetType()
</syntaxhighlight>
{{Out}}
<pre>
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Int32 System.ValueType
</pre>
 
=={{header|Python}}==
Built-in function <code>type()</code>
<pre>
>>> type('foo')
<class 'str'>
>>> type(12345)
<class 'int'></pre>
 
Testing types
<pre>
>>> type('foo') is str
True
>>> type(123.0) is not int
True
>>> type([]) is list
True
>>> type({}) is dict
True</pre>
 
=== Specific tester functions ===
 
* [https://docs.python.org/3/library/functions.html#isinstance isinstance()]
 
=={{header|Racket}}==
Hopefully you can see how to extend the code to add all sorts of other types. If I did this, I&rsquo;d swamp the task page.
A good list of types supported/provided by Racket can be found in the Typed Racket reference:
http://docs.racket-lang.org/ts-reference/type-ref.html
 
<syntaxhighlight lang="racket">#lang racket
 
(require racket/undefined)
 
(define fooer<%> (interface ()))
(define foo% (class* object% (fooer<%>)
(super-new)))
 
(struct my-tree (l v r))
;; -----------------------------------------------------------------------------
(define (n.t f)
(list f (regexp-replace #rx"\\?" (symbol->string (object-name f)) "")))
 
;; listed in the order (as close as) shown in
;; http://docs.racket-lang.org/guide/datatypes.html (section numbers next to
;; some entries)
(define type-tests.names
`(,@(map n.t
(list boolean? immutable? ; 3.1
))
;; the famous scheme numerical tower
,@(map n.t ; 3.2
(list number? complex? real? rational? integer? exact-integer?
exact-nonnegative-integer? exact-positive-integer?
inexact-real? fixnum? flonum? double-flonum? single-flonum?
zero? positive? negative? odd? even? exact? inexact?))
,@(map n.t
(list char? ; 3.3 --- there are also char-alphabetic? etc -- but they're not
; types as such
string? ; 3.4
byte? bytes? ; 3.5
symbol? ; 3.6
keyword? ; 3.7
pair? null? list? ; 3.8
vector? ; 3.9
hash? hash-equal? hash-eqv? hash-eq? hash-weak? ; 3.10
box? ; 3.11
void? ; 3.12
))
,(list (λ (v) (eq? v undefined)) "undefined") ; 3. 12
;; now we move to http://docs.racket-lang.org/reference/data.html
;; for section numbering
,@(map n.t
(list
regexp? pregexp? byte-regexp? byte-pregexp? ; 4.7
stream? sequence? ; 4.14
dict? ; 4.15
set-equal? set-eqv? set-eq? set? set-mutable? set-weak? ; 4.16
continuation? procedure? ; 4.17
))
;; class/interface testing
,(list (λ (v) (is-a? v object%)) "object%")
,(list (λ (v) (is-a? v foo%)) "foo%")
,(list (λ (v) (is-a? v fooer<%>)) "fooer<%>")
 
;; more types from reference (sections are top-level, mostly)
,@(map n.t
(list
syntax? ; 3.
my-tree? ; 5.
exn? exn:fail? exn:fail:filesystem? ; 10.2
promise? ; 10.3
))
 
;; there's all sorts of other types to test!
))
 
(define (->type-names v)
(let ((rv (for/list ((t.n (in-list type-tests.names))
#:when (with-handlers
((exn? (λ (x) #f)))
((car t.n) v))) (cadr t.n))))
(if (null? rv) (list "UNKNOWN") rv)))
 
(module+ test
(require xml/xml)
 
(define test-values
(list 3.+4.i 3+4i (- pi) pi 0. 0 -0.5 0.5 -1/3 1/3
-12345678909876543210123456789 12345678909876543210123456788 -132 133
#\t #\null
"" "monkeys" "\u03BB"
-1 255 256
#"" #"nibble"
'hello '||
'#:woo
'() '(1 . 2) '(3) '(5 6)
 
#() #(1) #("foo" 2 'bar)
 
(make-hash)
(make-hasheq)
(make-hasheqv)
(hash)
(hasheq)
(hasheqv)
(make-weak-hash)
(make-weak-hasheq)
(make-weak-hasheqv)
(make-immutable-hash)
(make-immutable-hasheq)
(make-immutable-hasheqv)
 
(box "x")
(void)
undefined
#rx".*" #px"3?" #rx#"t.m" #px#".i."
(in-vector #(1 2 3)) (stream 1 2 3)
#hash((a . "apple")) #("apple" "binana") '("apple" "binana")
'((a . "apple") (b . "binana"))
(set 1 2 3) (seteq 1 2 3) (seteqv 1 2 3)
(mutable-set 1 2 3) (mutable-seteq 1 2 3) (mutable-seteqv 1 2 3)
(weak-set 1 2 3) (weak-seteq 1 2 3) (weak-seteqv 1 2 3)
 
+ (λ (x) #t) (call/cc (λ (k) k))
 
(new object%) (new foo%)
 
#'(xxy zzy)
(my-tree (my-tree #f 1 #f) 2 #f)
(with-handlers ((exn? values)) (error 'aargh!))
(with-handlers ((exn? values))
(file->string "/tmp/there-is-no-way-this-file-exists---surely?"))
(delay 3)
))
 
;; tempted to print a cross-reference table, but that would be too wide for RC (maybe)
(write-xexpr #:insert-newlines? #f
`(table (thead (tr (th "Value [~s]") (th "->type-name")))
"\n"
(tbody ,@(map (λ (v) `(tr "\n" (td ,(~s v))
(td ,(string-join (->type-names v) ", "))))
test-values)))))
</syntaxhighlight>
 
{{out}}
 
The following table is generated:
 
<table><thead><tr><th>Value [~s]</th><th>-&gt;type-name</th></tr></thead>
<tbody><tr>
<td>3.0+4.0i</td><td>number, complex, inexact</td></tr><tr>
<td>3+4i</td><td>number, complex, exact</td></tr><tr>
<td>-3.141592653589793</td><td>number, complex, real, rational, inexact-real, flonum, double-flonum, negative, inexact</td></tr><tr>
<td>3.141592653589793</td><td>number, complex, real, rational, inexact-real, flonum, double-flonum, positive, inexact</td></tr><tr>
<td>0.0</td><td>number, complex, real, rational, integer, inexact-real, flonum, double-flonum, zero, even, inexact</td></tr><tr>
<td>0</td><td>number, complex, real, rational, integer, exact-integer, exact-nonnegative-integer, fixnum, zero, even, exact, byte, sequence</td></tr><tr>
<td>-0.5</td><td>number, complex, real, rational, inexact-real, flonum, double-flonum, negative, inexact</td></tr><tr>
<td>0.5</td><td>number, complex, real, rational, inexact-real, flonum, double-flonum, positive, inexact</td></tr><tr>
<td>-1/3</td><td>number, complex, real, rational, negative, exact</td></tr><tr>
<td>1/3</td><td>number, complex, real, rational, positive, exact</td></tr><tr>
<td>-12345678909876543210123456789</td><td>number, complex, real, rational, integer, exact-integer, negative, odd, exact</td></tr><tr>
<td>12345678909876543210123456788</td><td>number, complex, real, rational, integer, exact-integer, exact-nonnegative-integer, exact-positive-integer, positive, even, exact, sequence</td></tr><tr>
<td>-132</td><td>number, complex, real, rational, integer, exact-integer, fixnum, negative, even, exact</td></tr><tr>
<td>133</td><td>number, complex, real, rational, integer, exact-integer, exact-nonnegative-integer, exact-positive-integer, fixnum, positive, odd, exact, byte, sequence</td></tr><tr>
<td>#\t</td><td>char</td></tr><tr>
<td>#\nul</td><td>char</td></tr><tr>
<td>""</td><td>immutable, string, sequence</td></tr><tr>
<td>"monkeys"</td><td>immutable, string, sequence</td></tr><tr>
<td>"λ"</td><td>immutable, string, sequence</td></tr><tr>
<td>-1</td><td>number, complex, real, rational, integer, exact-integer, fixnum, negative, odd, exact</td></tr><tr>
<td>255</td><td>number, complex, real, rational, integer, exact-integer, exact-nonnegative-integer, exact-positive-integer, fixnum, positive, odd, exact, byte, sequence</td></tr><tr>
<td>256</td><td>number, complex, real, rational, integer, exact-integer, exact-nonnegative-integer, exact-positive-integer, fixnum, positive, even, exact, sequence</td></tr><tr>
<td>#""</td><td>immutable, bytes, sequence</td></tr><tr>
<td>#"nibble"</td><td>immutable, bytes, sequence</td></tr><tr>
<td>hello</td><td>symbol</td></tr><tr>
<td>||</td><td>symbol</td></tr><tr>
<td>#:woo</td><td>keyword</td></tr><tr>
<td>()</td><td>null, list, stream, sequence, dict</td></tr><tr>
<td>(1 . 2)</td><td>pair</td></tr><tr>
<td>(3)</td><td>pair, list, stream, sequence</td></tr><tr>
<td>(5 6)</td><td>pair, list, stream, sequence</td></tr><tr>
<td>#()</td><td>immutable, vector, sequence, dict</td></tr><tr>
<td>#(1)</td><td>immutable, vector, sequence, dict</td></tr><tr>
<td>#("foo" 2 (quote bar))</td><td>immutable, vector, sequence, dict</td></tr><tr>
<td>#hash()</td><td>hash, hash-equal, sequence, dict</td></tr><tr>
<td>#hasheq()</td><td>hash, hash-eq, sequence, dict</td></tr><tr>
<td>#hasheqv()</td><td>hash, hash-eqv, sequence, dict</td></tr><tr>
<td>#hash()</td><td>immutable, hash, hash-equal, sequence, dict</td></tr><tr>
<td>#hasheq()</td><td>immutable, hash, hash-eq, sequence, dict</td></tr><tr>
<td>#hasheqv()</td><td>immutable, hash, hash-eqv, sequence, dict</td></tr><tr>
<td>#&lt;hash&gt;</td><td>hash, hash-equal, hash-weak, sequence, dict</td></tr><tr>
<td>#&lt;hash&gt;</td><td>hash, hash-eq, hash-weak, sequence, dict</td></tr><tr>
<td>#&lt;hash&gt;</td><td>hash, hash-eqv, hash-weak, sequence, dict</td></tr><tr>
<td>#hash()</td><td>immutable, hash, hash-equal, sequence, dict</td></tr><tr>
<td>#hasheq()</td><td>immutable, hash, hash-eq, sequence, dict</td></tr><tr>
<td>#hasheqv()</td><td>immutable, hash, hash-eqv, sequence, dict</td></tr><tr>
<td>#&amp;"x"</td><td>box</td></tr><tr>
<td>#&lt;void&gt;</td><td>void</td></tr><tr>
<td>#&lt;undefined&gt;</td><td>undefined</td></tr><tr>
<td>#rx".*"</td><td>regexp</td></tr><tr>
<td>#px"3?"</td><td>regexp, pregexp</td></tr><tr>
<td>#rx#"t.m"</td><td>byte-regexp</td></tr><tr>
<td>#px#".i."</td><td>byte-regexp, byte-pregexp</td></tr><tr>
<td>#&lt;sequence&gt;</td><td>sequence</td></tr><tr>
<td>#&lt;stream&gt;</td><td>stream, sequence</td></tr><tr>
<td>#hash((a . "apple"))</td><td>immutable, hash, hash-equal, sequence, dict</td></tr><tr>
<td>#("apple" "binana")</td><td>immutable, vector, sequence, dict</td></tr><tr>
<td>("apple" "binana")</td><td>pair, list, stream, sequence</td></tr><tr>
<td>((a . "apple") (b . "binana"))</td><td>pair, list, stream, sequence, dict</td></tr><tr>
<td>#&lt;set: 1 3 2&gt;</td><td>stream, sequence, set-equal, set</td></tr><tr>
<td>#&lt;seteq: 1 2 3&gt;</td><td>stream, sequence, set-eq, set</td></tr><tr>
<td>#&lt;seteqv: 1 2 3&gt;</td><td>stream, sequence, set-eqv, set</td></tr><tr>
<td>#&lt;mutable-set: 1 2 3&gt;</td><td>sequence, set-equal, set-mutable</td></tr><tr>
<td>#&lt;mutable-seteq: 1 2 3&gt;</td><td>sequence, set-eq, set-mutable</td></tr><tr>
<td>#&lt;mutable-seteqv: 1 2 3&gt;</td><td>sequence, set-eqv, set-mutable</td></tr><tr>
<td>#&lt;weak-set: 1 3 2&gt;</td><td>sequence, set-equal, set-weak</td></tr><tr>
<td>#&lt;weak-seteq: 1 2 3&gt;</td><td>sequence, set-eq, set-weak</td></tr><tr>
<td>#&lt;weak-seteqv: 1 2 3&gt;</td><td>sequence, set-eqv, set-weak</td></tr><tr>
<td>#&lt;procedure:+&gt;</td><td>procedure</td></tr><tr>
<td>#&lt;procedure:...pe-detection.rkt:113:13&gt;</td><td>procedure</td></tr><tr>
<td>#&lt;continuation&gt;</td><td>continuation, procedure</td></tr><tr>
<td>#(struct:object)</td><td>object%</td></tr><tr>
<td>#(struct:object:foo% ...)</td><td>object%, foo%, fooer&lt;%&gt;</td></tr><tr>
<td>#&lt;syntax:D:\Users\tim\Dropbox\hacking\rosettacode\type-detection.rkt:117:13 (xxy zzy)&gt;</td><td>syntax</td></tr><tr>
<td>#&lt;my-tree&gt;</td><td>my-tree</td></tr><tr>
<td>#(struct:exn:fail "error: aargh!" #&lt;continuation-mark-set&gt;)</td><td>exn, exn:fail</td></tr><tr>
<td>#(struct:exn:fail:filesystem "file-size: file not found\n path: D:/tmp/there-is-no-way-this-file-exists---surely?" #&lt;continuation-mark-set&gt;)</td><td>exn, exn:fail, exn:fail:filesystem</td></tr><tr>
<td>#&lt;promise:...e/type-detection.rkt:122:11&gt;</td><td>promise</td></tr></tbody></table>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2020.08.1}}
Raku is a dynamic language that has gradual, duck typing. It provides introspection methods through its comprehensive MOP (Meta Object Protocol) making it easy to do type detection, subroutine signatures and multi-dispatch. Raku types have two general flavors: content types and container types. Different container types have varying restrictions on what sort of content they can contain and in return provide specialized methods to operate on those contents. Content types give the compiler hints on how to best handle the information, what storage requirements it may have, what operators will work with it, etc.
 
This is really a very broad and kind of hand-wavey overview of Raku types. For much more in-depth coverage see: https://docs.raku.org/type.html
 
<syntaxhighlight lang="raku" line>sub type ($t) { say $t.raku, "\tis type: ", $t.WHAT }
 
# some content types
.&type for 1, 2.0, 3e0, 4i, π, Inf, NaN, 'String';
 
# some primitive container types
.&type for $, [ ], @, { }, %, (5 .. 7), (8 ... 10), /0/, {;}, sub {}, ( );
 
# undefined things
.&type for Any, Nil;
 
# user defined types
class my-type { };
 
my my-type $object;
 
$object.&type;</syntaxhighlight>
 
{{out}}
<pre>1 is type: (Int)
2.0 is type: (Rat)
3e0 is type: (Num)
<0+4i> is type: (Complex)
3.14159265358979e0 is type: (Num)
Inf is type: (Num)
NaN is type: (Num)
"String" is type: (Str)
Any is type: (Any)
$[] is type: (Array)
$[] is type: (Array)
{} is type: (Hash)
{} is type: (Hash)
5..7 is type: (Range)
(8, 9, 10).Seq is type: (Seq)
/0/ is type: (Regex)
-> ;; $_? is raw { #`(Block|61385680) ... } is type: (Block)
sub () { #`(Sub|62948936) ... } is type: (Sub)
$() is type: (List)
Any is type: (Any)
Nil is type: Nil
my-type is type: (my-type)</pre>
 
=={{header|REXX}}==
These are some of the tests that can be performed on REXX variables (values) to determine which &nbsp; ''type'' &nbsp; they are.
 
Although everything &nbsp; (as far as variables are concerning) &nbsp; in the REXX language is a character string, &nbsp; character
<br>strings can be classified by having certain characteristics, &nbsp; or in other words, ''types''.
<br>Characteristics of these &nbsp; ''types'' &nbsp; can overlap.
<syntaxhighlight lang="rexx">/*REXX program displays what "type" a variable is (based on the variable's value). */
signal on noValue /*trap for undefined REXX variables. */
y= 1938 ; call showType y /*╔═══════════════════════════════════╗*/
y= 77.1 ; call showType y /*║ All REXX variables are stored as ║*/
y= ; call showType y /*║ character strings, even numbers. ║*/
y= ' ' ; call showType y /*║ If a variable string is numeric, ║*/
y= 'abc' ; call showType y /*║ all comparisons (IF statements) ║*/
y= 'ABC' ; call showType y /*║ that are made with numbers are ║*/
y= 'aBc' ; call showType y /*║ compared numerically. If not ║*/
y= '1515'x ; call showType y /*║ numeric, the string is compared ║*/
y= '10 11'x ; call showType y /*║ char by char after leading and ║*/
y= '00 0001'b ; call showType y /*║ trailing blanks are removed, and ║*/
y= '1'b ; call showType y /*║ shorter strings are padded with ║*/
y= ' + 1938 ' ; call showType y /*║ blanks to match the longer string.║*/
y= ' - 1.2e4' ; call showType y /*╚═══════════════════════════════════╝*/
y= '1' ; call showType y /* */
call showType yyy /*note: the variable YYY is undefined.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
noValue: say ' REXX variable ' condition("D") ' is undefined.'; exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
showType: procedure; parse arg x 1 xu; upper xu /*get true value & an uppercase version*/
@= ' value is'; say @ x
say @ 'of length' length(x)
if x =='' then say @ "null."
if x\=='' & x='' then say @ "all blank."
if datatype(x, 'N') then say @ "numeric (decimal)."
else say @ "a character string (not numeric)."
if datatype(x, 'W') then say @ "an integer (a whole number)."
if datatype(x, 'N') &,
\datatype(x, 'W') then say @ "not an integer."
if datatype(x, 'N') &,
pos('E', xu)\==0 then say @ "a number in exponential format."
if datatype(x, 'A') then say @ "an alphanumeric string."
if datatype(x, 'U') then say @ "all uppercase (Latin) letters."
if datatype(x, 'L') then say @ "all lowercase (Latin) letters."
if \datatype(x, 'L') &,
\datatype(x, 'U') &,
datatype(x, 'M') then say @ "of mixed case (Latin) letters."
if datatype(x, 'B') then say @ "binary."
if datatype(x, 'X') then say @ "hexadecimal."
if datatype(x, 'S') then say @ "a REXX symbol."
say copies('▒', 50) /*a fence that is used as a separator. */
return</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default data:}}
<pre>
value is 1938
value is of length 4
value is numeric (decimal).
value is an integer (a whole number).
value is an alphanumeric string.
value is hexadecimal.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is 77.1
value is of length 4
value is numeric (decimal).
value is not an integer.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is
value is of length 0
value is null.
value is a character string (not numeric).
value is binary.
value is hexadecimal.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is
value is of length 3
value is all blank.
value is a character string (not numeric).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is abc
value is of length 3
value is a character string (not numeric).
value is an alphanumeric string.
value is all lowercase (Latin) letters.
value is hexadecimal.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is ABC
value is of length 3
value is a character string (not numeric).
value is an alphanumeric string.
value is all uppercase (Latin) letters.
value is hexadecimal.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is aBc
value is of length 3
value is a character string (not numeric).
value is an alphanumeric string.
value is of mixed case (Latin) letters.
value is hexadecimal.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is §§
value is of length 2
value is a character string (not numeric).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is ►◄
value is of length 2
value is a character string (not numeric).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is ☺
value is of length 1
value is a character string (not numeric).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is ☺
value is of length 1
value is a character string (not numeric).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is + 1938
value is of length 8
value is numeric (decimal).
value is an integer (a whole number).
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is - 1.2e4
value is of length 8
value is numeric (decimal).
value is an integer (a whole number).
value is a number in exponential format.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
value is 1
value is of length 1
value is numeric (decimal).
value is an integer (a whole number).
value is an alphanumeric string.
value is binary.
value is hexadecimal.
value is a REXX symbol.
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
REXX variable YYY is undefined.
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Type detection
 
see "5 -> " + type(5) + nl
see "7.5 -> " + type(7.5) + nl
see "d -> " + type('d') + nl
</syntaxhighlight>
Output:
<pre>
5 -> NUMBER
7.5 -> NUMBER
d -> STRING
</pre>
 
=={{header|Rust}}==
 
While Rust compiles to machine code, it does provide multiple mechanisms for requesting that type information be preserved so that it can be queried at runtime.
 
===<code>enum</code>===
Rust has first-class support for tagged unions via the <code>enum</code> keyword.
 
The compiler will require that all possible values are handled, even if it's as simple as a fallthrough <code>_ => unreachable!()</code> which causes the program to die in a memory-safe way.
 
<syntaxhighlight lang="rust">enum ExpectedTypes {
Int(i64),
UInt(u64),
Real(f64),
Text(String),
Uncertain,
}
 
// Avoid having to prefix each variant name with ExpectedTypes::
use ExpectedTypes::*;
 
fn main() {
let enum_test = &[Int(-5), UInt(10), Real(-15.5), Text("Twenty".to_owned()),
Uncertain];
 
for entry in enum_test {
match entry {
Int(x) => println!("Got an integer: {}", x),
UInt(x) => println!("Got an unsigned integer: {}", x),
Real(x) => println!("Got a floating-point number: {}", x),
Text(x) => println!("Got a string of text: {}", x),
Uncertain => println!("Value is uncertain"),
}
}
}</syntaxhighlight>
 
Output:
<pre>Got an integer: -5
Got an unsigned integer: 10
Got a floating-point number: -15.5
Got a string of text: Twenty
Value is uncertain</pre>
 
(Rust also supports untagged unions, but they're only intended to be used for calling or exposing interfaces which use the C ABI.)
 
===Traits===
 
Rust traits are analogous to interfaces in other languages and support both monomorphic dispatch via generics (the compiler will generate a copy of the function for each combination of input arguments used) and polymorphic dispatch via type erasure (known as "Trait objects").
 
As Rust allows you to implement your own traits on other people's types, this can be used to implement type detection.
 
<syntaxhighlight lang="rust">use std::error::Error;
use std::fs::File;
use std::io::{self,prelude::*};
use std::net::TcpStream;
 
// Declare an Identify trait and implement it for a bunch of types
pub trait Identify {
fn id(&self) -> &'static str;
}
 
// Declare a macro to compact away the boilerplate
macro_rules! declare_id {
( $struct:ty, $id:ident ) => (
impl Identify for $struct {
fn id(&self) -> &'static str {
return stringify!($id);
}
}
)
}
 
// Use the macro to `impl` the Identify trait for a bunch of types
declare_id!(io::Empty, empty);
declare_id!(File, file_handle);
declare_id!(TcpStream, tcp_stream);
declare_id!(u8, int8);
declare_id!(&str, string);
 
// This uses monomorphic dispatch via generics.
// A copy of the function will be generated for each input type encountered
pub fn calc_size<R: Read + Identify>(readable: R) {
let id = readable.id();
let mut size = 0;
 
for _byte in readable.bytes() {
size += 1;
}
println!(" {}: {} bytes", id, size);
}
 
// This uses polymorphic dispatch via type erasure
pub fn identify(thing: &dyn Identify) {
println!(" Got {}", thing.id());
}
 
fn main() -> Result<(), Box<dyn Error>> {
println!("Monomorphic Generic Interface:");
calc_size(File::open("/bin/sh")?);
calc_size(io::empty());
calc_size(TcpStream::connect("127.0.0.1:37")?);
 
println!("\nPolymorphic Interface:");
for x in &[&15u8 as &dyn Identify, &"Hello" as &dyn Identify] {
identify(*x);
}
 
Ok(())
}</syntaxhighlight>
 
Output:
<pre>Monomorphic Generic Interface:
file_handle: 154072 bytes
empty: 0 bytes
tcp_stream: 4 bytes
 
Polymorphic Interface:
Got int8
Got string</pre>
 
===The <code>Any</code> trait===
 
Finally, while it's more limited than it appears, Rust does have some small degree of support for type introspection.
 
<syntaxhighlight lang="rust">use std::any::Any;
 
pub fn is_string(thing: &dyn Any) {
if thing.is::<&str>() {
println!("It's a string slice!");
} else {
println!("Dunno");
}
}
 
fn main() {
is_string(&"Hello, World!");
is_string(&5u16);
}</syntaxhighlight>
 
Output:
<pre>It's a string slice!
Dunno</pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">object TypeDetection extends App {
def showType(a: Any) = a match {
case a: Int => println(s"'$a' is an integer")
case a: Double => println(s"'$a' is a double")
case a: Char => println(s"'$a' is a character")
case _ => println(s"'$a' is some other type")
}
 
showType(5)
showType(7.5)
showType('d')
showType(true)
 
println(s"\nSuccessfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
 
}</syntaxhighlight>
 
=={{header|Scheme}}==
<syntaxhighlight lang="scheme">(define (print-text source)
(cond ((string? source)
;; The source is a string.
(display source))
 
((and (list? source)
(or (null? source) (string? (car source))))
;; The source is a list of strings.
(for-each display source))
 
((input-port? source)
;; The source is a file or similar.
(do ((s (read-line source) (read-line source)))
((eof-object? s))
(display s)
(newline)))))
 
(print-text "Print me.\n")
 
(print-text '("Print\n" "a list\n" "of strings.\n"))
 
(call-with-input-file "type_detection-scheme.scm" print-text)</syntaxhighlight>
 
{{out}}
Using CHICKEN 5 as an R7RS Scheme compiler.
 
$ csc -R r7rs type_detection-scheme.scm && ./type_detection-scheme
<pre>Print me.
Print
a list
of strings.
(define (print-text source)
(cond ((string? source)
;; The source is a string.
(display source))
 
((and (list? source)
(or (null? source) (string? (car source))))
;; The source is a list of strings.
(for-each display source))
 
((input-port? source)
;; The source is a file or similar.
(do ((s (read-line source) (read-line source)))
((eof-object? s))
(display s)
(newline)))))
 
(print-text "Print me.\n")
 
(print-text '("Print\n" "a list\n" "of strings.\n"))
 
(call-with-input-file "type_detection-scheme.scm" print-text)</pre>
 
=={{header|Smalltalk}}==
Just send class to any object and ask the class for its name...
<syntaxhighlight lang="smalltalk">typeOf := [:anyObject |
e'arg is of type {anyObject class name} and prints itself as: "{anyObject printString}"' printCR
].
typeOf value:1234.
typeOf value:1234.456.
typeOf value:(1/2).
typeOf value:(3+4i).
typeOf value:25 factorial.
typeOf value:true.
typeOf value:nil.
typeOf value:'hello world'.
typeOf value: (1 to:100).
typeOf value: (TopView new).
typeOf value: OperatingSystem. "a reference to the concrete OS"
typeOf value: Timestamp now.
typeOf value: #() class.
typeOf value: #() class class.
typeOf value: #() class new.
typeOf value: [ 1 print ].
typeOf value: thisContext. "that is the current continuation (stack frame)"
typeOf value: #+.
typeOf value: (SmallInteger >> #+).
[ 1 / 0 ] on:Error do:[:ex | typeOf value: ex ]. "catch the exception"
[ 1 fooBar ] on:Error do:[:ex | typeOf value: ex ].</syntaxhighlight>
{{out}}
<pre>arg is of type SmallInteger and prints itself as: "1234"
arg is of type Float and prints itself as: "1234.456"
arg is of type Fraction and prints itself as: "(1/2)"
arg is of type Complex and prints itself as: "(3+4i)"
arg is of type LargeInteger and prints itself as: "15511210043330985984000000"
arg is of type True and prints itself as: "true"
arg is of type UndefinedObject and prints itself as: "nil"
arg is of type String and prints itself as: "hello world"
arg is of type Interval and prints itself as: "1 to:100"
arg is of type TopView and prints itself as: "a TopView"
arg is of type OSXOperatingSystem class and prints itself as: "OSXOperatingSystem"
arg is of type Timestamp and prints itself as: "2020-12-25 23:51:33.275"
arg is of type ImmutableArray class and prints itself as: "ImmutableArray"
arg is of type Metaclass and prints itself as: "ImmutableArray class"
arg is of type ImmutableArray and prints itself as: "#()"
arg is of type Block and prints itself as: "[] in UnboundMethod>>doIt"
arg is of type Context and prints itself as: "UndefinedObject(**DIRECTED**) >> doIt [20]"
arg is of type Symbol and prints itself as: "+"
arg is of type Method and prints itself as: "a Method(SmallInteger >> +)"
arg is of type ZeroDivide and prints itself as: "division by zero"
arg is of type MessageNotUnderstood and prints itself as: "SmallInteger does not understand: "fooBar""
</pre>
 
=={{header|VBA}}==
VBA has a built-in function TypeName (VarType returns a number), which can also recognize arrays.
<syntaxhighlight lang="vb">Public Sub main()
Dim c(1) As Currency
Dim d(1) As Double
Dim dt(1) As Date
Dim a(1) As Integer
Dim l(1) As Long
Dim s(1) As Single
Dim e As Variant
Dim o As Object
Set o = New Application
Debug.Print TypeName(o)
Debug.Print TypeName(1 = 1)
Debug.Print TypeName(CByte(1))
Set o = New Collection
Debug.Print TypeName(o)
Debug.Print TypeName(1@)
Debug.Print TypeName(c)
Debug.Print TypeName(CDate(1))
Debug.Print TypeName(dt)
Debug.Print TypeName(CDec(1))
Debug.Print TypeName(1#)
Debug.Print TypeName(d)
Debug.Print TypeName(e)
Debug.Print TypeName(CVErr(1))
Debug.Print TypeName(1)
Debug.Print TypeName(a)
Debug.Print TypeName(1&)
Debug.Print TypeName(l)
Set o = Nothing
Debug.Print TypeName(o)
Debug.Print TypeName([A1])
Debug.Print TypeName(1!)
Debug.Print TypeName(s)
Debug.Print TypeName(CStr(1))
Debug.Print TypeName(Worksheets(1))
End Sub</syntaxhighlight>{{out}}
<pre>Application
Boolean
Byte
Collection
Currency
Currency()
Date
Date()
Decimal
Double
Double()
Empty
Error
Integer
Integer()
Long
Long()
Nothing
Range
Single
Single()
String
Worksheet</pre>
 
=={{header|Visual Basic .NET}}==
{{works with|Visual Basic .NET|9.0+}}
<syntaxhighlight lang="vbnet">Module TypeDetection
 
Sub Main()
printTypeOf(5)
printTypeOf("VB.Net")
printTypeOf(7.2)
printTypeOf(True)
End Sub
 
Private Sub printTypeOf(obj As Object)
Console.WriteLine(obj.GetType.ToString)
End Sub
 
End Module
</syntaxhighlight>
 
{{out}}
<pre>
System.Int32
System.String
System.Double
System.Boolean
</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">fn show_type<T>(a T) {
println('The type of $a is ${typeof(a).name}')
}
 
fn main() {
show_type(-556461841)
show_type('Rosetta')
show_type(7.4)
show_type(`s`)
show_type([0x32,0x22])
}</syntaxhighlight>
 
{{out}}
<pre>
The type of -556461841 is int
The type of Rosetta is string
The type of 7.4 is f64
The type of s is rune
The type of [50, 34] is []int
</pre>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
i = 1
ii=0.23
s = "Hello world"
a = split("Hello World"," ")
b=Array(i,ii,s,a)
Set c=CreateObject("Scripting.dictionary")
Class d
Private a,b
End Class
Set e=New d
 
 
WScript.Echo TypeName(b)
WScript.Echo TypeName(b(0))
WScript.Echo TypeName(b(1))
WScript.Echo TypeName(b(2))
WScript.Echo TypeName(b(3))
WScript.Echo TypeName(b(3)(0))
WScript.Echo TypeName(c)
WScript.Echo TypeName(e)
</syntaxhighlight>
{{out}}
<small>
<pre>
Variant()
Integer
Double
String
Variant()
String
Dictionary
d
</pre>
</small>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var showType = Fn.new { |obj|
Fmt.print("$10n has type $q", obj, obj.type)
}
 
var a = [4, 3.728, [1, 2], { 1: "first" }, true, null, 1..6, "Rosetta"]
a.each { |e| showType.call(e) }</syntaxhighlight>
 
{{out}}
<pre>
4 has type "Num"
3.728 has type "Num"
[1, 2] has type "List"
{1: first} has type "Map"
true has type "Bool"
null has type "Null"
1..6 has type "Range"
Rosetta has type "String"
</pre>
 
=={{header|Z80 Assembly}}==
<syntaxhighlight lang="z80">PrintChar equ &BB5A ;Amstrad CPC BIOS Call
 
org &8000
ld de,TestString
call PrintDispatch
call NewLine
ld de,TestHex
call PrintDispatch
call NewLine
 
ld de,TestBCD
call PrintDispatch
call NewLine
 
 
ReturnToBasic:
ret
;SUBROUTINES:
 
align 8
TypeTable:
word PrintString_Text ;string
word PrintHexByte ;a single hexadecimal 8-bit value
word PrintHexByte ;a single binary-coded-decimal 8 bit value
PrintDispatch:
;input: DE - pointer to "string" of bytes.
ld a,(de) ;read the type header. This is an index into TypeTable
inc de ;point DE to actual data.
ld h,>TypeTable
add a ;double the index, since these are words.
ld L,a ;now HL is offset to the desired routine.
;We need to dereference HL and get the actual subroutine address.
; You'd think the JP (HL) would do that, but it does not!
; Despite the syntax, JP (HL) doesn't actually dereference HL,
; it just copies the value stored in HL directly to the program counter.
; There are a couple ways to do this. Self-modifying code uses fewer registers but is a
; bit slow. We'll still use that as I think it's the easiest to follow.
ld a,(hl)
ld (Go+1),a ;store low byte in the low byte of the jump's operand.
inc hl ;inc to high byte.
ld a,(hl)
ld (Go+2),a ;store high byte in the high byte of the jump's operand
Go:
jp &ABCD ;the &ABCD gets overwritten with the address of the desired function.
 
PrintString_Text:
ld a,(de) ;get next char
or a ;is it the terminator?
ret z ;if so, exit
call PrintChar ;prints accumulator as an ASCII character
inc de ;next entry in string
jp PrintString_Text ;go back to start
PrintHexByte:
ld a,(de)
jp ShowHex ;it returns for us.
ShowHex:
push af
and %11110000
rrca
rrca
rrca
rrca
call PrintHexChar
pop af
and %00001111
PrintHexChar:
or a ;Clear Carry Flag
daa
add a,&F0
adc a,&40 ;this converts hexadecimal and BCD to ASCII - somehow!
jp PrintChar ;it returns for us.
NewLine:
push af
ld a,13
call PrintChar
ld a,10
call PrintChar
pop af
ret
TestString:
byte 0,"Hello World",0
TestHex:
byte 1,&46
TestBCD:
byte 2,&99</syntaxhighlight>
 
{{out}}
<pre>
Hello World
46
99
</pre>
 
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn processText(data_or_fileName){ // unknown
if (data_or_fileName.isType(String)) // == .isType("")
data_or_fileName=File(data_or_fileName,"rb").read(); //-->Data
text:=textdata_or_fileName.text; //-->String
doTheActualTextProcessing(text);
}
}</lang>
fcn doTheActualTextProcessing(text){ println(text) }</syntaxhighlight>
If an int is passed in, (123).text --> "123", other objects might throw an exception.
 
How to use:
<syntaxhighlight lang="zkl">processText("foo.txt");
processText(Data(Void,"This is some text"));
// fake up a class that holds a string:
cs:=class{ var text }; cs.text="this is more text";
processText(cs);</syntaxhighlight>
{{out}}
<pre>
this is foo.txt
 
This is some text
this is more text
</pre>
9,486

edits