Data Type Declarations and Restrictions

Starting in Qore 0.8.0, it is possible to restrict variables, class members, and function and method parameters to certain data types. This allows programmers to write safer code, as many more errors can be caught at parse time that would otherwise be caught at run time. Furthermore, providing type information to the parser allows Qore to implement performance optimizations by performing lookups and resolutions once at parse time rather than every time a variable or class member is accessed at run time.

When types are declared in a parameter list, functions and methods can be overloaded as well.

The types in the following table can be used as well as any class name or `'*classname'` (i.e. an asterix followed by the class name), meaning either the given class or NOTHING (no value).

Data Type Declaration Names

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
int | Integer | Integer | Restricts values Integer values
float | Float or Integer | Float | Restricts values to Float values
number | Number, Float, or Integer | Number | Restricts values to Number values
bool | Boolean | Boolean | Restricts values to Boolean values
string | String | String | Restricts values to String values
date | Date | Date | Restricts values to Date values; values may be either absolute or relative
binary | Binary | Binary | Restricts values to Binary values
hash | Hash | Hash | Restricts values to Hash values without any key type information
hash<...> | Hash | Hash | Restricts values to values of the referenced type-safe hash
hash<string, ...> | Hash | Hash | Restricts key values to the declared type
list | List | List | Restricts values to List values
list<...> | List | List | Restricts list values to the declared type
object | Object | Object | Restricts values to Object values
object<...> | Object | Object | Restricts values to objects of the specific class
<classname> | Object | Object | Restricts values to objects of the specific class given; either the class name can be given (ex: Mutex or a qualified path to the class: Qore::Thread::Mutex)
null | NULL | NULL | Restricts values to Qore's NULL type; this type has few (if any) practical applications and has been included for completeness' sake
nothing | NOTHING | NOTHING | Restricts values to Qore's NOTHING type; this type is mostly useful for declaring that a function or method returns no value
timeout | Integer, Date | Integer | Accepts Integer, Date and converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds
softint | Integer, Float, Number, Boolean, String, NULL | Integer | Accepts Integer, Float, Boolean, String, NULL and converts non-integer values to an integer and returns the integer
softfloat | Integer, Float, Number, Boolean, String, NULL | Float | Accepts Integer, Float, Boolean, String, NULL and converts non-float values to a float and returns the new value
softnumber | Integer, Float, Number, Boolean, String, NULL | Float | Accepts Integer, Float, Boolean, String, NULL and converts non-number values to a float and returns the new value
softbool | Integer, Float, Number, Boolean, String, NULL | Boolean | Accepts Integer, Float, Boolean, String, NULL and converts non-boolean values to a boolean and returns the new value
softstring | Integer, Float, Number, Boolean, String, NULL | String | Accepts Integer, Float, Boolean, String, NULL and converts non-string values to a string and returns the new value
softdate | Integer, Float, Number, Boolean, String, Date, NULL | Date | Accepts Integer, Float, Boolean, String, Date, and NULL and converts non-date values to a date and returns the new value
softlist | all types | List | Accepts all types; NOTHING is returned as an empty list; a list is returned unchanged, and any other type is returned as the first element of a new list
softlist<...> | all types | List | Accepts all data types; NOTHING is returned as an empty list; a list is returned with its elements processed by the subtype declaration, and any other type is returned as the first element of a new list, also processed by the subtype declaration
data | String or Binary | same as received | Restricts input to String and Binary and returns the same type
code | Closures, Call References | same as received | Restricts values to closures and call references
reference | References | the type the reference points to | Restricts values to references to lvalues
reference<...> | References | the type given as an argument | Restricts values to references to lvalues compatible with the given type
*int | Integer, NULL, or NOTHING | Integer or NOTHING | Restricts values to Qore's Integer or NOTHING types; if NULL is passed then NOTHING is returned
*float | Float, NULL, or NOTHING | Float or NOTHING | Restricts values to Qore's Float or NOTHING types; if NULL is passed then NOTHING is returned
*number | Number, NULL, or NOTHING | Number or Number | Restricts values to Qore's Number or NOTHING types; if NULL is passed then NOTHING is returned
*bool | Boolean, NULL, or NOTHING | Boolean or NOTHING | Restricts values to Qore's Boolean or NOTHING types; if NULL is passed then NOTHING is returned
*string | String, NULL, or NOTHING | String or NOTHING | Restricts values to Qore's String or NOTHING types; if NULL is passed then NOTHING is returned
*date | Date, NULL, or NOTHING | Date or NOTHING | Restricts values to Qore's Date or NOTHING type; values may be either absolute or relative date/time values; if NULL is passed then NOTHING is returned
*binary | Binary, NULL, or NOTHING | Binary or NOTHING | Restricts values to Qore's Binary or NOTHING types; if NULL is passed then NOTHING is returned
*hash | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts values to Qore's Hash or NOTHING types; if NULL is passed then NOTHING is returned
*hash<...> | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts values to values of the referenced type-safe hash or NOTHING types; if NULL is passed then NOTHING is returned
*hash<string, ...> | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts key values to the declared complex hash or NOTHING types; if NULL is passed then NOTHING is returned
*list | List, NULL, or NOTHING | List or NOTHING | Accepts either a List or NOTHING; if NULL is passed then NOTHING is returned
*list<...> | List, NULL, or NOTHING | List or NOTHING | Restricts list values to the declared complex list type or NOTHING; if NULL is passed then NOTHING is returned
*object | Object, NULL, or NOTHING | Object or NOTHING | Accepts either an Object or NOTHING; if NULL is passed then NOTHING is returned
*<classname> | Object of the given class, NULL, or NOTHING | Object of the given class or NOTHING | Restricts values to objects of the specific class given or NOTHING; either the class name can be given (ex: *Mutex or a qualified path to the class: *Qore::Thread::Mutex); if NULL is passed then NOTHING is returned
*object<...> | Object of the given class, NULL, or NOTHING | Object of the given class or NOTHING | Restricts values to objects of the specific class given or NOTHING; if NULL is passed then NOTHING is returned
*data | String, Binary, NULL, or NOTHING | String, Binary, or NOTHING | Restricts input to String, Binary, or NOTHING and returns the same type; if NULL is passed then NOTHING is returned
*code | Closures, Call References, NULL, or NOTHING | Closures, Call References, or NOTHING | Restricts values to closures, call references and NOTHING; if NULL is passed then NOTHING is returned
*timeout | Integer, Date, NULL, or NOTHING | Integer or NOTHING | Accepts Integer, Date and converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds. If no value or NULL is passed, then NOTHING is returned
*reference | References, NULL, or NOTHING | the type the reference points to and NOTHING | Restricts values to references to lvalues and NOTHING; if NULL is passed then NOTHING is returned
*reference<...> | References, NULL, or NOTHING | the type given as an argument and NOTHING | Restricts values to references to lvalues compatible with the given type and NOTHING; if NULL is passed then NOTHING is returned
*softint | Integer, Float, Number, Boolean, String, NULL or NOTHING | Integer or NOTHING | Accepts Integer, Float, Number, Boolean, String, NULL and converts non-integer values to an integer and returns the integer. If no value or NULL is passed, then NOTHING is returned
*softfloat | Integer, Float, Number, Boolean, String, NULL or NOTHING | Float or NOTHING | Accepts Integer, Float, Number, Boolean, String, NULL and converts non-float values to a float and returns the new value. If no value or NULL is passed, then NOTHING is returned
*softnumber | Integer, Float, Number, Boolean, String, NULL or NOTHING | Number or NOTHING | Accepts Integer, Float, Number, Boolean, String, NULL and converts non-number values to a number and returns the new value. If no value or NULL is passed, then NOTHING is returned
*softbool | Integer, Float, Number, Boolean, String, NULL or NOTHING | Boolean or NOTHING | Accepts Integer, Float, Number, Boolean, String, NULL and converts non-boolean values to a boolean and returns the new value. If no value or NULL is passed, then NOTHING is returned
*softstring | Integer, Float, Number, Boolean, String, NULL or NOTHING | String or NOTHING | Accepts Integer, Float, Number, Boolean, String, NULL and converts non-string values to a string and returns the new value. If no value or NULL is passed, then NOTHING is returned
*softdate | Integer, Float, Number, Boolean, String, Date, NULL or NOTHING | Date or NOTHING | Accepts Integer, Float, Number, Boolean, String, Date, and NULL and converts non-date values to a date and returns the new value. If no value or NULL is passed, then NOTHING is returned
*softlist | all types | List or NOTHING | Accepts all types; NOTHING and list values are returned as the same value; NULL is returned as NOTHING, any other type is returned as the first element of a new list
*softlist<...> | all types | List or NOTHING | Accepts all data types; NOTHING and NULL are returned as NOTHING; a list is returned with its elements processed by the declared subtype, and any other type is returned as the first element of a new list with its element processed by the declared subtype
any | any | same as received | Provides no restrictions on the type of value it receives and returns the same value, however complex type information is stripped on assignment for backwards compatibility; note that the `any` type restriction is the same as using no type restriction; to assign any type without stripping complex types, use the auto type restriction instead
auto | all data types | all data types | Provides no restrictions on the type of value it receives and returns the same value; does not strip complex types on assignment like any

