Delete things faster in Visual Studio with these two weird tricks

Here are two nifty keyboard shortcuts in Visual Studio:

Cut whole line (Ctrl-L): This will cut/delete the whole line and send it to the clipboard. This is useful in two situations.

First, it let’s you remove a whole line in a single action reliably.

For white space lines, depending on the line configuration, using delete or backspace might necessitate more than a single key stroke per line. Ctrl-l always does it in one action.

For non white-space lines Ctrl-l prevents you from having to select the whole line and then deleting it, saving you again one action. Every action saved counts.

The second situation is when you want to select a whole line, cut it, move and then paste it. With Ctrl-l you can reduce this from 4 actions to 3.

When using Ctrl-l if you overwrite your current clipboard you can do a Ctrl-Shift-v to cycle through your clipboard history.

Delete next word (Ctrl-Del): This is a universal shortcut that works for many programs but I have included it here since I learned about it recently. This will delete the whole word in front of you instead of just a single character.

Go and Rust, not Go versus Rust

In the last few months I have been playing around with Rust, Mozilla’s new systems programming language. I worked on small personal projects and submitted a few pull requests (mostly refactoring) to Servo, a Mozilla research project to build a browser engine in Rust.

Another language that often gets mentioned alongside Rust is Go, also known as golang since Go is hard to search for (so is Rust to a lesser extent).

Both languages are compiled, static, strongly typed and have pointers. Both are at a lower level than popular languages like Ruby or Python. They both have been called systems programming languages though this description fits Rust more than it does Go.

I have often seen people asking which one is better or which language should be chosen over the other.

Because of this appearance of opposition and the fact that I already knew Rust, I decided to try Go and see if and how the languages were similar.

Initial impressions of Go

My initial impressions of Go are very good. The language is easy to learn and is nicely designed. If you know any of the following languages; C, C++, Java or C# you’ll be able to jump right in after reading a short tutorial.

The tooling is great, particularly gofmt which formats your code automatically according to the Go style guidelines. I’m using a Vim plugin for Go which calls gofmt each time I save. This process is very nice once you start using it.

One downside is how the package/module/directory structure needs to be set up. It’s not clear when your first start how everything must be structured. It’s important to read this part of the documentation before starting your first project. Otherwise you’ll end up like I did, needing to rearrange the file structure of my git repository because I didn’t follow the proper structure.

Even now that I know the correct file structure I still find it a bit odd and constraining. It’s definitely not one of the language’s strong point.

Comparing Go and Rust

While both languages may seem to serve a similar purpose at first, upon using both they are very different. I have seen many people asking which one is better but the answer depends on what you are building and what you are looking for in a language.

Go is easier to learn. There is deliberately less features in the language and you can hit the ground running after a short tutorial.

Programming is also easier. I spent more time solving problems with my algorithms than I did wrestling with the language.

Go is also garbage collected. That means less to worry about as you don’t have to manage memory. On the other hand, for some applications a garbage collector can be a big downside and it does mean less control.

Rust on the other hand is a more complex language. There is a lot of interesting things in the language and if you’re a language nerd you will love a lot of it’s features. This makes learning and mastering the language harder than Go, but it also makes for a powerful language with a lot of expressive concepts like meta programming through syntax extensions.

I have spent a lot of time battling with the Rust compiler. Compared to Go this means I spend more time solving problems related to the language itself rather than to the algorithms I am writing.

One thing I must say is that when a program finally does compile, there are much less run time errors than in any compiled language I have tried before.

The language isn’t garbage collected and also allows for more control like choosing if memory is allocated on the stack or the heap for example.

Conclusion

Go is a general purpose utilitarian language that’s suitable, amongst other things, for building tools and app back-ends.

Rust is a “PHD smarts” language that’s better suited for systems level stuff and programs where memory management and performance is important.

Go will probably become a go to language when I need a compiled portable low-level language. It’s more modern than C and it’s simpler than C#.

Rust on the other hand is more specialized and is a better choice when doing systems level programs, when garbage collection isn’t an option, or when performance is critical.

