
A taste of Rust - edwintorok
http://lwn.net/Articles/547145/
======
Locke1689
_In contrast to this, array (or, as Rust calls them, "vector") references do
not require the compiler to know that the index is in range before that index
is dereferenced. It would presumably be possible to use the type system to
ensure that indexes are in range in many cases, and to require explicit tests
for cases where the type system cannot be sure — similar to the approach taken
for pointers.

Thus, while it is impossible to get a runtime error for a NULL pointer
dereference, it is quite possible to get a runtime error for an array bounds
error. It is not clear whether this is a deliberate omission, or whether it is
something that might be changed later._

I presume that's because the Rust designers didn't want to include a dependent
type system. Comments from pcwalton?

~~~
pcwalton
Right.

------
monkeyfacebag
The article doesn't specify what exactly, is permitted by an unsafe vs. safe
function. The Rust reference indicates the additional operations permitted by
unsafe functions are:

    
    
        1. Dereferencing a raw pointer.
        2. Casting a raw pointer to a safe pointer type.
        3. Calling an unsafe function.
    

I was expecting something more along the lines of Safe Haskell
([http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/safe-...](http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/safe-
haskell.html)) which is more about _trust_ than memory safety and, as such,
explicitly restricts IO.

This isn't a value judgment. I just find it an interesting distinction.

~~~
kibwen
Indeed, there's been some discussion regarding forcing users to specify what
sort of unsafety they desire when using unsafe blocks. There's no syntax
whatsoever yet, but consider something like the following:

    
    
      unsafe(no-bounds-checks) {
          ...
      }
    

or:

    
    
      unsafe(raw-pointers) {
          ...
      }
    

Right now the problem is that once you drop into an unsafe block, _everything_
that is unsafe becomes allowed. Obviously this is bad for correctness and bad
for readability.

~~~
lmkg
It seems to me one of the prime difficulties with trying to differentiate
types of unsafe behavior, is that often one will imply another. I recall that
in C#, there is only one type of Unsafe block and the only unsafe operations
it allows is raw pointer manipulation, but since you could theoretically point
into the runtime itself, the set of implied consequences of Unsafe blocks is
effectively unbounded. If Rust manages to drop its runtime it's not quite so
easily susceptible, but even so, returning a pointer to a vtable outside of
the unsafe block implies return-oriented programming implies unbounded
capabilities.

I guess part of the issue is, what is the goal of marking code as unsafe? The
use-case that C# was trying to serve was that you could be consuming a third-
party assembly without access to source, and you want to know what are the
possible consequences of running it. If Rust's main goal is being able to
audit your own code for safety (either by hand or by tools), rather than
trusting external binaries, then it makes more sense to take a feature-
oriented approach rather than a consequence-oriented one.

Rust's pointer taxonomy might also help with providing degrees of
consequences. You could, for example, restrict that raw pointers could only be
cast to pointers with non-sendable kind, which would let you circumvent type
safety while still controlling the scope of possible data races. Restricting
lifetimes might be useful too, but that's too far beyond the limits of my
experience.

~~~
pcwalton
> I guess part of the issue is, what is the goal of marking code as unsafe?

Basically, it's a way to be able to find the unsafe code by grepping for it.
It's a mechanism for security auditors to be able to search for the unsafe
code and audit it.

It also serves as some social pressure to avoid unsafe code.

------
zepolud
It might be childish but I just can't force myself to swallow the ugly curly
braces and semicolons.

Some compromises had to be made, e.g. the lack of tailcalls is a regrettable
but nonetheless well justified decision. But why didn't they include a
standard indentation style in the language specification itself and get rid of
the cruft? They have one for Servo anyway, which is the raison d'etre of the
whole language, so it's bewildering to me why it isn't included as a part of
the specification.

It just pains me to see a promising new language being burdened with an ugly
looking syntax when the language itself is quite elegant.

~~~
coldtea
> _It might be childish but I just can't force myself to swallow the ugly
> curly braces and semicolons._

Yes, it's childish. Worse, it's bikeshedding.

~~~
zepolud
Defining a sane syntax while the language is still in its infancy is anything
but bikeshedding. You have only one chance to do it right before an entrenched
codebase develops or interest in the language fizzles.

MS Research did this right with the experimental hardwhite support while F#
was still in alpha. People liked it so much that it became the default style
for the compiler and the standard library. It would be impossible to try to
make the switch now that the language is widely used.

It might be childish for me to choose one language for a project than another
over trivial things like semicolons, but for the language itself it's an
irreversible decision once the spec gets set in stone.