# int

int Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`int` | Integer | Integer | Restricts values to Qore's Integer type

Example
  int sub foo(int i) {
  return i;
  }

# float

float Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`float` | Float or Integer | Float | Restricts values to Qore's Float type

Example
  float sub foo(float f = M_PI) {
  return f;
  }

# number

number Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`number` | Number, Float, or Integer | Number | Restricts values to Qore's Number type

Example
  number sub foo(number n = 2.35e40) {
  return n;
  }

Since
  Qore 0.8.6 introduced the number type

# bool

bool Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`bool` | Boolean | Boolean | Restricts values to Qore's Boolean type

Example
  bool sub foo(bool b) {
  return b;
  }

# string

string Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`string` | String | String | Restricts values to Qore's String type

Example
  string sub foo(string str = "bar") {
  return str;
  }

# date

date Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`date` | Date | Date | Restricts values to Qore's Date type; date/time values can be either absolute or relative

Example
  date sub foo(date d = now_us()) {
  return d;
  }

# binary

binary Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`binary` | Binary | Binary | Restricts values to Qore's Binary type

Example
  binary sub foo(binary b) {
  return b;
  }

# hash

hash Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`hash` | Hash (all) | Hash (untyped) | Restricts values to Qore's Hash type; if a typed hash is received, type information is removed for the lvalue assignment

