Objects

Types are essential units to defines GreyCat data structure. Types define aggregates typed fields into a named type, later instantiated as object. It is very similary concept than classess used in other Object Oriented programming languages.


Type definition

Here is an example of a type in Greycat:

type Country {
  name: String;
  phoneCode: int;
  location: geo;
}

type City {
  name: String;
  population: int?;
}

Objects

Let’s create luxembourg object, an instance of type Country:

fn main() {
    var luxembourg = Country {
        name: "Luxembourg",
        phoneCode: 352,
        location: geo::new(49.8153, 6.1296),
    };
    println(luxembourg);
    println(luxembourg.phoneCode);
}
greycat run
# {"_type":"project.Country","name":"Luxembourg","phoneCode":352,"location":{"_type":"core.geo","lat":49.815300005,"lng":6.129600001}}
# 352

Static attributes

type Country{  
    static unknown_country_name: String = "Unknown Country";  
    name: String;
    phoneCode: int;
    location: geo;
}

fn main() {
    println(Country::unknown_country_name);
}

Functions on types

type Country {
    name: String;
    location: geo;
    fn print() {
        println("Hello from ${this.name}, location is latitude: ${this.location.lat()}, longitude: ${this.location.lng()}");
    }
}
fn main() {
    var luxembourg = Country { name: "Luxembourg", location: geo::new(49.815300005, 6.129600001) };
    luxembourg.print();
}
greycat run
# Hello from Luxembourg, location is latitude: 49.815300005, longitude: 6.129600001

Enum

Enums are list of values known at compile-time that cannot be extended dynamically. They are very useful tools when list of options are part of a domain definition. They can be used through the keyword enum and can have or not values.

enum DaysOfTheWeek{
    monday("Monday");
    tuesday("Tuesday");
    wednesday("Wednesday");
    thursday("Thursday");
    friday("Friday");
    saturday("Saturday");
    sunday("Sunday");
}
enum TransactionChannel{
    web(0);
    mobile(1);
    other(2);
}
fn main(){
    var day = DaysOfTheWeek::monday; // same accessor as the static :: 
}

Generic parameters

GreyCat support up to two generic paramaters for classes, for instance the map native class from STD library is defined as follow:

native type Map<K,V>{
    native fn get(k: K): V;
}

The generic parameters can be specialized during instance creation such as:

var m = Map<String,float>::new();
m.get("my_key");

Inheritance and composition

GreyCat support a simplified model of inheritance using the keyword extends such as:

type Sensor {
    value: float;
}
type SensorExtended extends Sensor {
    value2: int;
}

in addition GreyCat support type composition such as:

type SensorExtended extends Sensor {
    value2: int;
    s: Sensor;
}

Helper functions on types

GreyCat offers functions on types, such as parseNumber:

fn main() {
    println(parseNumber("123")); // 123
    println(parseNumber("12.3")); // 12.3
}

and some type inspection with sameType:

use util; // for Assert

type T {
    a: int;
}

fn main() {

    Assert::isTrue(sameType(1, parseNumber("123")));
    Assert::isTrue(sameType(1 as float, parseNumber("123.45")));

    Assert::isTrue(sameType(12_time, 342_time));
    Assert::isTrue(sameType(12_geo, 342_geo));
    Assert::isTrue(sameType(T{a: 12}, T{a:1234343}));

    var a = nodeTime<String>::new();
    var b = nodeTime<float>::new();
    a.setAt(12_time, "12");
    b.setAt(13_time, 13.4);
    Assert::isTrue(sameType(a, b)); // true!
}