for_each, map, and compiler warnings

Rust has a great attribute you can add to structs called must_use. It is used on the Result<T, E> enum in the standard library, which looks like this:

#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[must_use = "this `Result` may be an `Err` variant, which should be handled"]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Result<T, E> {
    /// Contains the success value
    #[stable(feature = "rust1", since = "1.0.0")]
    Ok(#[stable(feature = "rust1", since = "1.0.0")] T),

    /// Contains the error value
    #[stable(feature = "rust1", since = "1.0.0")]
    Err(#[stable(feature = "rust1", since = "1.0.0")] E),

And on std::iter::Map, it looks like this:

#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Map<I, F> { /* fields omitted */ }

So what does this attribute do? From the docs:

must_use – on structs and enums, will warn if a value of this type isn’t used or assigned to a variable. You may also include an optional message by using #[must_use = "message"] which will be given alongside the warning.

Continue reading “for_each, map, and compiler warnings”

Fixing a Simple Lifetime Error in Rust

Lifetimes are perhaps the hardest thing to understand when first approaching Rust. Today I’m going to create a lifetime error and demonstrate two strategies for fixing it. If you’re very new to rust, you may wish also to read the (beautifully titled) post Rust Lifetimes for the Unitialised first, as well as Strategies for Returning References in Rust.

To get started, we’re going to consider two Ruby implementations that are equivalent:

Continue reading “Fixing a Simple Lifetime Error in Rust”

Calculator REPL Part 4: Support bools

This is the fourth installment in my discussion of building a calculator REPL in Rust. (For convenience, here are part 1 part 2 and part 3 .) I’ve decided that I like this project a lot, and that I’m going to gradually start trying to make it into a fully-featured Scheme interpreter. (It already has way too many parentheses, after all.)

The first thing I want to do in expanding beyond a calculator REPL is have two data types. Before I just had ints; now I’m going to add bools. Continue reading “Calculator REPL Part 4: Support bools”

Investigating Performance Changes with git bisect

This week, I have been working an issue with LALRPOP. Basically, at some point there was a performance degradation on a newer version of the library. Niko Matsakis mentioned that this is likely due to failing to cache some regular expressions that we need repeatedly. I assume he’s correct, but I want to understand how this performance degradation was introduced, and I’m very new to this code base, so I’m going to try to find the change that introduced it. To find this change, I will use a tool called git bisect. Continue reading “Investigating Performance Changes with git bisect”

Calculator REPL Part 3: Evaluating the tokens

This is the third and final part of a series on building a simple calculator REPL in Rust. (You may with to read part one and part two first.)

Here we’re going to talk about the eval function, which takes an array of tokens, and either returns the result of the calculation or an error. You may have noticed that I used Polish notation, e.g., + 3 4 in this language, with the expressions delimited by parentheses. The reason for this is two-fold: First, I want to make this into a more full-featured Lisp interpreter one day, and second, for the same reason that Lisp is written in prefix notation – it makes things easy to parse. As wikipedia says:

When Polish notation is used as a syntax for mathematical expressions by programming language interpreters, it is readily parsed into abstract syntax trees and can, in fact, define a one-to-one representation for the same. Because of this, Lisp (see below) and related programming languages define their entire syntax in terms of prefix notation (and others use postfix notation).

We can think of an expression like (* (+ 2 3) (+ 1 3)) as a tree, with the division operator at the root and (+ 2 3) and (+ 1 3) as sub-trees. One major difference in the language I’ve defined from Polish mathematical notation is that I allow an arbitrary number of operands to follow each operator, which is why I need parentheses. Continue reading “Calculator REPL Part 3: Evaluating the tokens”

Calculator REPL Part 2: Tokenizing the Input

This is the second post in a series about building a calculator REPL in Rust. You may want to start with the first post. Today I’ll talk about how the tokenizer is built.

The tokenizer, basically, is a function that looks at a string and recognizes chunks that are meaningful to the program. In the calculator REPL I wrote, these are represented as an enumerated type, because they can be a delimiter, an operator, or a value. Continue reading “Calculator REPL Part 2: Tokenizing the Input”

How can I help Stabilize Things?

A friend and I are working on adding Rust support to Metaparticle.

We did a simple search for “decorators in Rust” and found this repo, which seemed promising. My friend added it, but soon found it wouldn’t build without using the nightly channel of rustc. I didn’t notice right away, because I like to experiment with Rust and have been running nightly by default for months, but my friend found this very off-putting. From his perspective, it seems like he can’t adopt Rust yet, because too many libraries require nightly, which makes it seem like the language isn’t production-ready yet. Continue reading “How can I help Stabilize Things?”

A Calculator REPL in Rust

This will be a short series on building a calculator REPL in Rust. This is a program that can evaluate expressions like (+ 3 (2 * 4)) (and get 11 in this case).

The source is all on GitHub. Also, to help people follow along, I’ve made branches that represent different steps of the process. All the branches are named like step-n-do-foo. My first code is on step-1-node-structs is where I added the tokens (which I called nodes for a minute).

The code has two main components: the tokenizer and the interpreter. Continue reading “A Calculator REPL in Rust”

Constant shoveling

Ruby has a << method used for array and string concatenation, affectionately called the “shovel operator.” It can also be used to add methods to a class, like so:

class MyClass
  class << self
    def print_foo
      puts 'foo'

# > foo

All the methods defined between class << self and end will be “self methods” on the Ruby object. (C# or Java would call them “static” methods; they belong to the class, not the instance.)

Anyway, defining constants inside the shovel operator works strangely. Continue reading “Constant shoveling”

Fun with Fixed Points

Today we’re going to have fun with fixed points. A fixed point of a function f is the value x such that f(x) = x. Not everyone function has a fixed point. For example, f(x) = x + 1 has no fixed point. But many functions do. Cosine is one such function. Today we’re going to write code that finds the fixed point of the cosine function. Continue reading “Fun with Fixed Points”