Example
  hash sub foo(hash h = ("foo": "bar", "x": 2)) {
  return h;
  }

## Type-Safe Hash Type

hashdecl Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`hash` | hash<hashdecl> | hash<hashdecl>> | Restricts values to hashes created from the given hashdecl

The hash type takes a single type-safe hash name (or namespace- prefixed path) in angle brackets after `"hash"` which results in a type declaration restricted to the declared type-safe hash as in the following example.

Examples
  # hashdecl typed hash declaration
  hashdecl MyHash {
  string foo = "empty";
  int x = 1;
  }
  # declaration and initialization to default key values
  hash<MyHash> h1();
  # declaration and initialization with explicit values
  hash<MyHash> h2(("foo": "string", "x": 10));
  # declaration and initialization with the new operator
  hash<MyHash> h3 = new hash<MyHash>(("foo": "string", "x": 10));
  # example of a function with a typed hash return type and parameter type
  hash<MyHash> sub foo(hash<MyHash> h = new hash<MyHash>("foo": "bar", "x": 2)) {
  return h;
  }
  # example of a function with a typed hash return type and a cast to a typed hash return type
  hash<MyHash> sub foo(int x) {
  return cast<hash<MyHash>>(get_hash(x));
  }

This type is supported at parse-time and at runtime; to convert such values to an untyped hash, assign it to a hash lvalue, use cast<hash>(...) on the value, call the hash() function on the value, or assign it to an untyped lvalue. Each of these options can be used to convert a type-safe hash to an untyped hash.

