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

Write the "Smart Pointers" concept #327

Merged
merged 3 commits into from
Dec 30, 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
2 changes: 1 addition & 1 deletion concepts/control-flow/.meta/config.json
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"]
}
2 changes: 1 addition & 1 deletion concepts/control-flow/links.json
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"
}
]
6 changes: 2 additions & 4 deletions concepts/smart-pointers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"blurb": "<todo>",
"authors": [
"<your_gh_username>"
],
"blurb": "Smart pointers in Cairo are special data structures that manage memory safely by ensuring that memory is accessed in a controlled way.",
"authors": ["0xNeshi"],
"contributors": []
}
126 changes: 126 additions & 0 deletions concepts/smart-pointers/about.md
Original file line number Diff line number Diff line change
@@ -1 +1,127 @@
# Smart Pointers

Smart pointers in Cairo are a powerful tool that provide safe and efficient management of memory.

A smart pointer is a data structure that acts like a regular pointer, but with added safety features to avoid common memory management issues like dereferencing null pointers or accessing uninitialized memory.

## What is a Smart Pointer?

In general, a pointer is a variable that stores a memory address, typically pointing to a value stored at that location.

However, raw pointers can be dangerous: if the pointer doesn't point to valid memory or is incorrectly dereferenced, it can lead to crashes or unpredictable behavior.

Smart pointers solve this issue by enforcing strict rules on memory management, ensuring that memory is accessed in a safe and controlled manner.

Cairo, like many modern languages such as Rust, uses smart pointers to prevent unsafe memory access.

A smart pointer in Cairo not only stores a memory address but also tracks ownership and ensures memory safety.

## Types of Smart Pointers in Cairo

Cairo provides several types of smart pointers, including `Box<T>` and `Nullable<T>`, each serving a different purpose.

Let's take a closer look at how these types work and when you might use them.

### `Box<T>`

The `Box<T>` type is the principal smart pointer in Cairo.

It allows you to store data in a special memory segment called the "boxed segment." A `Box<T>` is a pointer that points to this segment, and when you create a box, you allocate space for the data in this segment.

Boxes are ideal in situations where:

- You need to store a value of a type whose size cannot be determined at compile time.
- You have a large amount of data and want to transfer ownership without copying it.

By using a box, you can store large data structures more efficiently.

When passing a `Box<T>` to a function, only the pointer is passed, avoiding the need to copy the entire data, which improves performance, especially with large structures.

### `Nullable<T>`

The `Nullable<T>` type is another important smart pointer in Cairo.

It can either point to a valid value of type `T` or be `null` if there is no value.

This type is useful in cases where you need to store values that may not always exist, such as in a dictionary that can contain optional elements.

In Cairo, `Nullable<T>` is typically used in dictionaries to handle cases where no default value can be applied.

It allows you to store values conditionally, making it easier to handle the absence of data safely.

## Memory Safety with Smart Pointers

One of the primary advantages of using smart pointers is that they help ensure memory safety.

By managing ownership and access rules, Cairo prevents common issues such as dereferencing null or dangling pointers.

Smart pointers track when data is no longer needed and can automatically deallocate memory when it goes out of scope, reducing the risk of memory leaks.

### Example: Using a `Box<T>` for Recursive Types

A common challenge in many programming languages is handling recursive types.

Recursive types refer to types that contain references to themselves.

Without proper memory management, defining a recursive type can lead to issues such as infinite recursion.

In Cairo, `Box<T>` makes it possible to define recursive types safely.

For instance, you can use `Box<T>` to implement a binary tree, where each node contains a reference to another node.

By storing references in boxes, Cairo ensures that memory usage is finite, and the compiler can determine the required memory size for the structure.

```rust
use core::box::{BoxTrait};

#[derive(Copy, Drop)]
enum BinaryTree {
Leaf: u32,
Node: (u32, Box<BinaryTree>, Box<BinaryTree>),
}

fn main() {
let leaf1 = BinaryTree::Leaf(1);
let leaf2 = BinaryTree::Leaf(2);
let node = BinaryTree::Node((3, BoxTrait::new(leaf1), BoxTrait::new(leaf2)));
println!("{:?}", node);
}
```

### Performance Benefits of Smart Pointers

Smart pointers also improve the performance of your programs.

When you use `Box<T>`, only the pointer to the data is passed around, instead of copying the entire data structure.

This is especially useful when dealing with large datasets, as it significantly reduces the overhead of memory operations.

In the following example, the data is passed by reference using a `Box<T>` to avoid the cost of copying the entire structure:

```rust
#[derive(Drop)]
struct Cart {
paid: bool,
items: u256,
buyer: ByteArray,
}

fn pass_data(cart: Cart) {
println!("{} is shopping today and bought {} items", cart.buyer, cart.items);
}

fn pass_pointer(cart: Box<Cart>) {
let cart = cart.unbox();
println!("{} is shopping today and bought {} items", cart.buyer, cart.items);
}

fn main() {
let new_cart = Cart { paid: true, items: 1, buyer: "John" };
pass_data(new_cart);

let new_box = BoxTrait::new(Cart { paid: false, items: 3, buyer: "Jane" });
pass_pointer(new_box);
}
```

In this example, `pass_pointer` takes a `Box<Cart>` instead of a `Cart`, reducing the amount of memory copied during the function call.
4 changes: 4 additions & 0 deletions concepts/smart-pointers/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Introduction

Smart pointers in Cairo are special data structures that manage memory safely by ensuring that memory is accessed in a controlled way.
They act like regular pointers but include additional features like ownership rules and metadata to prevent common errors, such as dereferencing uninitialized memory.
This makes them essential for working with complex data structures and improving program safety and performance.
11 changes: 10 additions & 1 deletion concepts/smart-pointers/links.json
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
[]
[
{
"url": "https://book.cairo-lang.org/ch11-02-smart-pointers.html",
"description": "Smart Pointers in The Cairo Book"
},
{
"url": "https://book.cairo-lang.org/ch03-02-dictionaries.html#dictionaries-of-types-not-supported-natively",
"description": "Nullable<T> Use Case with Dictionaries"
}
]
Loading