A def is a function. It’s a way to structure omni code with re-usable blocks.

ins:  2
outs: 1

def mySum(a, b):
    return a + b

    out1 = mySum(in1, in2)

The types of the arguments and the return type of a def are inferred by the calling context. This means that the def mySum can be called on whatever type that supports the + operator.

x      = mySum(1, 2)      #returns an int, but x will change it to float
x2 int = mySum(1, 2)      #this will preserve the int
y      = mySum(1.0, 2.0)  #returns a float
z      = mySum(1, 2.0)    #returns a float

Types can be inforced by appending the type to the argument name.

def myIntSum(a float, b float):
    return a + b

Also, def supports the use of generics. Generics in omni can only represent number types (int, int32, int64, float, float32, float64).

def myGenericSum[T, Y](a T, b Y):
    return a + b

Default values can be simply added with a = operator.

def mySum(a = 0, b = 0):
    return a + b

The return type can also be enforced with either of these two syntaxes:

def mySum(a = 0, b = 0) float:
    return a + b

def myOtherSum(a = 0, b = 0) -> float:
    return a + b

Return type can be a generic type, inferred from the types of the arguments:

def mySum[T, Y](a T = 0, b Y = 0) T:
    return a + b

When using a recursive def, the return type must always be specified. It can also just be a generic type.

ins 1
outs 1

def factorial(x) float:
    if x <= 1:
        return 1.0
    return x * factorial(x - 1)

    x = factorial(in1)

    out1 = 0.0

When passing structs (more on them in the next section) to a def, they are passed by reference, meaning that they can be accessed and their values can be modified in place.

struct Vector:
    x; y; z

def updateVec(vec Vector, x, y, z):
    vec.x = x
    vec.y = y
    vec.z = z

    vec = Vector()
    vec.updateVec(10, 20, 30)

Next: 06 - Custom types: struct