Complex type information is lost when assigning to an lvalue with a compatible but more generic type or by assigning to an untyped lvalue; this was necessary to allow complex types to be introduced in Qore without breaking backwards compatibility.

However, a special single argument, `"auto"`, allows for the lvalue to maintain the complex hash type as in the following example:

hash h0 = ("a": 2, "b": 3);
# prints "hash"
printf("%y\n", h0.fullType());
hash<auto> h1 = new hash<MyHash>();
# prints "hash<MyHash>"
printf("%y\n", h1.fullType());

See also
  - Hashdecl: Type-Safe Hash Declarations
  - New Value Operator (new)
  - Cast Operator (cast<>())

## Hash With Declared Value Type

Complex hash Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`hash` | hash<string, type> | hash<string, type> | Restricts values to hashes with the given declared key type; use cast<>(...) to convert values to this type at runtime.

The hash type also supports two arguments in angle brackets to specify the key and value types, however the key type currently must always be string. This results in a hash where the keys and values must always be of the declared type. See the following example for more information.

Examples
  # 1: declaration and initialization (identical to 2 and 3)
  hash<string, int> h1((
  "code": 500,
  "type": 300,
  "value": 0,
  ));
  # 2: declaration and initialization with the assignment operator (identical to 1 and 3)
  hash<string, int> h2 = (
  "code": 500,
  "type": 300,
  "value": 0,
  );
  # 3: declaration and initialization with the new operator (identical to 1 and 2)
  hash<string, int> h3 = new hash<string, int>((
  "code": 500,
  "type": 300,
  "value": 0,
  ));
  # assignment from an untyped hash with the cast<> operator (can result in runtime type errors)
  hash<string, int> h4 = cast<hash<string, int>>(get_hash());

This type is supported at parse-time and at runtime; to convert such values to an untyped hash, assign it to a hash lvalue, use cast<hash>(...) on the value, call the hash() function on the value, or assign it to an untyped lvalue. Each of these options can be used to convert a type-safe hash to an untyped hash.

Complex type information is lost when assigning to an lvalue with a compatible but more generic type or by assigning to an untyped lvalue; this was necessary to allow complex types to be introduced in Qore without breaking backwards compatibility.

However, a special single argument, `"auto"`, allows for the lvalue to maintain the complex hash type as in the following example:

hash h0 = ("a": 2, "b": 3);
# prints "hash"
printf("%y\n", h0.fullType());
hash<auto> h1 = ("a": 2, "b": 3);
# prints "hash<string, int>"
printf("%y\n", h1.fullType());

See also
  - Hashdecl: Type-Safe Hash Declarations
  - New Value Operator (new)
  - Cast Operator (cast<>())

# list

list Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`list` | List | List | Restricts values to Qore's List type

Example
  list sub foo(list l = ("foo", "bar")) {
  return l;
  }

## List With Declared Value Type

Complex list Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`list` | list<type> | list<type> | Restricts values to lists with the given declared value type; use cast<>(...) to convert values to this type at runtime.

The list type supports one type argument in angle brackets to specify the value type. This results in a list where the values must always be of the declared type. See the following example for more information.

