Skip to main content

Type System

RGC is a statically typed language: every expression has a known type at compile time, and type inference means you don't need to write annotations everywhere.

Primitive types​

TypeDescriptionExample
intinteger42
floatfloating point3.14
boolbooleanTrue / False
strstring"hello"
Nonenull valueNone

Type annotations​

Variables, function parameters, and return values can be annotated explicitly:

def scale(x: float, factor: int) -> float {
return x * factor
}

Type inference​

Unannotated local variables are inferred from their initializers:

def main() {
n = 10 # n: int
s = "rgc" # s: str
}

Composite types​

RGC provides algebraic data types (ADTs), including class and enum:

class Point {
x: int
y: int
}

enum Shape {
Circle(radius: float)
Rect(width: float, height: float)
}

Pattern matching​

Use match together with enum for pattern matching:

def area(shape: Shape) -> float {
match shape {
case Circle(r) => 3.14159 * r * r
case Rect(w, h) => w * h
}
}

Nullability and errors​

  • Use Maybe[T] for values that may be absent.
  • Use Result[T, Err] for recoverable errors; silent failure is not allowed.
  • Use the postfix ? operator to propagate errors: it returns early on Err and unwraps the payload on Ok.
def safe_div(a: int, b: int) -> Result[int, str] {
if b == 0 {
return Result[int, str].Err("division by zero")
}
return Result[int, str].Ok(a // b)
}

def total(a: int, b: int) -> Result[int, str] {
x = safe_div(a, b)?
return Result[int, str].Ok(x + 1)
}

Continue reading​