Hands On Generic Parameterization of Functions
Created: 12 February 2025 Modified: 16 March 2026Mojo Parameterization is part of compile time code generation/modification.
We will try to keep our exploration of Parameters as shallow as possible so we can jump right in to writing compilable code. The goal is to provide enough understanding of Mojo Parameters to enable reading of documentation.
You will need a basic understanding of Traits which can be acquired reading Hands On Mojo Traits.
In other programming languages parameter and argument terminology is often used interchangeably. In Mojo the two are distincly different. Function arguments are used while the compiled code is running. Parameters are used while the code is being compiled.
For our code example we will create a function that focus on Parameters and Generics. Generics allow us to write generic code that will interact with multiple different structures. As long as the structure implements the correct trait. Below we have a contrived example that shows how generics work. The commented out code will not compile. You can uncomment it while you are playing with the code to better understand how traits, parameters and generics work. Notice how the Cat and the Dog struct can both be used in the same method because they both implement the WarmBlooded trait.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
trait WarmBlooded:
fn is_warm_blooded(self) -> Bool:
...
trait ColdBlooded:
fn is_cold_blooded(self) -> Bool:
...
@fieldwise_init
struct Cat(WarmBlooded):
var name: String
fn is_warm_blooded(self) -> Bool:
return True
@fieldwise_init
struct Dog(WarmBlooded):
var name: String
fn is_warm_blooded(self) -> Bool:
return True
@fieldwise_init
struct Turtle(ColdBlooded):
var name: String
fn is_cold_blooded(self) -> Bool:
return True
fn print_warm_blooded[BloodType: WarmBlooded](warm_blood: BloodType):
print(warm_blood.is_warm_blooded())
fn print_cold_blooded[T: ColdBlooded](cold_blood: T):
print(cold_blood.is_cold_blooded())
fn main():
betsy = Cat("Betsy")
ralph = Dog("Ralph")
samuel = Turtle("Samuel")
print_warm_blooded(betsy)
print_warm_blooded(ralph)
# print_cold_blooded(betsy) # This line won't compile
# print_warm_blooded(samuel) # This line won't compile
print_cold_blooded(samuel)
- Lines 1-3 we define the warm blooded trait.
- Lines 5-7 we define the cold blooded trait.
- Lines 9-14 we define the Cat struct which implements the is_warm_blooded method.
- Lines 16-21 we define the Dog struct which implements the is_cold_blooded method.
- Lines 23-28 we define the Turtle struct which implements the is_cold_blooded method.
- Lines 30-31 we define a function that only accepts types that implement the warm blooded trait.
- Lines 33-34 we define a function that only accepts types that implement the cold blooded trait.
- Line 37 we instantiate a Cat struct.
- Line 38 we instantiate a Dog struct.
- Line 39 we instantiate a Turtle struct.
- Line 40 we run the print_warm_blooded function on the betsy object.
- Line 41 we run the print_warm_blooded function on the ralph object.
- Line 42 is commented out because it will not compile. Betsy variable of type Cat does not implement cold blooded trait.
- Line 43 is commented out because it will not compile. Samuel variable of type Turtle does not implement warm blooded trait.
- Line 44 we run the print_cold_blooded function.