Rust
Programming Language
Links

Rust is what C++ should have been,
had it not escaped Bell Labs prematurely

Updated: 10 November 2018

Contents:

Learn Rust

Of course, begin with resources on the Rust programming language website: https://rust-lang.org/

There is The Rust Language Reference and The Rust Language Grammar. Both continue as works-in-progress 3 years after 1.0-stable (released May 2015) with pull-requests or filing issues welcomed: reference or grammar.md, respectively.

Reference to the Rust Standard Library, run:

rustup doc --std

Similarly, for the de facto tutorial, TRPL (2nd Ed), run:

rustup doc --book

While there’s much to appreciate and respect about it, its style may seem verbose for some tastes.

Critique:

In technical writing, conventional practice introduces new material by directly stating the most novel concepts for the audience first, followed by elaboration and examples.

By contrast, TRPL 1st and 2nd Edition use a narrative flow typical of many bloggers, where there’s a build-up of anticipation followed by a reveal of substance. The single most useful sentence– or sometime phrase– within each section stating the actual idiom often gets lost within their storytelling style.

Bridging such differences: they would do well by highlighting language idioms in a sidebar (or just a bold font, inline) for each subsection.

This would preserve integrity of their writing style while accommodating both a more diverse audience and readers returning to find just the one tidbit of interest.

For those who grew up with K&R C lovingly within reach, there is another book a bit closer, in that it states an idiom first and then its companion example or explanation:

Highly recommended book: Programming Rust

(No affiliation with the authors, publisher or sellers)

As of mid-2018:

Blandy’s & Orendorff’s Programming Rust is the closest to a K&R C book for the Rust programming language so far.

It’s concise. It begins with the key concepts. It’s organized suitably for the pragmatic software developer with a dev-ops mindset.

For working through actual code, the canonical book for that is: Rust by Example (RBE).

Discuss on Discord, or for immediate help, visit #rust-beginners on IRC. (That link will open a chat session in your web browser, the main caveat being that as an anonymous user, you cannot mute join/leave messages.)

For those looking for something similar to “Long Term Release” (LTS) cycles, you might want 2018 Edition coming end of October 2018. (Until then, 2015 Edition is still current yet conventionally known as “stable” release as opposed to “nightly”.)

Stay Current

This Week In Rust
Follow Rust programming language and community updates. Reading just this one is likely enough for most people, as they aggregate all of the other major resources.

Official blog
Consider reading from the run up to v1.0-stable, because tracking each update or new feature makes it cognitively easier to holistically comprehend the current version.

Announcements on The Rust Programming Language Forum

Track possible/pending features within The Unstable Book, but note that many items in there may never reach stable. Also, remember to annotate any code using these features with: #![feature(foo_feature)].

Likely to be covered on one of the above websites when it’s news, but complete collection of confirmed vulnerable exploits: RustSec advisory-db

Attend Rust Conf or Rust Belt Rust. Follow conf activity via Twitter #rustconf or IRC #rustconf.

Overcome & Persevere

Certain language features are challenging even for those who may believe they’ve grasped the core concepts.

Here are some resources found to be helpful.

Beware of silent integer overflows:
Instead of operators like a + b * c, use methods like .checked_add(). For instance, let mut x:u8=255; x+=100; produces difference behaviour when compiled via cargo build with and without --release flag. It will panic without the flag, and silently overflow/wrap-around with the release flag. This is because the default case suits the fast path for low-level hardware. There is virtually no additional overhead for these methods, when examining the generated Assembly language code.
Alternatively, use a BigNum library such as one built upon GNU Multiple Precision (GMP) like gmp-mpfr-sys.

Introduction to the mindset used by Rust:
Rust Means Never Having to Close a Socket from pre-1.0 Rust (Oct 2014) yet still relevant in mid-2018 for concepts explained.

Be sure to also read at least the introductory chapters of The Rustonomicon, even if you have no intention of ever using unsafe code. Explanations given there provide a more diverse perspective on ownership, borrowing, lifetimes, variance (Vlad’s answer may help explain concepts behind the jargon), drop check, etc.

Selection of forum posts, such as from Stack Overflow and Reddit:

A catalogue of Rust design patterns
Even for those coming from one of the Lisp languages/dialects and agree with Rich Hickey that patterns mean you’ve “run out of language,” this list is still quite valuable. (And yes, Rust has robust Macros that accommodate many of the use cases for which Common Lisp macros are actually used.)

