blog.dbrgn.ch

Rust: Implementing Methods on Builtins

written on Monday, May 25, 2015 by

Some days ago I released a blogpost about programming a perceptron in Rust. The post was quite popular, and it lead to @mhutter providing a pull request with a Ruby implementation of a perceptron.

When looking at the source code, I noticed how elegantly you can extend the native types in Ruby with your own methods:

> class Numeric
>   def heaviside
>     self < 0 ? 0 : 1
>   end
> end
=> nil
> 1.337.heaviside
=> 1
> -1.337.heaviside
=> 0

Turns out, in Rust you can do the same thing using Traits!

trait Heaviside {
    fn heaviside(&self) -> i8;
}

impl Heaviside for f64 {
    fn heaviside(&self) -> i8 {
        (*self >= 0.0) as i8
    }
}

fn main() {
    println!("heaviside(1.337) = {}", 1.337.heaviside());
    println!("heaviside(-1.337) = {}", (-1.337).heaviside());
}

Output:

heaviside(1.337) = 1
heaviside(-1.337) = 0

C# can also do something like that with its extension methods. The difference between Ruby, C# and Rust is that in Rust you explicitly need to use the trait definition before being able to use the implementation. That prevents 3rd party code from intentionally or accidentally "polluting" your namespace.

I updated the code on Github with the trait based implementation. I wasn't able to do the same for the dot product, because I got stuck in the Rust generics system... If you know how to do it, I'd be interested in learning :)

If you have comments, feel free to leave them below, on Hacker News or on /r/rust.

This entry was tagged ruby and rust