mod and use in Rust

Last time, we made a (very) simple parser with LALRPOP that parses Calving & Hobbes style scientific names.

It took me a little while to work out how to use Rust, Cargo, and LALRPOP to get this working, so this time we’re going to take a brief digression to talk about getting Rust code to work.

For contrast, I’m going to compare the setupu with a .csproj file, which a file that Visual Studio uses to keep track of C# projects. A .csproj file is basically a manifest. It has lines that say like “The project you’ve trying to build depends on this DLL, so go find that” and “Include this .cs file when you’re building.” When you ask Visual Studio to add a dependency or include a source file, it modifies .csproj for you.

Rust doesn’t have a .rsproj file. At first I thought that Cargo.toml would fill the same role. I was partly right, but Cargo.toml declares build steps and dependencies. But Cargo.toml doesn’t include a list of source files, and I spent a few minutes on the question of “how do you make a Rust project that has more than one file.” Everything I found googling seemed to imply that I could already do this, and wanted to do something more advanced.

Anyway, so here I am, I have three source files in my Rust executable project. Let’s just call them main.rs, point.rs and rectangle.rs. main.rs has the entry point, that is, the function that is invoked when the program is first execute. point.rs has some code for defining points on a plane, and rectangle.rs has some code for defining a rectangle on a plane.

point.rs has a struct called Point, and I remember from somewhere that the Rust compiler by default wraps stucts in a file in a module named for that file, so I try use points::Point at the top of rectangle.rs. So far so good. I want to use rectangles in my main function, so I type mod rectangle; at the beginnging of main.rs.

My project looks like this:

Running cargo build fails with this message:

