# Traits

**Definition** Traits allows unification of types under certain context.

By now you would've worked with various number types like `u16`, `i32`, `f64` etc., All of them behaves similarly to the programmer in general but each of them are represented differently in the computer.

```rust
// Assume both of the computations below are executed at run-time
let x = 5 as u64 * 100 as u64;
let y = 5 as u128 * 100 as u128;

assert_eq!(x as u128, y); // TRUE, no possible loss in conversion from u64 to u128
```

In the above code snippet, eventhough both x and y have the same value semantically, the machine code generated to compute them are different, in fact it take extra clock cycles to compute `y`.

The compiler was able to provide the programmer with a uniform semantics but handles all the messy details by itself. This was possible because of Traits in rust, and in this particular example [Mul](https://doc.rust-lang.org/std/ops/trait.Mul.html) trait is used.

## What is a Trait in rust?

A trait is simply a list of types and function definitions.

### Example

```rust
trait Foo {
    type Output; // Customizable

    fn do_something(self) -> Output;
}
```

In `do_something` function the parameter `self` refers to the variable of the type that is implementing the trait.

Checkout playground [link](https://play.rust-lang.org/?version=stable\&mode=debug\&edition=2021\&gist=5381ef684ec7ce34ba76dd75a0c41c2b) which demonstrates how to implement `Foo` trait for various types.

## Implementing Add trait for U256

In the last chapter we encountered `U256` but currently we have not defined the mechanisms to do additions like `U256 + U256`.

This can be achieved by implementing the [Add](https://doc.rust-lang.org/std/ops/trait.Add.html) trait for U256.

```rust
/// Adding U256 + U256
impl Add for U256 {
    type Output = U256;

    // self refers to U256
    fn add(self, other: U256) -> U256 {
        let (sum_x0, carry) = self.x0.overflowing_add(other.x0);
        let (sum_x1, _carry) = self.x1.overflowing_add(other.x1 + carry as u128);

        // _carry will be ignored, like it would happen for any other primitive int type

        U256 {
            x0: sum_x0,
            x1: sum_x1,
        }
    }
}
```

We can see this in action with the following example [Rust playground:](https://play.rust-lang.org/?version=stable\&mode=debug\&edition=2021\&gist=149afb833a39b6d7ad3aeb4fd30ddbf7)

```rust
fn main() {
    let num1 = U256 {
        x0: 2_u128.pow(65),
        x1: 2_u128.pow(68),
    };
    
    let num2 = U256 {
        x0: 2_u128.pow(68),
        x1: 2_u128.pow(127),
    };
    
    println!("sum: {:?}", num1 + num2);
}
```

What if we want to do `U256 + u128`?

```rust
/// Adding U256 + u128
impl Add<u128> for U256 {
    type Output = U256;

    // self refers to U256
    fn add(self, other: u128) -> U256 {
        let (sum_x0, carry) = self.x0.overflowing_add(other);
        let sum_x1 = self.x1 + carry as u128;

        U256 {
            x0: sum_x0,
            x1: sum_x1,
        }
    }
}
```

How about `u128 + u256`?

```rust
/// We are implementing a trait for an already existing type `u128`
impl Add<U256> for u128 {
    type Output = U256;

    // self refers to u128
    fn add(self, other: U256) -> U256 {
        let (sum_x0, carry) = self.overflowing_add(other.x0);
        let sum_x1 = other.x1 + carry as u128;

        U256 {
            x0: sum_x0,
            x1: sum_x1,
        }
    }
}
```

All this was possible because the `Add` trait was defined as follows,

````rust
trait Add<Rhs = Self> {
    type Output;

    /// Performs the `+` operation.
    ///
    /// # Example
    ///
    /// ```
    /// assert_eq!(12 + 1, 13);
    /// ```
    fn add(self, rhs: Rhs) -> Self::Output;
}
````

That `Rhs` term in the definition allows adding numbers of different types together.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bitcoin-dev-project.gitbook.io/rust-for-bitcoiners/curriculum/module_5/1_traits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
