TypeDeclaration

TypeDeclaration["Product",name,field1type1,field2type2,|>]

represents a declaration of a product type with the specified fields.

TypeDeclaration["Abstract",name]

represents a declaration of the abstract type name.

TypeDeclaration["Alias",name,targetType]

represents a declaration of the type name using the internal representation of targetType.

TypeDeclaration["Macro",name,targetType]

represents a declaration specifying that all instances of name should be replaced with targetType.

Details and Options

  • TypeDeclaration is a symbolic representation of a declaration and does not evaluate on its own.
  • TypeDeclaration can be used inside of CompilerEnvironmentAppendTo and the first argument of functions like FunctionCompile.
  • The following kinds of declarations are supported:
  • "Product"a type containing several fields; analogous to a struct in C
    "Abstract"an abstract type that concrete types can be instances of; a type class
    "Alias"a type that uses the same internal implementation as another type
    "Macro"a replacement rule that is applied to all types
  • When interfacing with C-compatible programs, the following type declarations are equivalent:
  • TypeDeclaration["Product",
    "myStruct",
    <|"f1"->"CInt","f2"->"CDouble"|>,
    "ReferenceSemantics"->False]
    struct myStruct {int f1; double f2;};
    TypeDeclaration["Macro","myInteger","CInt"]typedef int myInteger;
  • The fields of a product type instance prod can be accessed and set with prod["field"].
  • The following options are supported:
  • "AbstractTypes"{}abstract types containing the declared type
    "Creator"Nonea function to call to create an instance of the declared type
    "MemoryManaged"Automaticwhether to automatically free unreferenced instances
    "Operations"{}operations that are available for the declared type
    "ReferenceSemantics"Automaticwhether to internally represent the type with a pointer
  • By default, "Product" declarations have "MemoryManaged"True and "ReferenceSemantics"True.
  • "ReferenceSemantics" can only be set to True for "Product" declarations.
  • "MemoryManaged" can only be set to True for "Product" declarations with reference semantics.
  • "Creator" can only be set for "Product" declarations .
  • "Operations" can only be set for "Product" and "Abstract" declarations .
  • "AbstractTypes" cannot be set for "Macro" declarations.
  • For compatibility with C structs, product types must generally set "MemoryManaged" and "ReferenceSemantics" generally must be set to False.
  • The following methods are defined for objects prod that are instances of product types:
  • prod["field"]get the value of "field"
    prod["field"]=valset the value of "field"
    DeleteObject[prod]free prod (only available if prod is not memory managed)

Examples

open allclose all

Basic Examples  (2)

Represent a declaration of "fooInteger" as a macro type for "MachineInteger":

Compile a function using the declaration:

Globally declare "fooInteger" as a macro for "MachineInteger":

Compile a function using "fooInteger":

Reset the compiler environment to clear the declaration:

Scope  (5)

"Product"  (1)

A declaration of a product type:

Compile a function that instantiates a product type and then extracts a field:

"Abstract"  (1)

A declaration of an abstract type:

A declaration of a product type that is an instance of the abstract type:

A declaration of a product type that is not an instance of the abstract type:

A declaration of a function that accepts any instance of the abstract type:

Compile a program using the function on a type that is an instance of the abstract type:

The function does not accept inputs from types that are not instances of the abstract type:

"Alias"  (1)

An alias for the "String" type:

A function for the alias that differs from its implementation on the original type:

Compile a program that instantiates the alias through bitcasting and then evaluates the function on it:

"Macro"  (2)

A macro for the "String" type:

A function that refers to "String" using the macro:

Macros are not types, but replacement rules that are applied to types when they are resolved. Therefore, it is impossible to have different definitions of the same function for a macro and the type to which it refers:

Unlike macros, aliases are types, so functions can recognize whether they are applied to a type or an alias of that type.

Options  (11)

"AbstractTypes"  (2)

Represent an abstract type:

Represent an object that is a member of the abstract type:

Represent a function that accepts any instance of the abstract type:

Compile the function, showing that it accepts the product type that is a member of the abstract type:

Represent an abstract type:

Represent another abstract type that is a member of the first:

Represent a product type that is an instance of the second abstract type:

Represent a function that accepts any instance of the abstract type "superType":

Compile the function, showing that it accepts the product type that inherited membership in "superType" through "subType":

"Creator"  (1)

Represent a type with its own creation function:

Represent the implementation of the creation function:

Compile a function that uses CreateTypeInstance and calls the "Creator" function:

The result is 10 as expected:

"MemoryManaged"  (3)

Represent a type without automatic memory management:

Compile a function that uses the type:

The resulting function leaks memory because the object is not automatically freed:

By default, product types are automatically memory managed:

The function that uses the memory-managed type does not leak memory:

Represent a type without automatic memory management:

Compile a function that uses the type and frees it with DeleteObject:

The resulting function does not leak memory because it was manually freed:

Memory-managed product types include a reference count and are not compatible with external programs. When passing a product type to and from a library function, memory management should be disabled.

Compile a library defining a struct foo:

Represent a compatible type with TypeDeclaration:

Note that the compiled type "foo" is a reference type by default, and is equivalent to foo* in C.

Compile a function that calls the library using the type:

"Operations"  (3)

A declaration of a product type with one operation:

A declaration of the operation:

Compile a function to create an instance of the type and another to call the "Increment" operation:

Create the instance:

Call the "Increment" operation; the old value of 0 is returned:

Call the "Increment" operation again; now the old value is 1:

Operations can also be defined for an abstract type. In this case, they are available for any type that implements the abstract type.

Represent an abstract type:

Represent an object that implements the abstract type:

A declaration of the operation:

Compile a function to create an instance of the type and another to call the "Increment" operation:

Create the instance:

Call the "Increment" operation; the old value of 0 is returned:

Call the "Increment" operation again; now the old value is 1:

Operations defined for an abstract type can refer to an actual implementation:

Represent an abstract type:

A declaration of the operation; it is written polymorphically with ForAllType:

Represent an object that is a member of the abstract type:

Compile a function to create an instance of the type and another to call the "Increment" operation:

Create the instance:

Call the "Increment" operation; the old value of 0 is returned:

Call the "Increment" operation again; now the old value is 1:

The implementation of the operation is entirely set up by the abstract type.

A different implementation of an operation can be given. Since it is declared in a narrower way, using the actual type, it overrides that given from the abstract type:

Compile a function to create an instance of the type and another to call the "Increment" operation:

Create the instance:

Now the "Increment" operation is different:

"ReferenceSemantics"  (2)

Represent a type that will be passed by value instead of by reference:

Compile a function using the value type:

Compile a library defining a struct foo:

Represent a compatible type with TypeDeclaration:

Compile a function using the type:

Applications  (1)

The C standard library includes a function called ldiv that computes the quotient and remainder of two integers. It returns an object declared as:

typedef struct {
    long quot; /* quotient */
    long rem; /* remainder */
} ldiv_t;

Represent the declaration of the ldiv_t type:

Represent the declaration of the ldiv function:

Compile a program that calls the function from the C standard library:

Possible Issues  (1)

Macros are not types, but replacement rules that are applied to types when they are resolved. Therefore, it is impossible to have different definitions of the same function for a macro and the type to which it refers:

Unlike macros, aliases are types, so functions can recognize whether they are applied to a type or an alias of that type.

Wolfram Research (2022), TypeDeclaration, Wolfram Language function, https://reference.wolfram.com/language/ref/TypeDeclaration.html.

Text

Wolfram Research (2022), TypeDeclaration, Wolfram Language function, https://reference.wolfram.com/language/ref/TypeDeclaration.html.

CMS

Wolfram Language. 2022. "TypeDeclaration." Wolfram Language & System Documentation Center. Wolfram Research. https://reference.wolfram.com/language/ref/TypeDeclaration.html.

APA

Wolfram Language. (2022). TypeDeclaration. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/ref/TypeDeclaration.html

BibTeX

@misc{reference.wolfram_2024_typedeclaration, author="Wolfram Research", title="{TypeDeclaration}", year="2022", howpublished="\url{https://reference.wolfram.com/language/ref/TypeDeclaration.html}", note=[Accessed: 09-December-2024 ]}

BibLaTeX

@online{reference.wolfram_2024_typedeclaration, organization={Wolfram Research}, title={TypeDeclaration}, year={2022}, url={https://reference.wolfram.com/language/ref/TypeDeclaration.html}, note=[Accessed: 09-December-2024 ]}