Type detection: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Phix}}: added syntax colouring the hard way, phix/basics)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(39 intermediate revisions by 14 users not shown)
Line 18:
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">
<lang AWK>
# syntax: TAWK -f TYPE_DETECTION.AWK
# uses Thompson Automation's TAWK 5.0c
Line 35 ⟶ 219:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 50 ⟶ 234:
=={{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">
<lang C>
#include<stdio.h>
#include<ctype.h>
Line 83 ⟶ 267:
return 0;
}
</syntaxhighlight>
</lang>
Output, shown for multiple inputs, as well as single ones:
<pre>
Line 129 ⟶ 313:
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#}}==
<langsyntaxhighlight lang="csharp">using System;
 
namespace TypeDetection {
Line 157 ⟶ 456:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>The type of '5' is System.Int32
Line 171 ⟶ 470:
=={{header|C++}}==
{{trans|D}}
<langsyntaxhighlight lang="cpp">#include <iostream>
 
template <typename T>
Line 191 ⟶ 490:
std::cout << typeString(S{}) << '\n';
std::cout << typeString(nullptr) << '\n';
}</langsyntaxhighlight>
{{out}}
<pre>int
Line 204 ⟶ 503:
 
=={{header|Crystal}}==
<langsyntaxhighlight Rubylang="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)
Line 220 ⟶ 519:
print_type({a: 1, b: 2})
print_type ->(x : Int32){ x+2 > 0 }
</syntaxhighlight>
</lang>
{{out}}
<pre>Compile-time type of 123 is Int32
Line 237 ⟶ 536:
 
=={{header|D}}==
<langsyntaxhighlight Dlang="d">import std.stdio;
 
auto typeString(T)(T _) {
Line 256 ⟶ 555:
writeln(typeString(S()));
writeln(typeString(null));
}</langsyntaxhighlight>
 
{{out}}
Line 269 ⟶ 568:
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
Line 286 ⟶ 598:
{ 1 2 3 4 5 } myprint
123 myprint
3.1415 myprint</langsyntaxhighlight>
{{out}}
<pre>
Line 294 ⟶ 606:
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.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 317 ⟶ 946:
showType(value)
}
}</langsyntaxhighlight>
 
{{out}}
Line 328 ⟶ 957:
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}}==
Line 333 ⟶ 1,028:
Presumably this satisfies the task requirements...
 
<langsyntaxhighlight Jlang="j"> echo 'one'
one
echo 1
1</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight Javalang="java">public class TypeDetection {
private static void showType(Object a) {
if (a instanceof Integer) {
Line 359 ⟶ 1,054:
showType(true);
}
}</langsyntaxhighlight>
{{out}}
<pre>'5' is an integer
Line 373 ⟶ 1,068:
console.log(typeof('foo')); // Returns string
console.log(typeof(12345)); // Returns number
</pre>
 
=={{header|jq}}==
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:
 
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>
 
Line 379 ⟶ 1,100:
<code>typeof</code> function, and the function <code>isa</code> tests
whether an object is of that type.
<syntaxhighlight lang="julia">
<lang Julia>
 
julia> a = 1
Line 426 ⟶ 1,147:
true
 
</syntaxhighlight>
</lang>
 
=={{header|OASYS Assembler}}==
 
<langsyntaxhighlight 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 441 ⟶ 1,162:
/>1RF ; It is clear
:>0RF ; It is not clear
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
fun showType(a: Any) = when (a) {
is Int -> println("'$a' is an integer")
Line 457 ⟶ 1,178:
showType('d')
showType(true)
}</langsyntaxhighlight>
 
{{out}}
Line 468 ⟶ 1,189:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function writeValue(v)
local t = type(v)
if t == "number" then
Line 508 ⟶ 1,229:
end
 
main()</langsyntaxhighlight>
{{out}}
<pre>The value 42 is of type number
Line 515 ⟶ 1,236:
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.
<langsyntaxhighlight lang="perl">$scalar = 1;
@array = (1, 2);
%hash = ('a' => 1);
Line 533 ⟶ 1,419:
printf $fmt, '$regex', ref( $regex);
printf $fmt, '$reference', ref(\$reference);
printf $fmt, '$subref', ref( $subref);</langsyntaxhighlight>
{{out}}
<pre>$scalar is type: SCALAR
Line 545 ⟶ 1,431:
{{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.
<!--<langsyntaxhighlight Phixlang="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>
Line 556 ⟶ 1,442:
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 599 ⟶ 1,485:
=={{header|PowerShell}}==
In PowerShell everything is an object and all objects have the GetType() method:
<syntaxhighlight lang="powershell">
<lang PowerShell>
[string]$str = "123"
$str.GetType()
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 609 ⟶ 1,495:
True True String System.Object
</pre>
<syntaxhighlight lang="powershell">
<lang PowerShell>
[int]$int = $str -as [int]
$int.GetType()
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 638 ⟶ 1,524:
>>> type({}) is dict
True</pre>
 
=== Specific tester functions ===
 
* [https://docs.python.org/3/library/functions.html#isinstance isinstance()]
 
=={{header|Racket}}==
Line 644 ⟶ 1,534:
http://docs.racket-lang.org/ts-reference/type-ref.html
 
<langsyntaxhighlight lang="racket">#lang racket
 
(require racket/undefined)
Line 777 ⟶ 1,667:
(td ,(string-join (->type-names v) ", "))))
test-values)))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 869 ⟶ 1,759:
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 indepthin-depth coverage see: [http https://designdocs.raku.org/S02type.html#Built-In_Data_Types| Raku Design Documents Synopsis S02: Bits and Pieces: Built-In Data Types]
 
<syntaxhighlight lang="raku" perl6line>sub type ($t) { say $t.raku, "\tis type: ", $t.WHAT }
 
# some content types
Line 887 ⟶ 1,777:
my my-type $object;
 
$object.&type;</langsyntaxhighlight>
 
{{out}}
Line 919 ⟶ 1,809:
<br>strings can be classified by having certain characteristics, &nbsp; or in other words, ''types''.
<br>Characteristics of these &nbsp; ''types'' &nbsp; can overlap.
<langsyntaxhighlight 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 /*╔═══════════════════════════════════╗*/
Line 962 ⟶ 1,852:
if datatype(x, 'S') then say @ "a REXX symbol."
say copies('▒', 50) /*a fence that is used as a separator. */
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the internal default data:}}
<pre>
Line 1,055 ⟶ 1,945:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Type detection
 