src\rectangle.rs:1:5: 1:17 error: unresolved import `point::Point`. 
Maybe a missing `extern crate point`? [E0432]`

What’s going on? I checked all the obvious things. Did I misspell point? Am I in the wrong directory? The full “am I missing something silly” checklist.

Here’s what I’m missing: The difference between mod and use.

The mod rectangle; at the beginning of main.rs basically says “Hey go find a module named rectangle and compile it here. In other words, mod rectangle; is telling rustc that rectangle.rs is a file I care about.

rectangle.rs wants a type called Point, but nothing is telling rustc to include point.rs.

The answer was to include mod point; at the top of main.rs.

I was a little frustrated here. I’m missing a mod statement in main.rs, so the compiler fails with an error in rectangle.rs that’s complaining about extern create nonsense.

So, to make a long story short: use just brings names into scope. mod is used in your main fail to tell the compiler about other files you care about. This works fine:

I’m sure that someone more experienced with Rust will be able to say more about use and mod and their difference, but for now knowing that I need a mod foo statement in main.rs if I want the compiler to include foo.rs in the build is good enough. Also, knowing that if one of my files is complaining that it can’t find a type defined in another file, the probable explanation is that I failed to tell main.rs about the second file. Next time we’ll get back to building something interesting.

Also, special thanks to this StackOverflow question, which helped me understand.

Till next time, happy learning!

-Will

Scientific Names in LALRPOP

Last time, we wrote a regular expression that recognizes “scientific names” (of the Calvin & Hobbes variety). But this only worked because the simple grammar for scientific names is a regular language. If we want to do a more complicated language, or, for example, we want to have maintainable code and not be stuck in a regular expression nightmare, we’re going to need a better parser.

In this section of tutorial, I’m going to go much slower than Build Your Own Lisp goes, for a few reasons. First, I don’t know Rust nearly as well as orangeduck seems to know C, and second, I using a parser combinator in Rust is proving a bit more difficult than I had anticipated. Continue reading “Scientific Names in LALRPOP”

The Horrendous Space Kablooie

Last time, we built a simple REPL, the incredibly annoying echo. This program just echoed the user’s input back to the user. Now, I’d like to actually do something simple with the input. We’re going to need to parse the input into some sort of language. Now, languages can get pretty complicated. English, for example, is an utter nightmare to parse, because we don’t have that many rules, and we have so many symbols have multiple meanings (e.g., “I may start work for my cousin May in May.”). This makes it hard to write a simple parser for English.

Therefore, in keeping with the Calvin & Hobbes theme of the series, we’re going to write a parser for a much simpler language: “scientific names”. There’s a Calvin & Hobbes strip where Calvin opens a lemonade stand that sells “scientific names,” offering such samples as “the horrendous space kablooie” in place of the “Big Bang.” Continue reading “The Horrendous Space Kablooie”

Build Your Own Lisp (in Rust) part 2

Last time, we did a basic setup of our Rust programming environment so that we could get started. This week, we’re going to look at some sample code for a simple name calling game. My inspirations for this post are chapter 4 of Build Your Own Lisp and, of course, the Calvin & Hobbes comic strips where Calvin decides to be “The incredibly annoying human echo.” Continue reading “Build Your Own Lisp (in Rust) part 2”

Build Your Own Lisp (in Rust)

Lately I’ve been playing around with the Rust programming language a lot, and I’ve been loving it, I think mostly because I love the community. I’ve never been to a Rust meetup where I didn’t have a great time.

I’ve also started the online book Build Your Own Lisp. It teaches C by demonstrating the creation of a simple REPL for a subset of the Lisp language. Lisp is a fascinating language, and you really should read The Little Schemer when you have a chance. I’m interested in learning C, but I’m just as interested in learning Rust. Continue reading “Build Your Own Lisp (in Rust)”

Mind the Small Stuff

I love audiobooks, and one audiobook I’ve been listening to lately is The Meaning of It All by Richard Feynman. In it, Feynman points out an unusual observation that is accounted for by relativity, but not by Newtonian motion. (I think he means the difference between invariant and relativistic mass for a top spinning very rapidly.) Feynman says that a top, spinning at relativistic speeds, would be observed to weigh more than the same top at rest. This doesn’t accord with Newton’s rules, so it suggests that the rules are wrong:

It turns out that the tiny effects that turn up always require the most revolutionary modifications of ideas.

Continue reading “Mind the Small Stuff”

cURL on Windows

The environment I work in is ASP.NET, SQL Server, Active Directory, etc. We have the straight enterprisey Microsoft stack. And that works for us; it’s a well-established, well-supported way to build line of business applications. It’s easy to hire people who know the stack, it’s easy to explain the tech we’ll use to prospective clients, etc.

One of our clients recently hired another firm to build an iPhone app that interacts with our data. So we fired up a web API project, built the calls that should support the app, and went back to other work. The mobile developers found some small bugs in our API, so we had to test them out.

And that’s where I discovered an unexpected blessing of bash on Windows 10: You can just run straight shell scripts full of cURL calls without changing them.

curlAndVs

The mobile app developers had sent us some cURL scripts and said, “hey, these don’t bring back what we thought they would.” And I was able to just open up Notepad++, change the test server’s hostname to localhost:portwhatever with a find-all. Then I opened the web API project in Visual Studio, launched it, opened bash, and ran the cURL scripts. I was able to see what they saw.

It was pretty seamless. I’m not sure what I would’ve done before bash on Windows. I probably would have needed to hand-translate the cURL/bash files into something more Windows friendly, or at least copy-pasted lots of the data into Postman or something. And I would have always had the suspicion that whatever bugs I found doing that were a result of the translation process.

I think cURL is something of a lingua franca for demonstrating web APIs, at least in the Linux world. Being able to speak that language (and test internally in that language) is going to make the next web API much easier for us to build and test.

So there’s an unexpected happy use case for bash on Windows.

Till next time, happy learning!

-Will

Code is Collective Knowledge

I was recently listening to an episode of The Changelog.

I heard this quote.

Sofware is becoming mainstream … It used to be that … software engineering was kind of an afterthought … but these days its becoming more of a core competency, more and more of the core logic of the business is actually captured in the logic of code.

In episode 217, around 11:30 into the episode, the founder of Sourcegraph, Beyang Liu dropped that bit of wisdom. I’m still thinking about the implication.

This reminded me of a discussion I sometimes have: What makes software a fundamentally new thing? Why is it important? Doesn’t it still jobs? How is it different from really elaborate windup toys? (Queue angry letters from windup toy enthusiasts proving that any sufficiently complex windup toy is Turing Complete.)

Anyway, the point I like to make goes something like this: Software is the only technology that lets me write down knowledge in executable form. Someone worked out how to do square roots on a computer. Now my computer can do square roots. I don’t need to know how they work. (Of course, the abstraction may leak, in this case with floating point precision loss, but that’s beside the point.)

This executable repository of knowledge is a new thing in human history, and it adds an important, fundamental change: The knowledge and policy in a computer can be more complex than what any given human can carry between the ears at any given time. Take Google, for example. You couldn’t build a fast enough procedure outside software for retrieving all that information. Even if someone gathered enough subject matter experts, you’d be all day looking for the right expert.

And I think that’s why software is eating the world. It’s eating the world because organizations can collect their knowledge and policies in a durable, executable, maintainable form, and collect policies that are, in many ways, orders of magnitude more nuanced and faster to implement than humans ever could before.

 

What I learned from the podcast is an elevator pitch for software: Software is executable human knowledge. What an exciting thing to work on!

Till next time, happy learning!

-Will