Starklings04-Cairo: If
We’re back with another article of Starklings Cairo. In this installment, we’ll explore if
, the most basic (but still surprisingly versatile!) type of control flow. If you haven't seen our other articles, you can start with these: Variables in Cairo and Primitive Types in Cairo as well as Felt Operations. Understanding how to use if
expressions is fundamental for controlling the flow of your programs and making decisions based on conditions.
Further information
- If expressions — The Cairo book goes into more detail on how to use
if
andelse
as well aselse if
. We always recommend you go through the book as you are doing these exercises to help reinforce the concepts.
Alright let’s get started with these exercises!
if1.cairo
// if1.cairo
// Execute `starklings hint if1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn bigger(a: usize, b: usize) -> usize { // Complete this function to return the bigger number!
// Do not use:
// - another function call
// - additional variables
}
// Don't mind this for now :)
#[cfg(test)]
mod tests {
use super::bigger;
#[test]
fn ten_is_bigger_than_eight() {
assert(10 == bigger(10, 8), '10 bigger than 8');
}
#[test]
fn fortytwo_is_bigger_than_thirtytwo() {
assert(42 == bigger(32, 42), '42 bigger than 32');
}
}
First, we are tasked with completing the function to return the bigger number between a
and b
. We should not use another function call or additional variables. This seems simple enough, but as always let's take a look at the errors to keep on getting familiar with the output.
if1.cairo
Errors
Compiling test(exercise_crate_unittest) exercise_crate v0.1.0 (/Users/desmo/repos/starklings/starklings-cairo1/runner-crate/Scarb.toml)
error: Unexpected return type. Expected: "core::integer::u32", found: "()".
--> /Users/desmo/repos/starklings/starklings-cairo1/runner-crate/src/lib.cairo:6:40
fn bigger(a: usize, b: usize) -> usize { // Complete this function to return the bigger number! ^******************************************************
The error indicates that the function does not return the expected type, which means we haven’t implemented the return logic yet.
if1.cairo
Solution
To solve this, we’ll use a simple if
expression to compare a
and b
:
fn bigger(a: usize, b: usize) -> usize {
b
} else {
a
}
}
Explanation
In this very simple exercise, we can see how to use the if
expression to check which variable is bigger, a
or b
. The function bigger
takes two parameters, a
and b
, both of type usize
.
- Comparison: The
if
statement checks the conditionif a < b
to compare the two variables.
- If the condition is true (meaning
a
is less thanb
), the function executes the code block inside theif
statement and returnsb
. - If the condition is false (meaning
a
is not less thanb
), the function executes the code block inside theelse
statement and returnsa
.
2. Control Flow:
- When
a
is less thanb
, the function returnsb
, asb
is the larger number. - When
a
is greater than or equal tob
, the function returnsa
, asa
is the larger number or equal tob
.
This simple logic ensures that the function always returns the bigger of the two numbers without using any additional variables or function calls. This approach is efficient and straightforward, demonstrating the basic use of if
and else
in control flow. The function effectively selects the larger of the two numbers without any unnecessary complexity.
Great, let’s move on to the next one…
if2.cairo
// if2.cairo
// Step 1: Make me compile!
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
// Execute `starklings hint if2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn foo_if_fizz(fizzish: felt252) -> felt252 {
// Complete this function using if, else if and/or else blocks.
// If fizzish is,
// 'fizz', return 'foo'
// 'fuzz', return 'bar'
// anything else, return 'baz'
if fizzish == 'fizz' {
'foo'
} else {
1_u32
}
}
// No test changes needed!
#[cfg(test)]
mod tests {
use super::foo_if_fizz;
#[test]
fn foo_for_fizz() {
assert(foo_if_fizz('fizz') == 'foo', 'fizz returns foo')
}
#[test]
fn bar_for_fuzz() {
assert(foo_if_fizz('fuzz') == 'bar', 'fuzz returns bar');
}
#[test]
fn default_to_baz() {
assert(foo_if_fizz('literally anything') == 'baz', 'anything else returns baz');
}
}
This is a classic coding problem that gets us working with if
expressions to return different values based on the input. Such problems are fundamental for understanding how conditional statements work in programming.
Using if
, else if
, and else
statements, you can make your program react differently depending on the input it receives. This is crucial for creating dynamic and flexible applications. In this particular exercise, we are asked to implement a function that returns different outputs based on the value of the input parameter. This teaches us how to chain multiple conditions together and handle various scenarios in a structured manner.
if2.cairo
Errors
Compiling test(exercise_crate_unittest) exercise_crate v0.1.0 (/Users/desmo/repos/starklings/starklings-cairo1/runner-crate/Scarb.toml)
error: Unexpected return type. Expected: "core::felt252", found: "?0".
--> /Users/desmo/repos/starklings/starklings-cairo1/runner-crate/src/lib.cairo:9:45
fn foo_if_fizz(fizzish: felt252) -> felt252 {
^
⚠️ Testing of exercises/if/if2.cairo failed! Please try again. Here's the output:
The error indicates that the return type of the function is incorrect. This means our function isn’t returning the expected felt252
values.
if2.cairo
Solution
So, let’s go ahead and solve this:
fn foo_if_fizz(fizzish: felt252) -> felt252 {
if fizzish == 'fizz' {
'foo'
} else if fizzish == 'fuzz' {
'bar'
} else {
'baz'
}
}
Explanation
- If Expression:
- We use an
if
expression to check iffizzish
is equal to'fizz'
. If it is, we return'foo'
.
2. Else If Expression:
- We use an
else if
expression to check iffizzish
is equal to'fuzz'
. If it is, we return'bar'
.
3. Else Expression:
- If
fizzish
is neither'fizz'
nor'fuzz'
, we return'baz'
.
This pattern is very common in control flow, where multiple conditions need to be checked sequentially.
Conclusion
In this post, we went into the basics of using if
expressions in Cairo. We started with a simple exercise to determine the bigger of two numbers using an if
expression. Then, we moved on to a slightly more complex problem where we used if
, else if
, and else
blocks to return different values based on the input.
Understanding how to use if
expressions is crucial for controlling the flow of your programs and making decisions based on conditions. By mastering these basics, you can build more complex and dynamic applications in Cairo.
Stay tuned for more exercises with the Cairo programming language in our upcoming articles.