Podcasts:

Futures, async/await

TL;DR: use Tokio for real use cases.

New language features for futures via async and await keywords improve almost daily, but play with the bleeding edge at peril to your own sanity, unless as committed as a core Rust developer on this front.

Achieve high concurrency with Rust using far more workers than total number of OS heavyweight threads or physical CPU cores.

Rust accommodates Futures without additional runtime overhead (unlike “green threads”).

See std::future, or search for std::future within docs matching your installed toolchain by navigating web browser to local URL after running:
echo file://$(rustup doc --path --std | sed 's/stable-/nightly-/')

Be aware of key differences:

In the docs as of 0.3.0-alpha2, “Task” is now defined as Rust’s term for lightweight thread.

Implementation of RFC 2394 for async_await missed the cut-off for Rust Edition 2018, but having this feature land in stable during 2019 seems reasonable. Track progress of async/await as language features; i.e., using language keywords rather than attribute.

For up-to-the-minute status, check releases on GitHub to determine the newest version, and read #wg-net-async on Discord.

Sample Code:

Notable points, as discussed within explicit future construction, implicit await from Rust internals doc and elsewhere:

  1. First, construct a future such as by calling an #[async] fn, a closure, #[async] for ... {...} statement, or async_block! {...} block
  2. With Nightly as of 2018-09-02, use of #[async] attributes may be replaced with async keyword
  3. Understand that the async keyword before fn is just syntactic sugar for fn () -> impl Future, or you can use async before a block for more immediate use.
  4. None of the async function body runs until explicitly invoked currently using core.run(future).unwrap() where future is bound to results from one of the preceding expressions with async keyword or attribute:
  5. Eventually this may use the await keyword– but not yet!
  6. As of early October 2018, syntax involving “await” semantics are still a actively discussed, so expect to use a macro rather than keyword there for the time being

WASM

WebAssembly:

Start your project by forking this template and work within a branch there, so you can rebase as the template improves. (Note: may be renamed to rust_webpack_template.)

Begin by cloning their repo, renaming it, and creating a local branch. Run:

git clone https://github.com/rustwasm/rust_wasm_template.git
cd rust_wasm_template/
git checkout -b foo-app

Periodically, rebase to benefit from upstream fixes and enhancements. Within rust_wasm_template subdirectory, run:

git checkout master
git pull origin master
git checkout foo-app
git rebase -i master

(Note: git rebase -i master is not to be confused with something like git pull --rebase origin feature/JIRA-000_foo when collaborating on the same branch with a colleage.)

Then, when finishing your app, move it into your own repo. From parent directory containing rust_wasm_template, run:

rsync -a --exclude=.git --exclude=target  rust_wasm_template/  foo-app/
cd foo-app/
git init && git add --all .   # Only for the first iteration
git add -u .                  # For all iterations after the first
cargo clean
cargo run
git commit -m ’Create app from template’

Although this flow has many steps, it lets you regularly rebase from upstream for their new enhancements before adding your own to your app.

See also:

Interacting With Other Languages

Rust calling other languages:

Rust embedded into other languages:

Configure Emacs for Rust

For long-time users of Emacs, there’s a better way to load & configure packages. (Yes, that’s right, it’s actually changed since the 1980’s– who would have thought?)

This requires:

  1. Emacs package system
  2. use-package

For your ~/.emacs file or equivalent:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/"))
(setq package-archive-priorities '(("melpa" . 10) ("gnu" . 9))
      package-enable-at-startup nil
      use-package-always-ensure t)
(package-initialize)
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(eval-when-compile
  (require 'use-package)
  (use-package cl))

The Emacs implementation of the Language Server Protocol provides the very popular and useful feature from Visual Studio, which overlays relevant compiler messages and hints directly with the offending code.

See also eglot, an alternative and lighter LSP implementation than lsp-mode but requires Emacs-26. (e.g., Ubuntu 18.04 ships with Emacs-25.2.)

(use-package lsp-mode
  :config
  (setq lsp-ui-sideline-show-hover nil))

The default for lsp-ui-sideline-show-hover is non-NIL, which display information about symbols which can more distracting than useful.

NIL here doesn’t impact display of flycheck diagnostics or Code Actions.

For additional settings for lsp-mode above, use M-x describe-variable on each of these:

Using flycheck to lookup doc-strings for std traits and types produces apparent stalling of Emacs-25.2 on a 2018 4-core laptop with SSD and lots of RAM.

There is a separate package for the LSP UI:

(use-package lsp-ui
  :config
  (add-hook 'lsp-mode-hook #'lsp-ui-mode)
  :custom-face   ; see also: M-x list-colors-display
  (lsp-ui-sideline-current-symbol ((t :foreground "brown"
                                      :weight ultra-bold
                                      :box (:line-width -1 :color "brown")
                                      :height 0.99)))
  (lsp-ui-sideline-code-action ((t :foreground "orange"))))

The colour scheme above helps with Emacs displaying white background with black text; otherwise, some text was too faint to see.
(I keep brightness reduced to one click from off/black; i.e., rc.local has:
echo 50 > /sys/class/backlight/intel_backlight/brightness)

Hook for Rust language source code buffers to access build manager:

(use-package cargo
  :after rust-mode
  :config
  (add-hook 'rust-mode-hook #'cargo-minor-mode)
  (add-hook 'cargo-process-mode-hook #'visual-line-mode))

Ironically, there is apparently no file mode for rust’s Cargo.toml files:

(add-to-list 'auto-mode-alist '("Cargo.toml\\'" . conf-mode))

For TAB key for word-completion, used by racer:

(use-package company
  :config
  (add-hook 'racer-mode-hook #'company-mode))

Company also facilitates completion-at-point via C-M-i keys:

(use-package company-lsp
  :after company
  :config
  (setq company-lsp-enable-recompletion t)
  (lsp-define-stdio-client lsp-rust "rust" #'lsp-rust--get-root nil
                           :command-fn #'lsp-rust--rls-command
                           :initialize #'lsp-rust--initialize-client)
  (push 'company-lsp company-backends))

Provides M-. (meta-dot) for Rust source code buffers:

(use-package racer
  :after 'rust-mode
  :config
  (add-hook 'rust-mode-hook #'racer-mode))

Finally, rust-mode itself:

(use-package rust-mode
  :config
  ;; Requires the Language Server Protocol (LSP) be enabled,
  ;; but sometimes in emacs-25.2 fails with
  ;; "Suspicious state from syntax checker rust-cargo..."
  ;; When viewing rust code, use: M-x flycheck-buffer
  (add-hook 'rust-mode-hook #'flycheck-mode)
  (add-hook 'rust-mode-hook #'(lambda () (vc-mode-line nil)))
  (vc-mode-line nil)
  (setq cargo-process--command-clippy "+nightly clippy"
        company-tooltip-align-annotations t
        c-syntactic-indentation t
        c-basic-offset 2)
  :bind (("C-c C-c b" . cargo-process-build)
         ("C-c C-c c" . cargo-process-clippy)))

Not quite a REPL, Rust Playground is similar to *slime-scratch* as code sandbox. Start via: M-x rust-playground

For sharing like gist: M-x rust-playpen-region or rust-playpen-buffer

Try: M-x rust-playground-download

(If prompted for comment syntax, this is for Cargo.toml file, so use # 0x23 character.)

(use-package rust-playground
  :after rust-mode
  :config
  (setq rust-playground-basedir "/tmp/rust-playground"))

The default for Rust playground writes to ~/.emacs.d/rust-playground/ yet may be overridden by assigning rust-playground-basedir as above.

For LINT checking, consider installing Rust’s Clippy.

Run:

rustup install nightly && cargo +nightly install clippy

Then invoke with: M-x cargo-process-clippy or bind a key to that.

From the official websites and repos:

Search packages, and read their documentation:

Forum, IRC Channels and more are linked from Community page.

Academic Publications:

Useful Tools

Rust Language Server (aka RLS) implements the Language Server Protocol (LSP) for Visual Studio, and it’s available within Emacs (see above) plus many other code editors.

Why you want this:

When your code editor supports LSP, you’ll get live annotations as an overlay with your code indicating programming errors of syntax, mismatched types, conflicting lifetimes, violations of API contracts, etc.

Other helpful messages are also provided from an instance of the compiler running in the background.

These messages are delivered in real-time and conventionally displayed inline or close to the offending line of code while you type it.

Helpful For Understanding

In no particular order:

Interesting Libraries, Frameworks & Packages

Interesting Tools Made With Rust

Recently plucked from the ‘net, offered without context or explanation:

See Also:

This page is a work-in-progress.

Since C++ started as an incremental upgrade to C,
Rust would be C *= 11

Copyright © 2018 Daniel Joseph Pezely
May be licensed via Creative Commons Attribution.