Base types in the lang package

Base types in the lang package

Some types are useful enough that they are imported into every ooc module out there. For example, Object, which is the default super type of all objects.

Integer types, both fixed-width (Int32, Int64) and variable-width (Long, LLong) are also in lang/types, along with the boolean type Bool.

Object / Class

The Object and Class classes are written in ooc itself, and not part of some separate C runtime.

Anytime a type is referred to, you have something of type Class:

type := Int
type name // "Int"
type size // 4
type instanceSize // 4

Actually, in this case, it’s an instance of IntClass, as demonstrated by this chunk of code:

type class name // "IntClass"

Even base types have classes, although they aren’t available via the class property, unlike objects.

dog := Dog new()
dog class == Dog // true

a := 42
a class // invalid, not an object, it doesn't have fields

This is especially useful for generics, where classes are passed along with actual arguments:

acceptAnything: func <T> (t: T) {
  T // is a subtype of Class, can access 'name', etc.
}

size vs instanceSize

For basic types such as Int, Float, Char - there is no difference between size and instanceSize. For complex types, e.g. objects, there is a difference between size and instanceSize.

For objects, size is always equal to the size of a pointer - since objects are references. However, instanceSize is equal to the amount of memory an object takes in memory.

For more information on the subject, read about ooc classes

Various types

Bool

Booleans in ooc, equal to either the boolean literal true, or false, are of type Bool.

b := true

Void

Void is the type of nothing. A function that doesn’t return anything has a return type of Void, implicitly.

It is never used explicitly throughout the SDK, it is mostly there so that compiler iternals work fine.

Pointer

Pointer is the umbrella term for any type of pointer. When possible, using a more precise type such as Int* is desirable.

None

None can be used as an object representing nothing. It has a single no-argument constructor:

nothing := None new()

It can be used in place of null when adopting a pattern-matching approach.

Cell

Cell is documented in the structs package.

VarArgs

This is the sdk-side implementation of variable arguments. Basically, it allows packing different values in the VarArgs structure with _addValue - although the compiler will typically write those out with a static initializer for efficiency.

They can be iterated through thanks to VarArgsIterator:

something: func (args: ...) {
  iter := args iterator()
  while (iter hasNext?()) {
    T := iter getNextType()
    match T {
      case Int =>
        value := iter next(Int)
        // do something with value
      case =>
        raise("Unsupported argument type: %s" format(T name))
    }
  }
}

Or, more simply, with each:

something: func (args: ...) {
  args each(|arg|
    match arg {
      case value: Int =>
        // do something with value
      case =>
        raise("Unsupported argument type")
    }
  )
}