In this page
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}
- time is a native concept and is handled in the back as primitive signed int64
- It is absolute, chronological, and represents the number of microseconds passing since 01/01/1970 UTC.
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
- another important concept when manipulating time is duration
- it is defined as the span between 2 points in time.
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
}
- the native unit of duration in greycat is microseconds (since time itself is in microseconds)
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
Date (human activity related time)
- since dealing with epoch time is not human friendly, we have the notion of Date
- date relates to human activity/calendar => needs a TimeZone
- converting time to Date or vis-versa is done like this:
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
- The conversion time to date is resource intensive, while the conversion date to time is straightforward
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
- for convenience, GreyCat natively offers a template mechanism ${ }
- any GreyCat expression or function can be interpreted in this template.
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