Examples
  # 1: declaration and initialization (identical to 2 and 3)
  list<int> l1(500, 300, 0);
  # 2: declaration and initialization with the assignment operator (identical to 1 and 3)
  list<int> l2 = (500, 300, 0);
  # 3: declaration and initialization with the new operator (identical to 1 and 2)
  list<int> l3 = new list<int>(500, 300, 0);
  # assignment from an untyped list with the cast<> operator (can result in runtime type errors)
  list<int> l4 = cast<list<int>>(get_list());

This type is supported at parse-time and at runtime; to convert such values to an untyped list, assign it to a list lvalue, use cast<list>(...) on the value, call the list() function on the value, or assign it to an untyped lvalue. Each of these options can be used to convert a type-safe list to an untyped list.

Complex type information is lost when assigning to an lvalue with a compatible but more generic type or by assigning to an untyped lvalue; this was necessary to allow complex types to be introduced in Qore without breaking backwards compatibility.

However, a special single argument, `"auto"`, allows for the lvalue to maintain the complex list type as in the following example:

list l0 = (2, 3);
# prints "list"
printf("%y\n", l0.fullType());
list<auto> l1 = (2, 3);
# prints "list<int>"
printf("%y\n", l1.fullType());

See also
  - New Value Operator (new)
  - Cast Operator (cast<>())

# object

object Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`object` | Object | Object | Restricts values to Qore's Object type; note that any class name can also be used as a type restriction directly

Example
  object sub foo(object o = new Mutex()) {
  return o;
  }

## Class-Specific Type Declaration

Complex object Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`object` | object<class> | object<class> | Restricts values to objects of the given class

The object type declaration takes a single class name (or namespace- prefixed path) in angle brackets after `"object"` which results in a type declaration restricted to the declared class as in the following example.

Example
  object<MyClass> sub foo(MyClass o = new MyClass()) {
  return o;
  }

Note
  this type declaration is equivalent to using the class name by itself

# <classname>

<classname> Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
any class name | Object of the particular class given | Object of the particular class given | Restricts values to objects of the particular class given; subclasses are also accepted

Example
  Mutex sub foo(Qore::Thread::Mutex m = new Mutex()) {
  return m;
  }

# null

null Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`null` | NULL | NULL | Restricts values to Qore's NULL type; this type has few (if any) practical applications and has been included for completeness' sake

Example
  # I don't know if this type has any useful/practical applications...
  null n = NULL;

# nothing

nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`nothing` | NOTHING | NOTHING | Restricts values to Qore's NOTHING type; this type is mostly useful for declaring that a function or method returns no value

Example
  nothing sub bar() {
  printf("foo\n");
  }

# timeout

timeout Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`timeout` | Integer, Date | Integer | Accepts Integer, Date values and converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds

Example
  timeout sub foo(timeout to = 1250ms) {
  return to;
  }

# softint

softint Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softint` | Integer, Float, Number, Boolean, String, NULL | Integer | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-integer values to an integer and returns the integer

Example
  softint sub foo(softint i = "1000") {
  # note that "200" will be converted to an integer on return
  return i > 500 ? "200" : i;
  }

# softfloat

softfloat Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softfloat` | Integer, Float, Number, Boolean, String, NULL | Float | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-float values to a float and returns the float

Example
  softfloat sub foo(softfloat f = "1000") {
  # note that "200" will be converted to a float on return
  return f > 500.0 ? "200" : f;
  }

# softnumber

softnumber Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softnumber` | Integer, Float, Number, Boolean, String, NULL | Float | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-number values to a number and returns the number

Example
  softnumber sub foo(softnumber n = "1000") {
  # note that "200" will be converted to a number on return
  return n > 500.0n ? "200" : n;
  }

Since
  Qore 0.8.6 introduced the softnumber type

# softbool

softbool Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softbool` | Integer, Float, Number, Boolean, String, NULL | Boolean | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-boolean values to a boolean and returns the boolean

Example
  softbool b = "0.5";

# softstring

softstring Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softstring` | Integer, Float, Number, Boolean, String, NULL | String | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-string values to a string and returns the string

Example
  softstring str = 200;

# softdate

softdate Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softdate` | Integer, Float, Number, Boolean, String, Date, NULL | Date | Accepts Integer, Float, Number, Boolean, String, Date, and NULL values and converts non-date values to a date and returns the date

Example
  softdate d = "2001-10-10T20:00:05 +04:00";

# softlist

softlist Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softlist` | all data types | List | Accepts all data types; NOTHING is returned as an empty list; a list is returned unchanged, and any other type is returned as the first element of a new list

Example
  softlist sub foo(softlist l) {
  foreach any element in (\l) {
  }
  return l;
  }

## Softlist With Declared Value Type

Complex list Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`softlist` | all data types | List | Accepts all data types; NOTHING is returned as an empty list; a list is returned with its elements processed by the subtype declaration, and any other type is returned as the first element of a new list, also processed by the subtype declaration

The softlist type supports one type argument in angle brackets to specify the value type. This results in a list where the values must always be of the declared type. See the following example for more information.

Examples
  # 1: declaration and initialization (identical to 2 and 3)
  softlist<int> l1(500, 300, 0);
  # 2: declaration and initialization with the assignment operator (identical to 1 and 3)
  softlist<int> l2 = (500, 300, 0);
  # 3: declaration and initialization with the new operator (identical to 1 and 2)
  softlist<int> l3 = new list<int>(500, 300, 0);
  # assignment from an untyped list with the cast<> operator (can result in runtime type errors)
  softlist<int> l4 = cast<list<int>>(get_list());

This type is supported at parse-time and at runtime; to convert such values to an untyped list, assign it to a list lvalue, use cast<list>(...) on the value, call the list() function on the value, or assign it to an untyped lvalue. Each of these options can be used to convert a type-safe list to an untyped list.

Complex type information is lost when assigning to an lvalue with a compatible but more generic type or by assigning to an untyped lvalue; this was necessary to allow complex types to be introduced in Qore without breaking backwards compatibility.

However, a special single argument, `"auto"`, allows for the lvalue to maintain the complex list type as in the following example:

softlist l0 = 1;
# prints "list"
printf("%y\n", l0.fullType());
softlist<auto> l1 = (1, );
# prints "list<int>"
printf("%y\n", l1.fullType());

See also
  - New Value Operator (new)
  - Cast Operator (cast<>())

Since
  Qore 0.8.3 introduced the softlist type

# data

data Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`data` | String or Binary | same as received | Restricts values to String and Binary

Example
  data sub foo(data d) {
  return d;
  }

# code

code Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`code` | Closures, Call References | same as received | Restricts values to Closures and Call References

Example
  sub foo(code c) {
  c();
  }

Note
  that also `"closure"` and `"callref"` are accepted as synonyms for `"code"` (they are not more specific than `"code"` but rather provide identical type restrictions)

# reference

reference Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`reference` | References | the type the reference points to | Requires a reference to an lvalue to be assigned

Example
  sub foo(reference f) {
  f = 10;
  }
  int i;
  foo(\i);

## Reference With Declared LValue Type

Complex reference Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`reference` | reference<type> | type as given as the arg | Restricts values to references to lvalues with a type compatible to that given as the type argument

The reference type supports one type argument in angle brackets to specify a compatible lvalue type. See the following example for more information.

Example
  int i = 0;
  reference<int> r = \i;

# *int

*int Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*int` | Integer, NULL, or NOTHING | Integer or NOTHING | Restricts values to Integer and NOTHING; if NULL is passed then NOTHING is returned

Example
  *int sub foo(*int i) {
  return i;
  }

# *float

*float Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*float` | Float, NULL, or NOTHING | Float or NOTHING | Restricts values to Float and NOTHING; if NULL is passed then NOTHING is returned

Example
  *float sub foo(*float f) {
  return f;
  }

# *number

*number Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*number` | Number, NULL, or NOTHING | Number or NOTHING | Restricts values to Number and NOTHING; if NULL is passed then NOTHING is returned

