C3 AI Documentation Home

Value Types

A ValueType is the metadata for any individual piece of data the C3 AI Type System understands. Value Types can represent specific instances of Types, primitive values, collections, and functions. A ValueType represents a category or structure of data, enabling you to specify how data is handled, processed, or stored.

The metadata provides detailed information about a Type's structure, including its fields, methods, mixins, and annotations. This can help you understand the full capabilities and constraints of a Type. This is crucial for understanding the structure and capabilities of a Type, especially when dealing with complex models or dynamically generated Types.

ValueType hierarchy

To understand the types of data represented within the C3 AI Type System, here is a breakdown of the ValueType hierarchy:

Below is a more detailed breakdown of key Types.

PrimitiveType

The PrimitiveType is the simplest data type. Primitive Types are basic data types that are indivisible and have no substructure, such as numbers, strings, or booleans. The PrimitiveType cannot be broken down into smaller parts, although it can have an internal structure in practice (for example, a datetime value, which has rules for representing calendar units). However, this internal structure is not exposed to the user directly through the system.

The hierarchy of Primitive Types includes:

  • Numeric Types:

    • Integer types:
      • int (64-bit signed integer)
      • int32 (32-bit signed integer)
      • int16 (16-bit signed integer)
      • byte (8-bit signed integer)
    • Real numbers:
      • double (IEEE 754 double precision floating*point)
      • float (IEEE 754 single precision)
      • decimal (exact representation using Binary*Coded Decimal)
  • Other Primitive Types:

    • string: A sequence of Unicode characters
    • boolean: A true/false value
    • datetime: Represents a logical or physical point in time
    • binary: A block of raw binary data
    • json: Data in JavaScript Object Notation format

ReferenceType

You can use Reference Types to represent fields that point to instances of other Types. For example, in the following codes snippet:

Type
type Automobile {
  manufacturer: Manufacturer
  maintenanceRecords: [MaintenanceRecord]
  calculateDepreciation: function(purchasePrice: decimal, currentYear: int): decimal
}

The manufacturer field is a reference to a Manufacturer Type, while maintenanceRecords is an array of MaintenanceRecord Types. Functions like calculateDepreciation represent methods bound to this Type.

Collection Types

Collection Types group multiple values together and define how those values are organized. Some collections preserve the order of insertion, while others (like sets) enforce uniqueness of elements. Collections also declare the Type of the elements they contain, ensuring consistency in data handling.

  • Array: Indexed collection of values.
  • Set: Unique collection that ignores duplicates.
  • Map: Key-value pair collection, where each key is associated with a value.
  • Stream: A read-once sequence of values, often used for processing large or transient data.

Example usage:

Type
type Automobile {
  features: [boolean]
  colors: set<string>
  prices: map<string, double>
  salesData: function(): stream<int>
}

More information about the Collection Type can be found in the topic on Collections.

Function Types

In the Type System, functions are represented as MethodType (methods bound to specific types) or LambdaType (dynamic or anonymous functions). Functions can take arguments and return values, all of which are strongly typed. The return Types and argument Types must be specified explicitly.

For instance:

Type
type Automobile {
  calculateDepreciation: function(purchasePrice: decimal, currentYear: int): decimal
}

Here, calculateDepreciation is a method that computes depreciation based on the purchase price and the current year, returning a decimal value.

  • Static methods: Called on the Type itself.
  • Member methods: Called on an instance of the Type.

Lambdas

Lambdas allow for dynamic function implementations that can be passed as data or assigned to fields. These are useful when the logic is expected to change or when functions must be customized for different instances.

For example:

Type
type Automobile {
  depreciationAlgorithm: lambda(purchasePrice: decimal, currentYear: int): decimal
}

A lambda in this case could represent different depreciation algorithms for different instances of Automobile.

Was this page helpful?