My first Rust disappointment

Rust is an up-and-coming new programming language which offers compile time safety, automatic memory management, and C-like performance.

It also offers automatic resource management. In Java terms, it takes AutoCloseable, formalizes it more, and makes it ubiquitous throughout the language. When a resource is accessed, it is given a scope of applicability; when the scope ends, the resource is automatically closed. This eliminates problems like unclosed file and database handles.

To make this work throughout the language without annoyance, Rust introduces the ability when calling into another scope to either pass ownership of a value or lend it. If the value’s ownership is passed, the old scope can no longer access it, and the new scope owns it. If the value is borrowed, the called code can no longer access the borrowed value after returning.

With that background, here’s my first disappointment with the language, given that it seems to be trying to do everything right this time.

Yehuda Katz writes:

In practice, the reason this works so well is that most of the time, functions that take values are “borrowing” them. They take a value, do some work with the value, and return. Holding on to the value for longer, for example by using threads, is both uncommon and an appropriate time to think a little bit about what’s happening.

The starting point when writing new functions is to borrow parameters, not try to take ownership. After a little while of programming with Rust, this imposes no cognitive cost; it’s simply the default.

Except it’s not. The syntax for taking ownership is:

fn is_thirties(person: Person) {  
  person.age >= 30 && person.age < 40

For borrowing, it’s:

fn is_thirties(person: &Person) {  
  person.age >= 30 && person.age < 40

This leads me to propose a rule for future language designers:

When designing syntax for a programming language, the safest and most desirable behavior should be the one with the least syntax.

Rust has apparently repeated the mistake Java made with final parameters: it has made the unadorned syntax be the one you shouldn’t do unless you have a really good reason.

I appreciate that Rust’s choice is probably to make the syntax look familiar to C++ programmers, but to me that seems like a really bad tradeoff. The vast majority of programmers aren’t C++ programmers, and I daresay the majority of C++ programmers aren’t capable of using it safely, so optimizing for them is pessimizing for most use of the language.

Sure, it’s only a single character in front of every parameter, rather than the word final, but to me that makes it worse — it’s really easy to miss a single character.

What I think should have been done would have been for Rust to lend parameters by default; taking ownership of a parameter would then require an explicit warning notation, like an ! on the front. But then, that wouldn’t have looked like C. And of course, it’s far too late to change it now.

Yes, this is a very minor issue. It’s just that I’m old enough and cranky enough these days that when I read about a new programming language, I generally only get through a few pages before hitting an “oh my god what were they thinking” moment. (Go error handling. Scala’s arrow fetish and occasionally needing semicolons. Haskell’s responses to trivial errors. CoffeeScript semantic indentation. Perl 6 operators.) Rust is unusual in that I read entire articles and still wanted to try it, which is why the undesirable default behavior of function arguments disappoints me.

XPages JavaScript mystery meat

When using XPages, I try to build as much as possible in Java, and then use as little JavaScript as possible to glue the Java code into XPages.

The main problem I hit when doing this is ensuring that my Java methods have the right type signatures to get found and called by JavaScript. It’s confusing to call someMethod(true) and find that you get a run-time error saying there’s no Java method someMethod(boolean), even though there is.

So I put together a quick Java class to dump back the types of the objects it was passed, and then fed it everything I could think of from an XPage. Here’s the result.

Standard JavaScript types
Parameter Received as
boolean java.lang.Boolean
number java.lang.Double
null null
string java.lang.String
array java.util.Vector
JSF predefined variables
Parameter Received as
applicationScope com.sun.faces.context.ApplicationMap
cookie com.sun.faces.context.RequestCookieMap
header com.sun.faces.context.RequestHeaderMap
headerValues com.sun.faces.context.RequestHeaderValuesMap
initParam com.sun.faces.context.InitParameterMap
param com.sun.faces.context.RequestParameterMap
paramValues com.sun.faces.context.RequestParameterValuesMap
requestScope com.sun.faces.context.RequestMap
sessionScope com.sun.faces.context.SessionMap
XPages types
Parameter Received as
document data source
view data source lotus.domino.local.View
extlib object data source The Java class of your object data source
predefined variable ‘database’
predefined variable ‘session’ lotus.domino.local.Session
text field control via getComponent or other appropriate class from that package

Note that many of the JSF and XPages variables are accessible directly from Java, so you generally shouldn’t need to pass them as parameters — but I’ll leave that decision to you.


[Now updated for 2015!]

Component Status
systemd Replaces init, cron, inetd, udev, locale, acpid, atd.
systemd-journald Replaces syslog, klog.
systemd-logind Replaces getty, login, xdm. (*)
systemd-networkd Replaces ifup, ifdown, tcpwrapper, hostname, dhcpd.
systemd-journal-gatewayd Provides HTTP server for systemd-journal.
systemd-timesync Replaces NTP.
systemd-resolved Replaces resolvconf, bind, powerdns-recursor, dnsmasq.
systemd-automount Replaces autofs.
systemd-readahead No longer supported because everyone who matters has SSDs.
systemd-machined Replaces VirtualBox, VMware. (Coming soon.)
systemctl-cat Replaces cat. Really.
systemd-firewall Replaces iptables.
systemd-journal-remote Replaces logstash/elasticsearch with a new logging protocol over HTTP.
gummiboot To be incorporated, replacing grub.

Also, here come the security vulnerabilities:

…systemd-resolved does not implement any of the hardening recommendations of rfc5452

(*) OK, so it’s a bit more complicated than that. Eventually the plan is to get rid of X11 for Wayland, but currently X11 is still allowed. However, systemd is part of the PAM configuration now, and systemd starts your X session with display manager and window manager. So far login and getty still service legacy non-console ttys.