Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Everything within the C3 AI Suite is managed through or exists as a C3 .ai Type. C3. ai Types allow users to describe, process, and interact with data and analytics. Broadly speaking, a C3.ai Type is like a Java class, containing C3 Types are like Java classes, and include 'fields', 'methods', and an inheritance structure. Once you understand the structure of C3 .ai Type, Types you will be able to write your own C3.ai Types to load data, run analytics, build and deploy machine learning models, and configure application UIs, logic for your research project. 

All C3 .ai Types are defined in a .c3typ file, stored in 'src' directory of a C3.ai Package. (We'll get to C3.ai Packages a little later). All .c3typ files package. A .c3typ file can only define a single C3 .ai Type.Type. The .c3typ file name must match the name of the C3 Type being defined. 

In this section we will describe the package First, we will introduce the C3.ai Package to download for this example. Then, tutorial then we will discuss the syntax, special keywords, fields, methods, and Inheritance inheritance structure of C3 .ai Types. Finally, we will review some examples.

lightbulbAD

...

Package

For In this Guide, tutorial we will use the lightbulbAD C3 package. If you want to follow along with source code, please To download the source code for this package following , please follow the instructions available here: Guide to download C3 lightbulbAD Package.

Syntax

To start this discussion of syntax, Let To help familiarize yourself with the syntax for a C3 Type, let's look at how the definition of the 'SmartBulb' Type is defined in the lightbulbAD C3 Packagepackage:

...

/*
 * Copyright 2009-2020

...

C3

...

(www.c3.ai).

...

All

...

Rights

...

Reserved.

...


 *

...

This

...

material,

...

including

...

without

...

limitation

...

any

...

software,

...

is

...

the

...

confidential

...

trade

...

secret

...

and

...

proprietary

...


 *

...

information

...

of

...

C3

...

and

...

its

...

licensors.

...

Reproduction,

...

use

...

and/or

...

distribution

...

of

...

this

...

material

...

in

...

any

...

form

...

is

...


 *

...

strictly

...

prohibited

...

except

...

as

...

set

...

forth

...

in

...

a

...

written

...

license

...

agreement

...

with

...

C3

...

and/or

...

its

...

authorized

...

distributors.

...


 *

...

This

...

material

...

may

...

be

...

covered

...

by

...

one

...

or

...

more

...

patents

...

or

...

pending

...

patent

...

applications.

...


 */

...



/**

...


 *

...

A

...

single

...

light

...

bulb

...

capable

...

of

...

measuring

...

various

...

properties,

...

including

...

power

...

consumption,

...

light

...

output,

...

etc.

...


 */

...


entity

...

type

...

SmartBulb

...

extends

...

LightBulb

...

mixes

...

MetricEvaluatable,

...

NLEvaluatable

...

type

...

key

...

"SMRT_BLB"

...

{

  /**

...


   * This bulb's

...

historical

...

measurements.

...


   */

...


  bulbMeasurements:

...

[SmartBulbMeasurementSeries](smartBulb)

...



   /**

...


    * This bulb's

...

historical

...

predictions.

...


    */

...


   @db(order='descending(timestamp)')

...


   bulbPredictions:

...

[SmartBulbPrediction](smartBulb)

...



   /**

...


    * This bulb's

...

latest

...

prediction.

...


    */

...


   currentPrediction:

...

SmartBulbPrediction

...

stored

...

calc

...

"bulbPredictions[0]"

...



   /**

...


    * This bulb's

...

historical

...

events.

...


    */

...


   bulbEvents:

...

[SmartBulbEvent](smartBulb)

...



   /**

...


    * The latitude of this bulb.
    */
   latitude: double

   /**
    * The longitude of this bulb.
    */
   longitude: double

   /**
    * The unit of measurement used for this bulb's light output measurements.
    */
   lumensUOM: Unit

   /**
    * The unit of measurement used for this bulb's power consumption measurements.
    */
   powerUOM: Unit

   /**
    * The unit of measurement used for this bulb's temperature measurements.
    */
   temperatureUOM: Unit

   /**
    * The unit of measurement used for this bulb's voltage measurements.
    */
   voltageUOM: Unit

   /**
    * A SmartBulb is associated to a {@link Fixture} through a SmartBulbToFixtureRelation.
    */
   @db(order='descending(start),

...

descending(end)')

...


   fixtureHistory:

...

[SmartBulbToFixtureRelation](from)

...



   /**

...


    * The current Fixture to which this bulb is attached.
    */
   currentFixture: Fixture stored calc 'fixtureHistory[0].(end

...

==

...

null).to'

...



   /**

...


    * Method to determine the expected lumens of a light bulb
    */
   expectedLumens: function(wattage:

...

!decimal,

...

bulbType:

...

!string):

...

double

...

js

...

server

   /**

...


    * Returns the life span of this smartBulb
    */
   lifeSpanInYears: function(bulbId:

...

string):

...

double

...

js

...

server

   /**

...


    * Returns the average life span of all smartBulbs.
    */
   averageLifeSpan: function():

...

double

...

js

...

server

   /**

...


    * Returns the id of the smart bulb with the shortest recorded life span to date.
    */
   shortestLifeSpanBulb: function():

...

string

...

js

...

server

   /**

...


    * Returns the id of the smart bulb with the longest recorded life span to date.
    */
   longestLifeSpanBulb: function():

...

string

...

js

...

server

...



}

At a glance, a .c3typ file has the following components: 

  • Keywords which define

We can see the general structure of the .c3typ file at a glance

  • Keywords introduce the name, inheritance structure, and specify properties of the type.
  • fields are named, and their Types defined
  • methods are named, their types are similar to function signatures.
  • Additional annotations like '@db' can sometimes precede fields or methods.
  • Types can inherit other types.

From a high level, the signature of a C3 Type definition looks like this: (originally from official C3.ai type documentation here: https://developer.c3.ai/docs/7.12.17/topic/mda-types

Code Block
[remix, extendable] [entity] type TypeName [extends, mixes AnotherType] {
	/* comments */
	[field declaration]
	[method declaration]
}
  • a C3 Type.
  • Fields which define attributes or data elements on a C3 Type.
  • Methods which define business logic on C3 Types.
  • Annotations like '@db', which often precede fields or methods and further configure a C3 Type.
  • Constants such as strings or integers.
  • Comments which aren't parsed by C3 and instead provide a message to the developer.

At a high level, the basic syntax to define C3 Types is as follows:

[remix, extendable] [entity] type TypeName extends, mixes AnotherType {
    /* comments */
    [field declaration]
    [method declaration]
}

Note: Everything within square brackets '[]' is optional.

Additional Resources

  • C3

...

  • AI Developer Documentation:

    Keywords

    A C3 Type definition is introduced using with a series of keywords, and names. These keywords tell the C3 AI Suite how to construct this typeType, how to store it internally, and whether it inherits fields and methods from other already defined C3 Types. We describe each:

    • type: All C3 Types use .c3typ files have the keyword 'type'. This indicates to keyword tells the C3 AI Suite that this is file defines a C3 Type definition. 
    • entity: The keyword 'entity' keyword indicates that the type mixes in the the C3 Type is a 'Persistable' type and is stored internally to C3 in a table somewhere. We can mix in Persistable instead but this keyword makes the Type definition shorter and easier to read(i.e., needs to be stored in a database in the C3 AI Suite). Since a large majority of the C3 Types on the C3 AI Suite are persistablePersistable, this is a good keyword to have.
    • mixes: A type which specifies `mixes AnotherType` inherits the fields and methods of the other type. Multiple Types can be mixed in, and mixes do not change the way the type is stored internally.
    • remixes: A type which specifies `remix` defines a modification of an existing type.
    • extends: A type which specifies `extends AnotherType` is a special type of of mixin. This mixin subclasses a persistable type in a special way, The original Types along with the new Types are stored together in the same table. required as well, is the `type key` modifier which describes the key to use when storing the new type internally.
    • extendable: A keyword indicating that a Type can be extended. The C3 AI Suite will create the internal table for this type with an additional field called the 'key' which will be used to distinguish the different varieties of this base type.
    • type key: A set of keywords indicating the Key value to use when storing a type which extends another type.
    • schema name: A set of keywords indicating the name of the table to use to store the Type.

    Primitive Types

    As a basis for many fields, the C3 AI Suite defines many 'primitive' types. These are basic types like 'int' and 'double. Primitive Types are given to the developer by the platform and new ones require backend C3 support to define. Most DTI researchers will not be defining these, but using those that already exist.

    We list them here for reference.

    • binary
    • boolean
    • byte
    • char
    • datetime
    • decimal
    • double
    • float
    • int
    • json
    • long int
    • string

    C3.ai resources on Primitive Types:

    ...

    • 'entity' is an important keyword to include in .c3typ files. 
    • mixes: Adding the keyword `mixes <AnotherType>`, a C3 Type inherits the properties (e.g., fields, methods) of `<AnotherType>'. A C3 Type can mix-in multiple Types. 
    • remixes: Adding the keyword`remix <AType>` allows a developer to modify an existing C3 Type (e.g., add new fields or methods, update existing fields or methods). Re-mixing is useful when you don't have access to the original .c3typ file for a particular C3 Type, but wish to edit that C3 Type. 
    • extends: Developers often add the keyword `extends <AnotherType>` to define a subclass of a particular C3 Type (e.g., SmartBulb extends Lightbulb). The extension Type (i.e., Smartbulb) inherits all the fields and methods of the original Type (i.e., Lightbulb). Additionally, data associated with the extension and original C3 Types are stored in the same database table. Therefore, you must specify a `type key`on the extension Type so the C3 AI Suite can distinguish data associated with the extension and original C3 Types. Please note a C3 Type can only extend ONE other Type. 
    • extendable: All extended Types (i.e., Lightbulb) MUST be marked with the keyword "extendable".  Under the covers, the keyword "extendable" tells the C3 AI Suite to add a field (called 'key') to the database table storing the extended (or base) C3 Type. This 'key' field is used to distinguish data associated with different varieties of the extended C3 Type.
    • type key: All extension Types (i.e., Smartbulb) MUST BE marked with the keyword 'type key <VALUE>' (e.g., "type key SMRT_BLB").
    • schema name: A set of keywords indicating the name of the database table used to store data for a Persistable C3 Type. Developers specify a schema name to customize database table names.

    Additional Resources

    ...

    ...

    ...

    ...

    ...

    ...

    ...

    • Primitive Fields

    Persistable Types

    The most common type a C3 developer will define is a 'Persistable' type. A Persistable type is any type which inherits the 'Persistable' Type. This can be specified either by directly mixing in 'Persistable', or using the keyword 'entity'. All persistable types live within the C3 AI Suite stored in a table backed by some sort of database technology. Usually this is postgres, but depending on the data (Or annotations as will be discussed below), It can also be stored in a file blob or key-value store such as Cassandra.

    The C3 AI Suite also needs to know where to store this table. Thus when the user is creating an entirely new persistable type (that is one not extending an existing persistable type), they must use the keywords 'schema name' followed by the table name to define the name of the table to use. (e.g., in the definition of LightBulb, we have 'schema name "LGHT_BLB"'.

    C3.ai resources on Persistable Types

    Generic Types

    Types can also be made generic similar to Java generic Types and C++ generic classes. In fact, it uses the same syntax with angle brakets '<>' defining the generic parameters of the type. When defining a generic type, the Name of the type you're creating will be followed by angle brackets and a comma-separated list of placeholder names to refer to the generic type parameters you want to use. For example:

    Code Block
    type TheType<V,U> {
    	fieldA: V
    	fieldB: [U]
    }

    Then, when you use your type in other places, you must specify which type you mean in each type parameter slot. So later you might define a new type which has a field like:

    Code Block
    type NewType {
    	newField: TheType<TypeA, TypeB>
    }

    C3.ai resources on Generic Types:

    Fields

    Each field of a C3 Type is defined by first giving the field name followed by a colon ':' followed by a Type.

    The name must follow a set of conventions: – Name conventions here –

    Depending on the Type of the field, the field is grouped into some broad categories.

    Primitive Fields

    Primitive Fields use types which are PrimitiveTypes. These are simple data types usually directly supported by database technologies such as SQL. These fields are stored directly within the main type's table.

    Reference Fields

    Reference Fields use another defined C3 Type. This reference is implemented in the main Type's table as a foreign key into the referenced Type's table, (The 'id' field!).

    Collection Fields

    Collection Fields are groups of Types. There are four broad categories of collections which can be used.

    • array: denoted by `[MyType]`
    • map: denoted by `map<int, MyType>` (the left argument is the key which can be any primitive type, while the right can be any Type.)
    • set: denoted by `set<MyType>`
    • stream: denoted by `stream<MyType>`. (This is a read-once type of collection).

    When we define a field which is a collection of MyType, we can also specify which MyTypes get added by using Foreign Key Collection Notation. If for example, we're trying to define the new type TheType, and we want a collection to have type [MyType], but we don't want all MyTypes to be in this collection, we can use the notation `(thetype, id)` which specifies that C3 Should only use MyTypes whose 'thetype' property matches TheType's id property. Please see the section 'Foreign Key Collection Notation and Schema Names' in the following C3.ai documentation where this concept is explained better: https://developer.c3.ai/docs/7.12.17/topic/mda-fields

    Calculated Fields

    These fields are derived from other fields. Calculated fields are specified as follows

    Code Block
    fieldName: FieldType [stored] calc "field_formula"

    So, like the other types, we first specify a type for the field, then we must use the keyword 'calc' followed by an expression formula. (e.g, in the SmartBulb example above, this is 'fixtureHistory[0].(end == null).to').

    You may also specify the keyword 'stored'. With the stored keyword, the value of the field is stored in the Type's Table, while without it is calculated at runtime.

    ...

    C3 Types 

    There are many categories of C3 Types. 

    We will cover the most commonly used categories in this tutorial:

    • Primitive Types 
    • Persistable Types 
    • Generic (Parametric) Types 
    • Abstract Types 

    Primitive Types

    Like many programming languages, the C3 AI Suite has primitives. Primitives define the units (or data types) of fields on a C3 Type (e.g., "int", "double", "float"). The C3 AI Suite includes a number of primitives, listed below for reference. Adding new primitives will require support from the C3 AI engineering team, however, most DTI researchers should be able to progress their research projects with the C3 AI Suite's existing primitives. 

    • binary
    • boolean
    • byte
    • char
    • datetime
    • decimal
    • double
    • float
    • int
    • json
    • long int
    • string

    C3 Also supports certain composites of primitive types. For example, the C3 Type Mapp  is a map between values and keys. We can create a map directly in python in two ways:

    1. Let C3 Figure out the type for us: c3.MappObj(value=python_obj) The new Mapp object can be accessed through the .value  property of the MappObj
    2. Tell C3 exactly which types are supported with c3.Mapp(c3.MappType.fromString("map<string,any>"), {'a': 5, 'b': [1,2,3]})

    Similarly, C3 has the Arry  type which supports plain arrays. We can specify them in the same ways.

    1. Let C3 Figure out the type for us: c3.ArryObj(value=python_list)  The new Arry  object can be accessed through the .value  property of the ArryObj
    2. Tell C3 exactly which types are supported with c3.Arry(c3.ArryType.fromString('[int]'), [1,2,3,4]) 

    In both cases, these primitive types aren't persisted. They can be used anywhere a C3 Type specifies it must have an Obj  type. (Especially useful for DynBatchJobs  or DynMapReduce jobs for contexts).

    Additional Resources

    Persistable Types

    The most common C3 Type you will define is a 'Persistable' Type. Persistable Types store data in a C3 AI Suite database. By default, all Persistable Types are stored in Postgres though they can also be stored in file systems (e.g., Azure Blob) or key-value stores (e.g., Cassandra), by adding an annotation to your .c3typ file (discussed below). 

    When defining a Persistable type, you MUST add the following two key terms to your .c3typ file:

    1. entity: The keyword 'entity' keyword tells the C3 AI Suite this is a 'Persistable' Type.
    2. schema name: The schema names is the name of the database table where the C3 Type's data are stored. When defining a new Persistable Type, you need to add the keywords 'schema name' followed by your chosen table name, in your .c3typ file. (e.g., in the C3 Type LightBulb, we have 'schema name "LGHT_BLB"').
      Note: Extended C3 Types DO NOT NEED a scheme name and Schema names CANNOT exceed 30 characters. 

    Additional Resources

    Generic (Parametric) Types

    Like a Java or C++ Class, C3 Types can be parameterized (or genericized). In fact, the C3 AI Suite uses the exact same syntax as Java and C++ to define a Type's parameters (i.e., angle brackets '<>' ). When defining a Generic (Parametric) Type, your Type name will be followed by angle brackets and a comma-separated list of parameters (usually other C3 Types).  For example:

    Code Block
    type TheType<V,U> {
    	fieldA: V
    	fieldB: [U]
    }

    Then, when using your Parametric Type in other places, you must specify the arguments for each parameter in the angle brackets. As example, you may define a new C3 Type with the following field:

    Code Block
    type NewType {
    	newField: TheType<TypeA, TypeB>
    }

    If your C3 Types will be heavily re-used by other developers you should consider using Parametric (Generic) Types.

    Additional Resources

    Methods

    Each method of a C3 Type is defined by first giving the method name followed by a colon ':' followed by a function signature, (e.g., function() or function(wattage: !decimal, bulbType: !string)), followed by a colon ':', followed by a return Type, along with a language and environment specification.

    Function Signatures

    Instead of a Type name following the name as with fields, methods have a function signature. the syntax looks like:

    Code Block
    function(parName1: [!] parType1, parName2: [!] parType2):

    we see 'function' followed by a comma separated list of argument definitions. An argument definition consists of a parameter name followed by a colon ':', followed by a Type name. Optionally, you can also include an '!' before the parameter type to indicate that that argument is required.

    Return Types

    After the function signature we have a return type. This must be a C3 type. The function must return an object of the appropriate type in the .

    Language/Environment Specification

    Finally, we end with a language and environment specification.

    Language Specifications

    • py: Use the 'py' keyword to indicate this is a Python function.
    • js: Use the 'js' keyword to indicate this is a JavaScript function.

    Currently, these are the only two languages which the C3 AI Suite supports for native method definitions

    Environment Specification

    Then, this is followed by an environment specification. for JavaScript the only two environments are:

    • server: This JavaScript function is executed within the C3 AI Suite by a worker node.
    • client: This JavaScript function is executed at the client browser.

    Fields

    As discussed above, a C3 Type mainly consists of two components: fields and methods.

    Fields are attributes or properties of a C3 Type. To define a field on C3 Type, use the following syntax: field name, followed by a colon ':', followed by a ValueType (e.g., "lumens: int"). By convention, field names are camelCase.

    A C3 Type can have many different kinds of fields. Here are the four most commonly used fields:

    • Primitive Fields 
    • Reference Fields 
    • Collection Fields 
    • Calculated Fields 

    Primitive Fields

    Like many other programming languages the C3 AI Suite has primitive fields (e.g., int, boolean, byte, double, datetime, string, longstring). For example:

    doubleField: double
    intField: int

    Primitive fields are stored in a particular C3 Type's database table.

    Reference Fields

    Reference fields point (or refer) to other C3 Types. Reference fields link (or join) two C3 Types together. Under the covers, the Reference field stores a pointer (i.e., foreign key reference or ID) to record of another C3 Type. To define a Reference field, use the following syntax: field name, followed by colon ':', followed by Type Name (e.g., "building: Building"). For example:

    refField: AnotherType

    Collection Fields

    Collection fields contain a list of values or records. There are four categories of collections fields:

    • array: denoted by `[MyType]` (contains an array of references to 'MyType').
    • map: denoted by `map<int, MyType>` (left argument is the key which can be any primitive type, right argument can be any C3 Type).
    • set: denoted by `set<MyType>`.
    • stream: denoted by `stream<MyType>`. (This is a read-once type of collection).

    Collection fields can also be used to model one-to-many and many-to-many relationships between two C3 Types. To do so, we use the Foreign Key Collection Notation, which specifies the foreign key by which two C3 Types (i.e., ThisType and AnotherType) are joined.

    To define this annotation use the following syntax: "fieldName :   `[AnotherType]` (fkey, key)" where:

    • 'fkey' is a field on `AnotherType' to use as the foreign key
    • 'key' is an optional field on ThisType, whose records should match those of the 'fkey' field on 'AnotherType' (defaults to `id` field of ThisType, if not specified).
    • In other words, the Collection field will contain pointers to all records in AnotherType, where ThisType.key == AnotherType.fkey.

    For example:

    fieldName: [AnotherType] (fkey[, key])

    Shown in the example code and diagram below, the field bulbMeasurements, contains a list of all the SmartBulbMeasurementSeries records, where SmartBulb.id == SmartBulbMeasurements.smartBulb (e.g., a list of various measurements relevant to a SmartBulb, like temperature or power). 

    Image Added

    Please see the 'Foreign Key Collection and Schema Names" section in the following C3 AI Develop Documentation for more details: https://developer.c3.ai/docs/7.12.25/topic/mda-fields

    Calculated Fields

    Calculated fields are derived from other fields on a C3 Type. Calculated fields typically included either JavaScript code or C3 AI ExpressionEngineFunctions and are specified as follows:

    fieldName: FieldType [stored] calc "field_formula"

    There are two types of calculated fields:

    1. Simple calculated fields: The values of these fields are calculated at runtime and not stored. To define a simple calculated field use the following syntax: keyword `calc`, followed by an expression formula.
    2. Stored calculated fields: The values of these fields are stored in the C3 Type's database table. To define a stored calculated field use the following syntax: keywords `stored calc`, followed by an expression formula (e.g, in the SmartBulb example above, 'stored calc fixtureHistory[0].(end == null).to').

    Additional Resources

    Methods

    At a high-level, methods are pieces of code that take in arguments or parameters and return new values. To define a method on a C3 Type, use the following syntax, method name followed by a colon ':' followed by a function signature, (e.g., function() or function(wattage: !decimal, bulbType: !string)), followed by a colon ':', followed by a return parameter, along with an implementation language and execution location

    Function Signatures

    Here's the syntax for a method's function signature:

    Code Block
    function(parName1: [!] parType1, parName2: [!] parType2):

    We see the keyword 'function' followed by a comma-separated list of input parameters. To define an input parameter, use the following syntax: argument name followed by a colon ':', followed by argument type (e.g., bulbID: string). Optionally, you can also add an exclamation point '!' before the argument type to indicate the argument is required.

    The function itself is NOT implemented in the .c3typ file, rather in a separate .js (JavaScript), .py (Python) or .r (R) files stored in the same directory as the .c3typ file. 

    Return Parameter

    Following the function signature is a return parameter. Return parameters must be a C3 Type. 

    Implementation Language/Execution Location

    Finally, let's discuss the implementation language and execution location.

    Language Specifications

    Methods can be implemented in JavaScript, Python, or R:

    • py: Use the 'py' keyword to indicate this is a Python method.
    • js: Use the 'js' keyword to indicate this is a JavaScript method.
    • r: Use the 'r' keyword to indicate this is an R method.

    Currently, these are the only three programming languages natively supported by the C3 AI Suite to define methods. 

    Execution Location

    Methods can be executed in three locations:        

    • server: Indicates the method will run on the C3 AI Suite by a worker node. Server should be used for methods requiring high processing power (e.g., methods that fetch or create large amounts of data).
    • client: Indicates the method will run on the client's browser.
    • all: Indicates the method will run wherever it is called from. If the call comes from the browser, the function will execute in the browser. If the call comes from a server, the execution will happen in the server.

    Please note, R and Python methods can only be executed on the server. Javascript methods can be executed in either the server or client.

    Additionally, for For Python, we need to specify a valid 'ActionRuntime' for the python function to be executed in. ( ActionRuntimes are defined within the in C3 AI Suite , and new ones ActionRuntimes can be defined as part of a C3 Package. They in a package and are essentially conda environments. ) For example, 'server' will use the 'py-server' ActionRuntime.

    Function Definitions

    FinallyAs mentioned above, the function definition goes itself is defined in a different file from the Type definition .c3typ file. It should have The name of this file should be the same base name as the .c3typ definition file, but have an extension appropriate for the language of implementation file where the method is defined (e.g., SmartBulb.js and SmartBulb.c3typ), but have a different extension, per the function's implementation language (e.g., 'py' for PythonPython, 'js' for JavaScript, 'jsr' for JavaScriptR). Within, the file must contain functions whose name matches the method name from the Type definition exactlyThe function names in this file must exactly match the method names in the .c3typ file. For example, if we have define a C3 Type defined like soas such: 

    Code Block
    entity type NewType {
    	field: double
    	funcA: function(num: !int) : float js server
        funcB: function(num: !int, name: string) : double py server
    }

    This type C3 Type will be defined in a file named called 'NewType.c3typ',  There will also have to be . We also need two other files, 'NewType.js' and 'NewType.py', in the same directory as 'NewType.c3typ'. Here's a peek inside:

    'NewType.js'

    ...

    Code Block
    function funcB(num, name='default') {
        ...
    }

    ...

    Additional Resources

    Inheritance

    Like many modern languages, Types can also a Java or C++ Class, a C3 Type can inherit fields and methods from other types in an object oriented fashionC3 Types. The keywords which signal inheritance are `keywords`mixes` and `and `extends` signal inheritance. These keywords follow the name of the new type.C3 Type's name in your .c3typ file.

    These Where C3 Type inheritance differs from other languages, is that these two keywords signal two different types kinds of Type inheritance.

    Mix-ins

    This most basic Mix-ins are the most common type of inheritance is and signaled by the 'mixes' keyword. When a type C3 Type 'mixes' another typeC3 Type, it inherits all of the fields and methods of that type. The new type gets its own schema and table, and the user can go on to use it as they normally would.the original C3 Type. In general, mix-ins are used to incorporate non-persistable Types. The new C3 Type is stored in a new table and has its own schema. 

    Code Block
    type ParentType {
        fieldA: int
        funcA: function(): ReturnType
    }
    
    type ChildType mixes ParentType {
        fieldB: double
        funcB: function(): ReturnType
    }

    In this example, ChildType also includes the field and method defined in the parent typemixes ParentType, and inherits 'fieldA' and 'funcA' defined on ParentType.

    Persistable Inheritance

    This second type of Persistable inheritance is signaled by the 'extends' keyword. When a type C3 Type 'extends' another typeC3 Type, it inherits its fields and methods, but also resides in the same schema and table as the original type. In fact, a type can only extend a type which has been marked as `extendable`.all the original C3 Type's fields and methods. The extension and original C3 Types must be marked with 'entity' keyword and share the same database table. To distinguish data from the original and extension C3 Types, the C3 AI Suite adds a 'type key' field to this database table. Additionally, only C3 Types marked with the `extendable` keyword can be extended. 

    Code Block
    extendable entity type ParentType schema name "PRT_TYP" {
        fieldA: int
        funcA: function(): ReturnType
    }
    
    entity type ChildType extends ParentType type key "CHLD" {
        fieldB: double
        funcB: function(): ReturnType
    }

    In this example, ParentType is an extendable Persistable type stored in schema Persistable type stored in the table 'PRT_TYP'. ChildType extends ParentType and is also stored in the table 'PRT_TYP'. ChildType extends ParentType and uses   Records associated with ChildType have 'type key' == 'CHLD' .C3.ai developer resources on Inheritance:to distinguish them from ParentType's data.

    Additional Resources

    Annotations

        • Key
        • Type Composability

    Annotations

    With annotations you can further configure a C3 Type. Annotations Annotations can appear before Type definitions, field declarations, and method declarations. They do a variety of things such as configure As example, annotations can be used to specify the database technology used to store that Type, mark what type of ActionRuntime should be used a C3 Type (e.g., Cassandra, Azure Blob), mark the ActionRuntime in which to run a particular method, Mark deprecate a field or method as deprecated or beta, Specify a timeseries treatment, and specify parameters of C3 Analytics (discussion to come soon). These are only a selection of what annotations can do., specify how time-series data should be treated, and specify how to trigger analytics or DFEs (DataFlow Events).

    Here are a few examples of defining annotations: Here, we show a couple of examples:

    Code Block
      /**
       * This bulb's historical predictions.
       */
      @db(order='descending(timestamp)')
      bulbPredictions: [SmartBulbPrediction](smartBulb)

    The bulbPredictions field is annotated that the database should store the bulbPredictions With the `@db(order = 'descending(timestamp)'` annotation, the bulbPrediction field's records are stored in descending order by timestamp.

    Code Block
    @ts(treatment='avg')
    lumens: double

    With the `@ts(treatment = 'avg')

    ...

    The annotation, the value of the lumens field of a type be default is now going to use the 'AVG' treatment.C3.ai developer resources on Annotations:for a given SmartBulb is the average of all that Smartbulb's lumens data. 

    Additional Resources

    Final

    ...

    Types

    Types, methods, and fields can be made 'final' using the 'final' keyword. This prevents The fields and methods from being overridden by any type which mixes them in. If a type is made final, all fields and methods of that type are made final.of a Final Type cannot be modified or overridden (via 'mixes' or 'exends').

    Code Block
    type FinalType {
        final method: function(): string
    }

    ...

    Additional Resources

    Abstract Types

    The C3 AI Suite also supports abstract types. If you use To define an Abstract Type, add the keyword 'abstract' before the type definition, this will indicate an abstract type. You cannot instantiate an abstract type, and must mix it into another concrete typeType definition. Abstract Types cannot be instantiated and must mix-in to another concrete Type. This provides a great way to standardize interfaces. Here's an example:

    Code Block
    abstract type InteraceInterface {
    	field1: int
        method1: function(double): int
    }

    ...

    Additional Resources

    Examples

    Look through the lightbulbAD package and find To see more examples of C3 Types, check out the .c3typ files . Look at these to see the range of possibilitiesin the lightbulbAD package: Guide to download C3 lightbulbAD Package