-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'exercism:main' into main
- Loading branch information
Showing
48 changed files
with
1,281 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"blurb": "Associated implementations in Cairo allow you to enforce relationships between types and their trait implementations, ensuring type safety and consistency.", | ||
"authors": ["0xNeshi"], | ||
"contributors": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Associated Items | ||
|
||
Associated items are items declared in traits or defined in implementations. | ||
|
||
These include: | ||
|
||
- **Associated functions** (like methods) | ||
- **Associated types** | ||
- **Associated constants** | ||
- **Associated implementations** | ||
|
||
They group logically related functionality with a type. | ||
|
||
For example, the `is_some` method in `Option` is intrinsically tied to `Option`. | ||
|
||
## Associated Types | ||
|
||
Associated types define placeholders for types in traits, which are specified by implementors. | ||
|
||
This keeps trait definitions flexible and concise. | ||
|
||
Example: | ||
|
||
```rust | ||
trait Pack<T> { | ||
type Result; | ||
|
||
fn pack(self: T, other: T) -> Self::Result; | ||
} | ||
|
||
impl PackU32Impl of Pack<u32> { | ||
type Result = u64; | ||
|
||
fn pack(self: u32, other: u32) -> Self::Result { | ||
let shift: u64 = 0x100000000; // 2^32 | ||
self.into() * shift + other.into() | ||
} | ||
} | ||
``` | ||
|
||
Here, `Result` is an associated type determined by each implementation. | ||
|
||
A function using this trait doesn't need to specify extra generics: | ||
|
||
```rust | ||
fn combine<T, impl PackImpl: Pack<T>>(a: T, b: T) -> PackImpl::Result { | ||
a.pack(b) | ||
} | ||
``` | ||
|
||
## Associated Constants | ||
|
||
Associated constants are fixed values tied to a type and defined in a trait or its implementation. | ||
|
||
Example: | ||
|
||
```rust | ||
trait Shape<T> { | ||
const SIDES: u32; | ||
fn describe() -> ByteArray; | ||
} | ||
|
||
struct Triangle {} | ||
|
||
impl TriangleShape of Shape<Triangle> { | ||
const SIDES: u32 = 3; | ||
fn describe() -> ByteArray { | ||
"I am a triangle." | ||
} | ||
} | ||
|
||
struct Square {} | ||
|
||
impl SquareShape of Shape<Square> { | ||
const SIDES: u32 = 4; | ||
fn describe() -> ByteArray { | ||
"I am a square." | ||
} | ||
} | ||
``` | ||
|
||
This ties constants like `SIDES` to `Shape` instead of hardcoding them elsewhere. | ||
|
||
## Associated Implementations | ||
|
||
Associated implementations enforce relationships between types and traits. | ||
|
||
For example: | ||
|
||
```rust | ||
// Collection type that contains a simple array | ||
#[derive(Drop)] | ||
pub struct ArrayIter<T> { | ||
array: Array<T>, | ||
} | ||
|
||
// T is the collection type | ||
pub trait Iterator<T> { | ||
type Item; | ||
fn next(ref self: T) -> Option<Self::Item>; | ||
} | ||
|
||
impl ArrayIterator<T> of Iterator<ArrayIter<T>> { | ||
type Item = T; | ||
fn next(ref self: ArrayIter<T>) -> Option<T> { | ||
self.array.pop_front() | ||
} | ||
} | ||
|
||
/// Turns a collection of values into an iterator | ||
pub trait IntoIterator<T> { | ||
/// The iterator type that will be created | ||
type IntoIter; | ||
impl Iterator: Iterator<Self::IntoIter>; | ||
|
||
fn into_iter(self: T) -> Self::IntoIter; | ||
} | ||
|
||
impl ArrayIntoIterator<T> of IntoIterator<Array<T>> { | ||
type IntoIter = ArrayIter<T>; | ||
fn into_iter(self: Array<T>) -> Self::IntoIter { | ||
ArrayIter { array: self } | ||
} | ||
} | ||
``` | ||
|
||
This guarantees `Array` can always be converted into an iterator (`IntoIter`), ensuring consistency and type safety. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Introduction | ||
|
||
Associated implementations in Cairo allow you to enforce relationships between types and their trait implementations, ensuring type safety and consistency. | ||
By specifying that an associated type must implement a particular trait, you create a strong, compile-time guarantee that the necessary functionality is provided. | ||
This feature is especially useful for building modular, extensible, and type-safe abstractions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[ | ||
{ | ||
"url": "https://book.cairo-lang.org/ch12-10-associated-items.html", | ||
"description": "Associated Items in the Cairo book" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"blurb": "Control flow in Cairo uses `if` expressions to conditionally execute code and loops to run code repeatedly.", | ||
"blurb": "Control flow in Cairo uses `if` expressions to conditionally execute code, and loops to run code repeatedly.", | ||
"authors": ["Falilah"], | ||
"contributors": ["0xNeshi"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[ | ||
{ | ||
"url": "https://book.cairo-lang.org/ch02-05-control-flow.html", | ||
"description": "Control flow concept in cairo book" | ||
"description": "Control Flow Concept in The Cairo Book" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
{ | ||
"blurb": "<todo>", | ||
"authors": [ | ||
"<your_gh_username>" | ||
], | ||
"blurb": "In Cairo, methods and associated functions allow you to organize functionality around specific types, making your code modular and intuitive.", | ||
"authors": ["0xNeshi"], | ||
"contributors": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,61 @@ | ||
# Method Syntax | ||
|
||
Methods in Cairo are similar to functions, but they are tied to a specific type through traits. | ||
|
||
Their first parameter is always `self`, representing the instance on which the method is called. | ||
|
||
While Cairo doesn’t allow defining methods directly on a type, you can achieve the same functionality by defining a trait and implementing it for the type. | ||
|
||
Here’s an example of defining a method on a `Rectangle` type using a trait: | ||
|
||
```rust | ||
#[derive(Copy, Drop)] | ||
struct Rectangle { | ||
width: u64, | ||
height: u64, | ||
} | ||
|
||
#[generate_trait] | ||
impl RectangleImpl of RectangleTrait { | ||
fn area(self: @Rectangle) -> u64 { | ||
(*self.width) * (*self.height) | ||
} | ||
} | ||
|
||
fn main() { | ||
let rect = Rectangle { width: 30, height: 50 }; | ||
println!("Area is {}", rect.area()); | ||
} | ||
``` | ||
|
||
In the example above, the `area` method calculates the area of a rectangle. | ||
|
||
Using the `#[generate_trait]` attribute simplifies the process by automatically creating the required trait for you. | ||
|
||
This makes your code cleaner while still allowing methods to be associated with specific types. | ||
|
||
## Associated Functions | ||
|
||
Associated functions are similar to methods but don’t operate on an instance of a type—they don’t take `self` as a parameter. | ||
|
||
These functions are often used as constructors or utility functions tied to the type. | ||
|
||
```rust | ||
#[generate_trait] | ||
impl RectangleImpl of RectangleTrait { | ||
fn square(size: u64) -> Rectangle { | ||
Rectangle { width: size, height: size } | ||
} | ||
} | ||
|
||
fn main() { | ||
let square = RectangleTrait::square(10); | ||
println!("Square dimensions: {}x{}", square.width, square.height); | ||
} | ||
``` | ||
|
||
Associated functions, like `Rectangle::square`, use the `::` syntax and are namespaced to the type. | ||
|
||
They make it easy to create or work with instances without requiring an existing object. | ||
|
||
By organizing related functionality into traits and implementations, Cairo enables clean, modular, and extensible code structures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
# Introduction | ||
|
||
In Cairo, methods and associated functions allow you to organize functionality around specific types, making your code modular and intuitive. | ||
Methods operate on an instance of a type and always include `self` as their first parameter, while associated functions, such as constructors, don’t require an instance. | ||
Together, they enable a clean and structured approach to defining behavior and utilities for your types. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
[] | ||
[ | ||
{ | ||
"url": "https://book.cairo-lang.org/ch05-03-method-syntax.html", | ||
"description": "Method Syntax in The Cairo Book" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
{ | ||
"blurb": "<todo>", | ||
"authors": [ | ||
"<your_gh_username>" | ||
], | ||
"blurb": "Operator overloading in Cairo enables you to redefine standard operators like `+` and `-` for custom types by implementing specific traits.", | ||
"authors": ["0xNeshi"], | ||
"contributors": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,50 @@ | ||
# Operator Overloading | ||
|
||
Operator overloading is a feature in some programming languages that allows the redefinition of standard operators, such as addition (`+`), subtraction (`-`), multiplication (`*`), and division (`/`), to work with user-defined types. | ||
|
||
This can make the syntax of the code more intuitive, by enabling operations on user-defined types to be expressed in the same way as operations on primitive types. | ||
|
||
In Cairo, operator overloading is achieved through the implementation of specific traits. | ||
|
||
Each operator has an associated trait, and overloading that operator involves providing an implementation of that trait for a custom type. | ||
However, it's essential to use operator overloading judiciously. | ||
|
||
Misuse can lead to confusion, making the code more difficult to maintain, for example when there is no semantic meaning to the operator being overloaded. | ||
|
||
Consider an example where two `Potions` need to be combined. | ||
|
||
`Potions` have two data fields, mana and health. | ||
|
||
Combining two `Potions` should add their respective fields. | ||
|
||
```rust | ||
struct Potion { | ||
health: felt252, | ||
mana: felt252, | ||
} | ||
|
||
impl PotionAdd of Add<Potion> { | ||
fn add(lhs: Potion, rhs: Potion) -> Potion { | ||
Potion { health: lhs.health + rhs.health, mana: lhs.mana + rhs.mana } | ||
} | ||
} | ||
|
||
fn main() { | ||
let health_potion: Potion = Potion { health: 100, mana: 0 }; | ||
let mana_potion: Potion = Potion { health: 0, mana: 100 }; | ||
let super_potion: Potion = health_potion + mana_potion; | ||
// Both potions were combined with the `+` operator. | ||
assert(super_potion.health == 100, ''); | ||
assert(super_potion.mana == 100, ''); | ||
} | ||
``` | ||
|
||
In the code above, we're implementing the `Add` trait for the `Potion` type. | ||
|
||
The add function takes two arguments: `lhs` and `rhs` (left and right-hand side). | ||
|
||
The function body returns a new `Potion` instance, its field values being a combination of `lhs` and `rhs`. | ||
|
||
As illustrated in the example, overloading an operator requires specification of the concrete type being overloaded. | ||
|
||
The overloaded generic trait is `Add<T>`, and we define a concrete implementation for the type `Potion` with `Add<Potion>`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
# Introduction | ||
|
||
Operator overloading in Cairo enables you to redefine standard operators like `+` and `-` for custom types by implementing specific traits. | ||
This allows user-defined types to interact intuitively with operators, similar to primitive types. | ||
When used thoughtfully, operator overloading enhances code readability and expressiveness while preserving clarity and intent. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,10 @@ | ||
[] | ||
[ | ||
{ | ||
"url": "https://book.cairo-lang.org/ch12-03-operator-overloading.html", | ||
"description": "Operator Overloading in The Cairo Book" | ||
}, | ||
{ | ||
"url": "https://book.cairo-lang.org/appendix-02-operators-and-symbols.html", | ||
"description": "Operators and Symbols in The Cairo Book" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
{ | ||
"blurb": "<todo>", | ||
"blurb": "Printing in Cairo allows you to display messages, debug information, or formatted values during program execution.", | ||
"authors": [ | ||
"<your_gh_username>" | ||
"0xNeshi" | ||
], | ||
"contributors": [] | ||
} |
Oops, something went wrong.