Line 1,061 ⟶ 1,951:
see "7.5 -> " + type(7.5) + nl
see "d -> " + type('d') + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,078 ⟶ 1,968:
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.
 
<langsyntaxhighlight lang="rust">enum ExpectedTypes {
Int(i64),
UInt(u64),
Line 1,102 ⟶ 1,992:
}
}
}</langsyntaxhighlight>
 
Output:
Line 1,119 ⟶ 2,009:
As Rust allows you to implement your own traits on other people's types, this can be used to implement type detection.
 
<langsyntaxhighlight lang="rust">use std::error::Error;
use std::fs::File;
use std::io::{self,prelude::*};
Line 1,176 ⟶ 2,066:
 
Ok(())
}</langsyntaxhighlight>
 
Output:
Line 1,192 ⟶ 2,082:
Finally, while it's more limited than it appears, Rust does have some small degree of support for type introspection.
 
<langsyntaxhighlight lang="rust">use std::any::Any;
 
pub fn is_string(thing: &dyn Any) {
Line 1,205 ⟶ 2,095:
is_string(&"Hello, World!");
is_string(&5u16);
}</langsyntaxhighlight>
 
Output:
Line 1,212 ⟶ 2,102:
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">object TypeDetection extends App {
def showType(a: Any) = a match {
case a: Int => println(s"'$a' is an integer")
Line 1,227 ⟶ 2,117:
println(s"\nSuccessfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
 
}</langsyntaxhighlight>
 
=={{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...
<langsyntaxhighlight lang="smalltalk">typeOf := [:anyObject |
e'arg is of type {anyObject class name} and prints itself as: "{anyObject printString}"' printCR
].
Line 1,254 ⟶ 2,199:
typeOf value: (SmallInteger >> #+).
[ 1 / 0 ] on:Error do:[:ex | typeOf value: ex ]. "catch the exception"
[ 1 fooBar ] on:Error do:[:ex | typeOf value: ex ].</langsyntaxhighlight>
{{out}}
<pre>arg is of type SmallInteger and prints itself as: "1234"
Line 1,281 ⟶ 2,226:
=={{header|VBA}}==
VBA has a built-in function TypeName (VarType returns a number), which can also recognize arrays.
<langsyntaxhighlight lang="vb">Public Sub main()
Dim c(1) As Currency
Dim d(1) As Double
Line 1,316 ⟶ 2,261:
Debug.Print TypeName(CStr(1))
Debug.Print TypeName(Worksheets(1))
End Sub</langsyntaxhighlight>{{out}}
<pre>Application
Boolean
Line 1,343 ⟶ 2,288:
=={{header|Visual Basic .NET}}==
{{works with|Visual Basic .NET|9.0+}}
<langsyntaxhighlight lang="vbnet">Module TypeDetection
 
Sub Main()
Line 1,357 ⟶ 2,302:
 
End Module
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,366 ⟶ 2,311:
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}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var showType = Fn.new { |obj|
SystemFmt.print("%(Fmt.s(10, obj))$10n has type %(Fmt.$q(", obj, obj.type))")
}
 
var a = [4, 3.728, [1, 2], { 1: "first" }, true, null, 1..6, "Rosetta"]
a.each { |e| showType.call(e) }</langsyntaxhighlight>
 
{{out}}
Line 1,385 ⟶ 2,389:
{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
Line 1,395 ⟶ 2,513:
doTheActualTextProcessing(text);
}
fcn doTheActualTextProcessing(text){ println(text) }</langsyntaxhighlight>
If an int is passed in, (123).text --> "123", other objects might throw an exception.
 
How to use:
<langsyntaxhighlight 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);</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits