Rust

Today's post is about Rust, the programming language.

One of my jobs wanted me to have a look at Rust for possible suitability for some of our purposes. I took a couple of days and read the Rust book and a few additional things I found on webpages (that's one of the points below). Then, today, I tried to actually write something with it.

Here are my reactions, in roughly chronological order.

 

The installer is a security disaster waiting to happen. Their install instructions are, basically, "fetch this shell script and run it". The script is relatively portable. While it does depend on $(...), /proc/self/exe, and curl or wget with HTTPS support, it's possible that those don't exclude anything their prebuilt binaries will run on. Because that's the next step: the people who check the script aren't really any better off, because what the script does is suck over an executable and then run it. This is an extremely high-value attack target; sooner or later it will get cracked, and then everyone who installs from it will be compromised, silently so if the person who wrote the trojan was any good.

But work doesn't care about security; they already run a whole lot of binaries someone else built and just assume they're OK. So I ignored that and ran it (on a work machine, to be sure).

Their installer then told me it would scribble on my shell startup files (at least it warned me ahead of time!), but the names it gave made it clear it blindly assumed my shell is bash, which it most definitely is not. (It's a Linux machine, yes, but I cannot tolerate bash for interactive use. bash's failings could make up a whole post of their own.) Apparently they believe the world is a monoculture (in this case, assuming Linux users all use bash).

Fortunately, it had an option to configure the installation. One of the things it did let me do was suppress the scribbling on my bash startup files. Unfortunately, it didn't give me any choice about anything else, insisting on putting things in two subdirectories of my homedir.

Minor annoyance: the installer has drunk the KiB, MiB, etc, koolaid. (This is admittedly purely cosmetic, but it's still annoying.)

It appears to have no mailing lists, only Web forum crap. Apparently they have drunk the koolaid that says that the Web is a suitable interface for anyone to anything, including thinking that a Web forum is a suitable replacement for a real mailing list (which it isn't, if only because mailing lists are active (push towards the user) whereas Web fora are passive (the user has to pull)). This makes them unsuitable for any kind of announcement, unless they believe all their users are fanatical enough to check the Web crap religiously. Perhaps there are mailing lists lurking somewhere, but if so, they are way too well hidden.

The installer told me that, to configure my current shell, I should run a particular `source' command. I didn't, of course, because I looked at what it told me to source, and it was sh syntax variable settings. My shell is not an sh derivative and does not understand sh syntax. Yet more monocultural assumptions.

The Rust webpages say that `rustup docs --book' will "open" the Rust book. (Whenever anyone uses "open" to mean "display", it usually means the author has spent so much time in GUI-land as to forget there is anything else, or perhaps never spent any time outside GUI-land. Either way, it primes me to watch for a very blinkered mindset.)

Of course, this didn't work. Running that command did nothing apparent. Quite by chance, when reading a Web version of the book, I happened to find a statement that rustup would "open the local documentation in [my] browser". Apparently they (a) think that a Web browser is a suitable tool for reading documentation (better than most of the misuses of Web browsers, but I'd still far rather have a text file I can use with the likes of less) and (b) think everybody keeps their Web browser in some kind of standard place, wherever rustup is looking for it. And, of course, they can't be bothered to document where they hid the underlying files, so I can go look at them (or maybe even, horrors!, look at them in the Web browser I do indeed have on the machine but which apparently rustup couldn't find, if their HTML files aren't so bloated-crawling-horror-specific they won't work except with the two or three browsers they feel like supporting).

They apparently have a code reformatting tool (rustfmt). Based on the descriptions I saw, it has no options, meaning they like the religion of their preferred coding style enough to feel justified in imposing it on everyone. (Furthermore, coding style guides are properly called guides for a reason; I have yet to see a coding style guideline concrete enough to be tested mechanically that isn't better off broken at least occasionally. I once worked on a project in Ruby which had elevated rubocop's style guide to the status of a style straitjacket; it was, umm, unpleasant.)

They appear to be uninterested in feedback from anyone who hasn't drunk github's koolaid. I would never go near github on my own hook, because they require use of the Web (and, worse, the HTTPS Web) to sign up. With reusable passwords. (Reusable passwords are a horrible, horrible authentication mechanism; the only excuse for them is that humans can remember them unaided. But with the proliferation of such systems, people find themselves unable to remember all the passwords in question, using password managers and the like, in which case they'd be better off with something like ssh public-key identities.) They claimed to have ssh access support, but when I tried to use it, I found they had removed support for the key exchange algorithms the SSH specs made mandatory. (This is not quite a spec violation; mandatory-to-implement does not mean mandatory-to-leave-enabled. But it does cripple interoperability, as in this case.) Furthermore, github dropped support for git's own protocol, even for read-only access, leading me to feel that having "git" in its name borders on fraudulent. And, while I obviously haven't actually tested it, I suspect that doing things like opening github issues would require use of the Web interface anyway.

This also means that Rust is utterly dependent on github. If whoever owns github this week happened to feel like it, they could cripple or perhaps even kill the Rust project by just dropping those repos. Or, for that matter, if github were to fold.

Rust treats strings as octet strings in some respects, UTF-8 in other respects, and strings of abstract Unicode codepoints in yet others. Unsurprisingly, they end up with something like the worst of all worlds. Their documentation even says that Rust source must be written in UTF-8, which is confusing the language with the language's implementation. And, of course, making it difficult to impossible to work with non-UTF-8 strings means they've just opted themselves right out of a whole bunch of things. Apparently pushing the religion of Unicode and UTF-8 is more important than being useful. More monoculture.

The command-line interfaces for many (most? all?) of their tools have drunk the double-dash koolaid, insisting on two dashes for multicharacter options. I don't know who originated that (I first became aware of it in Project GNU software), but it's annoying, pernicious, and completely unnecessary. More monoculture.

Their compiler errors are insanely verbose, over a dozen lines per error in a simple test I just did. That's really nice...for about one day. After that it gets really old really fast.

The cargo paradigm (cargo is their packaging, library, and build tool) is another security disaster waiting to happen. It's an extremely high-value central point of attack. Like their install host, it sooner or later will get cracked, and then everyone who pulls from it will have their code silently trojaned. Compounding this is the lack of mailing lists, leaving no way to express interest in hearing about such a thing when (notice I don't say `if') it happens.

It mandates IEEE floats. Problematic for only a small fraction of people, probably, but if it's impossible even in principle to build it for a VAX, well, I certainly wouldn't use it.

Crashes apparently don't drop core, instead printing a (very verbose) message before exiting (and, in some circumstances, apparently printing a stack trace). I have no idea why anyone would think this more useful than a core dump; perhaps the designers just haven't ever used serious developer tools? Or maybe it's because they're all using Linux, and these days Linux appears to have broken coredumps? (Processes claim in their wait status to have dumped core, but there's no core dump to be found anywhere. I have to wonder how anyone can seriously consider Linux a suitable system for developing anything. Maybe too many people just have never used anything better?)

In the Webpage `documentation', many of the images simply don't work on my work palmtop, er, excuse me, `smartphone'. I don't know why not.

One of the examples in the Rust book really needs to have some kind of forward reference to a later section added.

The build tool their religion pushes (`cargo') appears to be impossible to just add into a Makefile for a heterogenous project. Perhaps they think people using other languages is a bad enough thing that they want to make it painful. Fortunately, rustc is a command-line compiler.

Their tools blindly assume, even in the face of active evidence to the contrary (in the form of my TERM environment variable), that my terminal type supports X3.64 SGR sequences with the ISO 6429 colour parameter values, or at least does nothing untoward with them:

[Pavilion] 46> ~/rust/bin/cargo new chatter
[0m[0m[1m[31merror[0m[1m:[0m destination `/home/mouse/rust/ME/chatter` already exists

Use `cargo init` to initialize the directory
Again, perhaps they just all use nothing but Linux? A lot of Linux tools do the same, and a few do worse; I ran into a thing once that actually wedged on startup if the terminal (or emulator) in use didn't respond to the X3.64 DSR sequence, and a great many other things break to lesser degrees.

Of course, this borders on being undocumented. Doing some Websearches (on a work machine, of course), I found users saying that setting CLICOLOR=0 in the environment should shut that off; it didn't. I eventually found `--color never', which works, but (a) is far too well hidden and (b) appears to have no way to specify it but the command line, compelling a bunch of small shellscripts to get minimally-sane behaviour. (This leads into a separate rant, that these days a lot of people seem to think `documentation' means `what someone once said on stackexchange' or the like.)

Their front page (https://www.rust-lang.org/) then has the barefaced gall to claim that Rust "has great documentation, a friendly compiler with useful error messages, and top-notch tooling—an integrated package manager and build tool, smart multi-editor support with auto-completion and type inspections, an auto-formatter, and more". This is mostly false, as outlined above: the documentation is not "great", unless "a great pain in the arse" counts as "great"; the compiler's error messages are horribly over-verbose; the integrated package manager is a disaster waiting to happen; the build tooling goes way too far in the `policy instead of mechanism' direction; the "smart multi-editor support" is lacking the one thing I actually would like from it (syntax colouring); the auto-formatter is "when we want your opinion we'll give it to you", and, well, the "more" is the one piece I have absolutely no issue with there.

`rustc -W help' assumes a ridiculously wide window; when I ran it it produced one output line 1087 characters long.

The overhead is huge, ridiculously huge for a language supposedly suitable for embedded and systems programming [EDIT: this comparison is unfair; see here for how and why]:

[Pavilion] 127> cat main.c
#include <stdio.h>
int main(void);
int main(void) { printf("Hello\n"); return(0); }
[Pavilion] 128> cat main.rs
fn main() { println!("Hello"); }
[Pavilion] 129> cc -o mainc main.c
[Pavilion] 130> rustc -o mainrs main.rs
[Pavilion] 131> mainc
Hello
[Pavilion] 132> mainrs
Hello
[Pavilion] 133> size mainc
   text	   data	    bss	    dec	    hex	filename
   1583	    616	      8	   2207	    89f	mainc
[Pavilion] 134> size mainrs
   text	   data	    bss	    dec	    hex	filename
 303248	  11728	    312	 315288	  4cf98	mainrs
[Pavilion] 135> 
Using rustc -O (and cc -O99, to keep it fair), I see instead
[Pavilion] 144> size mainc
   text	   data	    bss	    dec	    hex	filename
   1575	    616	      8	   2199	    897	mainc
[Pavilion] 145> size mainrs
   text	   data	    bss	    dec	    hex	filename
 302540	  11688	    312	 314540	  4ccac	mainrs
which really isn't much better. I tried various -Copt-level= settings but was unable to get the rust `text' value below 300000.

The rustc book says, at one point, "For more information about the process and policy of future-incompatible changes, see RFC 1589". When I check RFC 1589, it proves to be "A Kernel Model for Precision Timekeeping". Say what??

The rustc book confuses PIC code and ASLR. (The former is necessary but not sufficient for the latter, but it's the latter that brings the benefits they're citing.)

I ranted about their style `guide' above. It's a problem even if I don't run rustfmt. The compiler was erroring for style reasons for some of my code, and there appears to be no way to turn that warning off for the file, only by adding an appropriate comment[1] for each and every instance of the warning. After far more searching than I should have needed to do, I eventually found `-A nonstandard_style' as a command-line option which shut it off, but there really needs to be a way to set it in the code rather than the compiler command line. Better yet, of course, would be to provide mechanism, rather than trying to impose their policy religion on me! (I'm actually slightly surprised they even had a way to turn it off on the command line.)

[1] That the compiler doesn't always totally ignore source code that conforms to the stated syntax for comments is, come to think of it, another issue.

Finally, one issue that really is an issue with the language proper. The match construct really needs to push `value is not used' from its context down into the match arms; in particular, mismatched arm types shouldn't be an error when the match's value is not used.

Most of these are actually issues not with the language proper, but with the implementation, the software ecosystem that has grown up around it, or the choices the Rust people made to, for example, encourage that software ecosystem. I see only four of the above issues that are issues with the language proper (string schizophrenia, IEEE floats, non-ignored comments, and unused match mismatches).

 

After all that, is there anything good about any of it?

Yes.

The ownership paradigm is a very clever way of getting most of the benefit of garbage collection without actually needing a garbage collector.

Similarly, traits are a clever way to get much of the benefit of OO without paying the worst of the prices.

The licensing for the licensed parts is sane.

 

EDIT: See also my next post and the one after that.

Main