Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement associated items concept #330

Merged
merged 2 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions concepts/associated-items/.meta/config.json
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": []
}
127 changes: 127 additions & 0 deletions concepts/associated-items/about.md
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.
5 changes: 5 additions & 0 deletions concepts/associated-items/introduction.md
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.
6 changes: 6 additions & 0 deletions concepts/associated-items/links.json
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"
}
]
5 changes: 5 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,11 @@
"slug": "functions",
"name": "Functions"
},
{
"uuid": "56b0dcb7-c9c3-4323-b297-873002b713d3",
"slug": "associated-items",
"name": "Associated Items"
},
{
"uuid": "9be30113-b4fe-4cdd-9894-9afd593f2a90",
"slug": "generics",
Expand Down
Loading