Both are wonderful languages and I intend to use them both going forward.

Rust: Traits

Rust 0.12

Traits in Rust are similar to interfaces in a language like C#. The definition of a trait is that they are a collection of concrete methods that are used to extend an existing class using a name resolution policy to prevent multiple inheritance conflicts.

In Rust, traits are divided into a trait block which defines methods and an implementation block for each type which implements the trait. You can see the combination of these two components as the trait. This division allows us to implement methods at two level; at the general trait level and at the type level. When defining a default definition at the trait level it is not necessary to explicitly implement said method at the type level unless we wish to override the default with a type specific implementation.

Unimplemented method definitions must be implemented by a type which implements the trait or this will raise a compile time error.

struct Counter {
    hits: u32,
}

trait Logger {
    fn log(&self, message: String);

    fn write_state_to_log(&self);

    // Provide default method implementation
    fn line_break(&self) {
        println!("");
    }
}

impl Logger for Counter {
    fn log(&self, message: String) {
        println!("{}", message);
    }

    // if we were to omit one of these methods we would get 
    // a compile time error
    fn write_state_to_log(&self) {
        println!("{}", self.hits);
    }

    // no implementation for line_break
}

In this previous example we first define a struct called Counter and a trait called Logger. The third method contains an implementation while the first two are only signatures.

We can then use it as such:

fn main() {
    let counter = Counter { hits: 0 };
    counter.line_break();
    counter.log("Test message".to_string());
}

We can also make a method receive a parameter of type trait rather than a concrete type. This allows us to work with abstractions in our functions.

fn receive_trait<L: Logger>(logger: L) {
    logger.write_state_to_log();
}

fn main() {
    let counter = Counter { hits: 0 };
    receive_trait(counter);
}

In the previous example we create a function with a generic type L which must implement the Logger trait.

Implementing multiple traits

A type can implement multiple traits. Let’s add another one:

trait OutputsToConsole {
    fn output(&self, message: String);
}

We can implement it and call it like so:

impl OutputsToConsole for Counter {
    fn output(&self, message: String) {
        println!("{}", message);
    }
}

fn main() {
    let counter = Counter { hits: 0 };
    counter.line_break();
    counter.log("Test message".to_string());
    counter.output("Test output".to_string());
}

But what happens if two traits have a method with the same signature and we implement both traits for the same type? How will Rust know what method to call?

Let’s find out:

// code for Logger omitted

trait OutputsToConsole {
    fn output(&self, message: String);

    // new method with the same signature as
    // a method in Logger
    fn line_break(&self);
}

impl OutputsToConsole for Counter {
    fn output(&self, message: String) {
        println!("{}", message);
    }

    fn line_break(&self) {
        println!("");
    }
}

fn main() {
    let counter = Counter { hits: 0 };
    counter.line_break();
}

Compiling this piece of code produces the following output:

main.rs:58:5: 58:25 error: multiple applicable methods in scope [E0034]
main.rs:58 counter.line_break();
^~~~~~~~~~~~~~~~~~~~
main.rs:15:5: 15:25 note: candidate #1 is `Logger::line_break`
main.rs:15 fn line_break(&self) {
^~~~~~~~~~~~~~~~~~~~
main.rs:43:5: 45:6 note: candidate #2 is `Counter.OutputsToConsole::line_break`
main.rs:43 fn line_break(&self) {
main.rs:44 println!(“”);
main.rs:45 }
error: aborting due to previous error

Non-surprisingly, the Rust compiler gives out an error. The way to call the proper method isn’t so clear though. There is a proposed syntax that would allow to define the correct method to call but it hasn’t been implemented in the language as of this writing (remember Rust is pre-1.0).

In the meantime, one way to do it would be to have a function which receives a generic type which is constrained to the trait we want and call the method from this constrained generic parameter.

Returning a trait

Having a function return a trait is not something that is as easy as I would have expected. You can’t simply define a function as such:

fn return_trait(&counter: Counter) -> Logger {
    // doesn't work
}

To do this we need some other concepts which I will cover in another post.
For now we still have a basic idea of how to use traits.