Example
  *number sub foo(*number n) {
  return n;
  }

Since
  Qore 0.8.6 introduced the *number type

# *bool

*bool Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*bool` | Boolean, NULL, or NOTHING | Boolean or NOTHING | Restricts values to Boolean and NOTHING; if NULL is passed then NOTHING is returned

Example
  *bool sub foo(*bool b) {
  return b;
  }

# *string

*string Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*string` | String, NULL, or NOTHING | String or NOTHING | Restricts values to String and NOTHING; if NULL is passed then NOTHING is returned

Example
  *string sub foo(*string str) {
  return str;
  }

# *date

*date Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*date` | Date, NULL, or NOTHING | Date or NOTHING | Restricts values to Date and NOTHING; if NULL is passed then NOTHING is returned

Example
  *date sub foo(*date str) {
  return str;
  }

# *binary

*binary Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*binary` | Binary, NULL, or NOTHING | Binary or NOTHING | Restricts values to Binary and NOTHING; if NULL is passed then NOTHING is returned

Example
  *binary sub foo(*binary b) {
  return b;
  }

# *hash

*hash Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*hash` | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts values to Hash and NOTHING; if NULL is passed then NOTHING is returned

Example
  *hash sub foo(*hash h) {
  return h;
  }

## *hash<...>

Complex Hashdecl or Nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*hash<...>` | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts values to values of the referenced type-safe hash or NOTHING types; if NULL is passed then NOTHING is returned

Example
  *hash<MyHash> sub foo(*hash<MyHash> h) {
  return h;
  }

## *hash<string, ...>

Complex Hash or Nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*hash<string, ...>` | Hash, NULL, or NOTHING | Hash or NOTHING | Restricts key values to the declared complex hash or NOTHING types; if NULL is passed then NOTHING is returned

Example
  *hash<string, int> sub foo(*hash<string, int> h) {
  return h;
  }

# *list

*list Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*list` | List or NOTHING | List or NOTHING | Restricts values to List and NOTHING; if NULL is passed then NOTHING is returned

Example
  *list sub foo(*list l) {
  return l;
  }

## *list<...>

Complex List or Nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*list<...>` | List, NULL, or NOTHING | List or NOTHING | Restricts list values to the declared complex list type or NOTHING; if NULL is passed then NOTHING is returned

Example
  *list<int> sub foo(*list<int> l) {
  return l;
  }

# *object

*list Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*list` | Object, NULL, or NOTHING | Object or NOTHING | Restricts values to Object and NOTHING; if NULL is passed then NOTHING is returned

Example
  *object sub foo(*object obj) {
  return obj;
  }

# *<classname>

*<classname> Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*`any class name | Object of the particular class given, NULL, or NOTHING | Object of the particular class given or NOTHING | Restricts values to objects of the particular class given or NOTHING; subclasses are also accepted; if NULL is passed then NOTHING is returned

Example
  sub foo(*Mutex m) {
  }

# *date

*data Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*data` | String, Binary, NULL, or NOTHING | String, Binary, or NOTHING | Restricts values to String, Binary, and NOTHING; if NULL is passed then NOTHING is returned

Example
  sub foo(*data d) {
  }

# *code

*code Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*code` | Closures, Call References, NULL, or NOTHING | Closures, Call References, or NOTHING | Restricts values to Closures, Call References, and NOTHING; if NULL is passed then NOTHING is returned

Example
  sub foo(*code c) {
  }

# *timeout

*timeout Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*timeout` | Integer, Date, NULL, or NOTHING | Integer or NOTHING | converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds; also accepts NOTHING and returns NOTHING; if NULL is passed then NOTHING is returned

Example
  sub foo(*timeout c) {
  }

# *reference

*reference Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`reference` | References, NULL, or NOTHING | the type the reference points to | Requires a reference to an lvalue to be assigned or NOTHING; if NULL is passed then NOTHING is returned

