GreyCat Language Syntax


Variables and scopes

The var keywords allows developer to declare new variables.

var x = 3;

GreyCat leverages an Automatic Reference Counter (ARC) strategy to cleanup variables. For performance reason, no Garbage Collector is used, and variables are available until all references from all scopes are clear.


Functions

Like most imperative languages, GreyCat uses functions to encapsulate a compute unit Functions in GreyCat are defined by the keyword fn

fn add(x: int, y: int): int {
    return x + y;
}

fn main() {
    println(add(1, 2)); // prints 3
}

Function add takes 2 integers x and y as parameter, and returns an integer.

So-called lambda functions are available too, and can be assigned to variables:

fn hello() {
    return "hello";
}

fn main() {
  // f_hello points to function hello:
  var f_hello = project::hello;
  println(f_hello()); // displays "hello"
}

Functions as values can therefore be used as function parameters, the following example illustrates function composition:

fn hello() {
    return "hello";
}

fn main() {
  var f_hello = project::hello;
  var f_len = fn (s: String): int { return s.size(); };

  var gof = fn (g: function, f: function): int { return g(f()); };

  var l = gof(f_len, f_hello);

  println("length of ${f_hello()} is ${l}");
}

Entrypoints

fn compute(p: int): int {
    return 3 + 5 + p;
}
fn compute12() {
    return compute(12);
}
fn main() {
    var res = compute(2);
    println(res);
}

the traditional main function can be executed by default with a run command

greycat run 
# 10

in fact, any parameter-less function can be executed directly as the entrypoint

greycat run project.compute12
# 20

Numbers (int/float)

fn main() {
  var i = 42;     // an integer number known as 'int' in GreyCat (64-bits)
  var pi = 3.14;  // a floating-point number known as 'float' in GreyCat (64-bits)
  var c = 3f;     // a floating-point number, with explicit 'f' suffix
  var x = float::max; //get the highest floating point 
}
Name Symbol Min Max Precision
Integer (64 bits) int -9,223,372,036,854,775,808 9,223,372,036,854,775,807 1
Float (64 bits) float -1.797E308 1.797E308 5.4E-079

Geo lat/lng positioning

fn main() {
    var position = geo::new(49.6116, 6.1319);
    println(position);
    println(position.lat());
    println(position.lng());
}

GreyCat encodes geo positions in an efficient way (64-bits for both latitude and longitude)


Time

fn main() {
    var t = time::now();
    println(t);
}

will print

{"_type":"core.time","epoch":1684162972,"us":393737}
Name Symbol Min Max Precision
Time (64 bits) time 21/12/-290308 10/01/294247 1 microsecond

There are several ways to initialize a time in GreyCat:

fn main() {
    var t1 = time::now(); //Current system time
    var t2 = 5_time; //5 microseconds after 01/01/1970
    var t3 = -1000000_time; //1 second before 01/01/1970
    var t4 = time::new(23, DurationUnit::hours); //23 hours after 01/01/1970
    var t5 = time::new(1684163705, DurationUnit::seconds); //If you have the POSIX epoch in seconds

    if (t5 > t4) {
        //Do something
    }
}

since time is an integer in the back, it can be compared to another time (absolute order)


Duration

fn main() {
    var t1 = time::new(1684164000, DurationUnit::seconds); //timestamp 1
    var t2 = time::new(1684165000, DurationUnit::seconds); //timestamp 2
    var d = t2 - t1; //d will automatically be a duration
    println(d.to(DurationUnit::seconds)); // Prints the integer number of seconds
    println(d.tof(DurationUnit::hours));  // Prints the fractional number of hours  
}

some other ways to initialize duration

    var d1 = duration::new(5, DurationUnit::microseconds);
    var d2 = duration::new(2, DurationUnit::days);         //new is used for int
    var d3 = duration::newf(1.5, DurationUnit::years);     //newf is used for float
    var d4 = 5.6_s;  // 5.6 seconds duration
    var d5 = 7_hour; // 7 hours duration

fn main() {
    var t = time::now();      //Current system time
    var date = t.toDateUTC(); //Date in UTC
    var dateLux = t.toDate(TimeZone::Europe_Luxembourg); //Date in Luxembourg Timezone 

    println("Date in UTC: ${date.format("%d/%m/%Y %H:%M:%S")}");
    println("Date in Luxembourg: ${dateLux.format("%d/%m/%Y %H:%M:%S")}");

    var convert_back_to_time = date.toTime(); //Convert date back to time
    if(convert_back_to_time == t){
        println("Successful");
    }
}

Date in UTC: 15/05/2023 16:12:09

Date in Luxembourg: 15/05/2023 18:12:09

Successful

A Date can be created in the following ways:

fn main() {
    var d = Date::new(2023, 06, 07, 10, 57, 32, 1, TimeZone::Europe_Luxembourg); // 7 June 2023 10:57:32 + 1us in Luxembourg timezone
    var d2 = Date::parse("07/06/2023 10:57:32", "%d/%m/%Y %H:%M:%S", TimeZone::Europe_Luxembourg);
    var d3 = Date::fromTime(time::now(), TimeZone::Europe_Luxembourg);
    println(d2.format("%d/%m/%Y %H:%M:%S"));
}

07/06/2023 10:57:32


Date methods always require a TimeZone


take away message: time is universal on earth while date can be mapped to several time!

use date only for feature extraction!


Date Format

Specifier Meaning Example
%d Day of the month, zero-padded (01-31) 22
%D Short MM/DD/YY date, equivalent to %m/%d/%y 07/30/09
%e Day of the month, space-padded ( 1-31) 22
%H Hour in 24h format (00-23) 16
%I Hour in 12h format (01-12) 08
%m Month as a decimal number (01-12) 08
%M Minute (00-59) 52
%S Second (00-61) 06
%s Unix time; the number of seconds since the Unix epoch. 1455803239
%y Year, last two digits (00-99) 11
%Y Year 2016

String definition

fn main() {
  var name = "Luxembourg";
  var sentence = "My city is named: ${name}";
  println(sentence);
}

My city is named: Luxembourg

fn main() {
    var name = "Luxembourg";
    var sentence = "${name} has ${name.size()} characters count in it";
    println("${sentence}");
}

Luxembourg has 10 characters count in it


Arrays and Maps

GreyCat provides arrays and maps that are in-memory and meant for small amounts of data

fn main() {
    var array = [1.2, 3.4, 5.0, 4.1];
    for (k, v in array) {
        println("Index: ${k}, value ${v}");
    }
}

Similarly:

fn main() {
    var map = Map<String, int>::new();
    map.set("Hello", 5);
    map.set("Test", 2);

    println(map.get("Test"));
}

Arrays and maps are useful for small amounts of data. For large datasets, use nodeIndex and nodeList