~~~
jboy
To me, one of the most interesting design decisions of Rust is that the
creators strongly try to avoid inventing new language features. Instead, they
attempt to find the best combination of tried-and-true existing features from
a variety of other languages.

I wonder whether language syntax could be considered such a "feature" -- that
is, the Rust creators would consciously prefer to combine existing syntaxes
(at this point, mainly C++, Haskell, OCaml and Ruby) than invent their own.

An argument could be made that they could just "use Python's syntax", but
perhaps a counter-argument would be that Python's syntax would need to be
extended so much (for types, pointers, templates, etc.) that the result would
effectively be a new invention.

~~~
lobster_johnson
That logic sounds fishy to me. After all, they took C++'s semicolon syntax
over Haskell, OCaml and Ruby's semicolon-free syntax, so there must have been
a reason for picking one over the others. So the issue is not about inventing
syntax, it's about choosing one (existing) syntax over another.

pcwalton says it was to attract C++ devs, which is interesting considering
that Go was also designed to attract C++ devs and made the opposite choice. As
a sometime C++ dev, I recognize the historical uselessness of semicolons and
would _love_ a replacement language that did away with them.

~~~
klibertp
Since when OCaml is semicolon-free? It not only has semicolons, single
semicolon (;) means something different than double semicolon (;;). The former
is used as an expression separator, like comma in Erlang, and the latter
denotes the end of a top-level declaration, like period in Erlang. That's a
pain while refactoring, but I can live with it. Anyway, that's just a style,
nothing more, you can learn to love it or you can write a "transpiler", it's
really a non-issue.

~~~
lobster_johnson
True, Ocaml has semicolons, although it's a little different given that you
can construct deeply nested functional expressions without ever using a single
one. If I remember correctly the semicolon is a separator, not a terminator,
which means that declarations don't need to end with a semicolon, for example,
and you pretty much only need it to separate statements.

~~~
klibertp
I'm not sure I prefer 'in' over semicolon in declarations. I mean:

    
    
        let x = ref 0 in
        (* something *)
    

in Ocaml is not much worse/better than

    
    
        let mut x = 0;
        // something
    

in Rust. As I said above, that's really a minor, stylistic issue, one probably
would write "let x = mut 0 in" for a week or so (coming from OCaml) and that's
it, after a week it becomes as natural to write semicolon as it is to write
'in'.

~~~
lobster_johnson
I agree, I didn't really put OCaml forward as the ideal solution. Ruby and Go
solve the semicolon problem in much better ways, in my opinion.

------
rustc
I'm a big fan of rust (hence my username), and would like to know if there
have been any non-trivial benchmarks of Rust's compilation time, and the
performance of compiled executable.

Last I checked Rust took about 40 minutes to compile itself on my laptop. Is
it still the case? (I haven't touched Rust for a month or so.)

Also, is anyone using Rust in non-toy projects? (Except Mozilla's own servo.)

~~~
dbaupp
Are these the sort of benchmarks (of compiled executables) you are looking
for: [http://pcwalton.github.io/blog/2013/04/18/performance-of-
seq...](http://pcwalton.github.io/blog/2013/04/18/performance-of-sequential-
rust-programs/) ?

~~~
rustc
Thanks for the link. They're good, but I'd really like to see the comparison
of memory safe version and parallel version, compared to languages which
compete on those fronts (as the comments on that post have already requested),
as that would really be the selling point of Rust IMO.

~~~
fzzzy
It's still a little early to be benchmarking the scheduler as it is currently
undergoing a large rewrite, I believe.

------
MaxSize
I know there are various pointer type prefixes in Rust (@foo, ~foo, &foo,
*foo), 'foo for lifetimes and $foo for macro arguments, but WTH is +foo?
[https://github.com/mozilla/rust/blob/master/src/librustc/mid...](https://github.com/mozilla/rust/blob/master/src/librustc/middle/borrowck/loan.rs#L260)

I haven't seen this in the documentation.

~~~
kibwen
A very old, very very deprecated feature. I believe pcwalton's working on
removing the last vestiges of it from the compiler as we speak. The feature
was called "argument modes", but it's been deprecated for so long that almost
nobody remembers precisely how they were used (very few understood it in the
first place). They were quite pervasive in the early 0.0 days, and it's taken
this long to remove them completely.

In addition to the +foo forms, there were also others: -foo, &&foo, ++foo,
perhaps more. Be glad that they're gone. :)

------
ww520
I actually like Rust's compartmentalized approach to memory allocation. Having
task/thread specific heap is very concurrent friendly, great for running
programs in multi-processor system.