Example
  sub foo(*reference f) {
  f = 10;
  }
  int i;
  foo(\i);

## *reference<...>

complex Reference or Nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*reference<...>` | References, NULL, or NOTHING | the type given as an argument and NOTHING | Restricts values to references to lvalues compatible with the given type and NOTHING; if NULL is passed then NOTHING is returned

Example
  sub foo(*reference<int> f) {
  f = 10;
  }
  int i;
  foo(\i);

# *softint

*softint Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softint` | Integer, Float, Number, Boolean, String, NULL, NOTHING | Integer or NOTHING | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-integer values to an integer and returns the integer; also accepts NOTHING and NULL and returns NOTHING

Example
  sub foo(*softint i) {
  }

# *softfloat

*softfloat Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softfloat` | Integer, Float, Number, Boolean, String, NULL, NOTHING | Float or NOTHING | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-float values to a float and returns the float; also accepts NOTHING and NULL and returns NOTHING

Example
  sub foo(*softfloat f) {
  }

# *softnumber

*softnumber Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softnumber` | Integer, Float, Number, Boolean, String, NULL, NOTHING | Number or NOTHING | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-number values to a number and returns the number; also accepts NOTHING and NULL and returns NOTHING

Example
  sub foo(*softnumber n) {
  }

Since
  Qore 0.8.6 introduced the *softnumber type

# *softbool

*softbool Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softbool` | Integer, Float, Number, Boolean, String, NULL, NOTHING | Boolean or NOTHING | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-boolean values to a boolean and returns the boolean; also accepts NOTHING and NULL and returns NOTHING

Example
  sub foo(*softbool b) {
  }

# *softstring

*softstring Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softstring` | Integer, Float, Number, Boolean, String, NULL, NOTHING | String or NOTHING | Accepts Integer, Float, Number, Boolean, String, and NULL values and converts non-string values to a string and returns the string; also accepts NOTHING and returns NOTHING

Example
  sub foo(*softstring str) {
  }

# *softdate

*softdate Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softdate` | Integer, Float, Number, Boolean, String, Date, NULL, NOTHING | String or NOTHING | Accepts Integer, Float, Number, Boolean, String, Date, and NULL values and converts non-date values to a date and returns the date; also accepts NOTHING and NULL and returns NOTHING

Example
  sub foo(*softdate d) {
  }

# *softlist

*softlist Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softlist` | all data types | List or NOTHING | Accepts all data types; NOTHING and NULL are returned as NOTHING; a list is returned unchanged, and any other type is returned as the first element of a new list

Example
  *softlist d = v;

## *softlist<...>

Complex Softlist or Nothing Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`*softlist` | all data types | List or NOTHING | Accepts all data types; NOTHING and NULL are returned as NOTHING; a list is returned with its elements processed by the declared subtype, and any other type is returned as the first element of a new list with its element processed by the declared subtype

Example
  *softlist<softint> sub foo() {
  # returns a list with 2 as the first element
  return "2";
  }

Since
  Qore 0.8.3 introduced the *softlist type

# any

any Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`any` | all data types | all data types | Provides no restrictions on the type of value it receives and returns the same value, however complex type information is stripped on assignment for backwards compatibility

Example
  any v = bar;
  any l = (1, 2);
  # prints "list" as the complex type info is stripped on assignment for backwards compatibility
  printf("%s\n", l.fullType());

Note
  - The `any` type restriction is the same as using no type restriction
  - To assign any type without stripping complex types, use the auto type restriction instead
  - In general auto is recommended over `any`

# auto

auto Type Restriction

Name | Accepts Qore Type(s) | Returns Qore Type(s) | Description
`auto` | all data types | all data types | Provides no restrictions on the type of value it receives and returns the same value; does not strip complex types on assignment like any

Example
  auto v = bar;
  auto l = (1, 2);
  # prints "list<int>"
  printf("%s\n", l.fullType());

- In general `auto` is recommended over any