The Rust Programming Language
rust-lang.org
rust-lang.org
The bottom line is that if you're interested in writing applications using Rust, you should really hold off until 0.4 or so (I'd say give it three months), both to give them time to implement all the missing pieces and then to refactor the Rust compiler to use those pieces, thereby shaking out the bugs and annoyances.
But if you're interested in helping out on writing the compiler itself, or proof-of-concept libraries, definitely consider pitching in. The devs greatly appreciate volunteer contributions.
I mean an actual production release?
As someone who follows the project closely, I do think that almost all of the core concepts will be present by 0.4 or 0.5 at the latest (fingers crossed), which would probably be the best time for eager early adopters to dive in. Also consider that Mozilla will be using Rust for experimental prototype browser engine implementations soon, likely even before 0.3 is released.
But if you're looking for some semblance of stability, I'm not sure what advice I can give beyond "wait for 1.0"--which has no definite timeframe. The Rust devs don't even schedule minor releases more than two in advance, so Rust might jump directly from 0.4 to 1.0, or from 0.9 to 1.0, or from 0.367 to 1.0. But don't worry, when they do make the jump, I'm sure you'll hear about it on HN. :P
If you'd prefer to track the project milestones yourself, check out the Github issues page[1] and browse the currently scheduled milestones from the dropdown in the left column.
[1] https://github.com/mozilla/rust/issues?milestone=&sort=c...
See for yourselves: http://www.adahome.com/History/Steelman/steelman.htm Later revisions have well-though-out rationales that show off all the changes: Ada 95: http://www.adaic.org/resources/add_content/standards/95rat/r... Ada 2005: http://www.adaic.org/ada-resources/standards/ada05/ Ada 2012(!!): http://www2.adacore.com/wp-content/uploads/2006/03/Ada2012_R...
The steelman was the end revision of requirements for the original language. There is a comparison of C/C++/Java/Ada wrt the steelman available as well. Ada has become so much more since this document and it's original version one really must see it to be believe it. :o)
As a community we have a tendency to embark on projects on a whim, but the effort, time and money required to bring a language to maturity is enormous. Even then any deficiency a preexisting language may have surely is not so insurmountable as to make it viable to develop a new language in house.
Can we please have some sanity? Can we please look for mature solutions?
Edit: Ada has an amazing GCC frontend developed largely by a successful opensource company (with just massive customers across the globe) and is available across all of its targets: the bsd's, solaris, linux, mac, haiku, android and more. It's a great solution that is hard to ignore.
I think a main selling point for Rust is its type system: it's more up to date from the state of the art of... the mid seventies, having Algebraic Data Types and type inference. Though it does seem to lack some of Ada's features, such as its limited support for dependent types in the form of its ranged numeric types and fixed-length array, so it may balance out.
Edit: oh, and Rust has no null.
I guess people still dislike verbose syntax, and you still see people making macho arguments about how they like to throw type-safety over the window for 'power', but Ada without doubt is a seriously underrated language.
In a perfect world, perhaps we'd be using Ada for all tasks that currently require C++. However, the fact that we're still using C++ over Ada suggests to me that there is still room for new languages in this area. I agree that it's sad to see so much redundancy and duplication of effort. But if the end result of all of this is that future applications are written in a more reliable language, isn't that still a net win for society, regardless of what that language is?
Dynamic allocations in Ada are a cinch by the way. We use the "new" reserved word.
subtype Hacker_News_Article_ID is Natural; -- Numbers 0 .. Integer'Last;
type Article_Handle is access all Hacker_News_Article_ID; -- "all" reserved word used allows access to variables on the stack.
Favorite_Article : aliased Hacker_New_Article_ID := 3793716; -- "aliased" so we can point to this stack variable.
Article_Pointer : Article_Handle := Favorite_Article'Access; -- A sensible default perhaps.
later on...
Article_Pointer := new Hacker_News_Article_ID (Whatever);
Good luck!
In practice, this means your Ada written image viewer can show you 1000 thumbnails, but no more. Or 10000, or some other hard limit. And you can only view images smaller than 2MP. Unless the author made the fixed sizes really large, but now you're burning 10MB of memory per image even if they're all tiny gifs.
A declaration like the one above is typically done on the stack (although it doesn't have to be). An array can be allocated on the heap with "new", with, IIRC, the following syntax: new Foo_Array (3..10)
new Foo_Array(x..y)
That's what I couldn't figure out how to do last I tried.Their goal of being a modern systems programming language are similar.
Has a section called: "Have you seen this Google language, Go? How does Rust compare?"
Excerpt: "Go adopted semantics (safety and memory model) that are quite unsatisfactory." Like Null pointers, global GC, shared mutable state etc.
I'm a C++ systems programmer, so I'm trying to understand some of the issues here. I'm not familiar with either language, please forgive the ignorant questions.
Null: Why is null evil? Doesn't Go use it in the Java sense of releasing a reference to the object?
Global GC: Seems more like a runtime implementation choice?
Shared mutable state: Doesn't seem so bad for someone approaching a systems programming language. I don't always want to make copies and send it over as a message to the other threads?
My higher-level point is that, perhaps these languages could do a better job of selling, differentiating, explaining themselves. I know it's hard, that's why I'm trying to help by posing my stupid questions. Btw. if they're planning to write Firefox in this, maybe the author should maintain a minimal browser written in Rust to show how the language fits its original design goals.
Global GC is definitely a language issue. It affects language semantics.
Avoiding shared mutable state does not mean making copies. If you can statically check there is no other reference you can avoid copying. Think advanced move semantics.
Global GC: It's hard to do GC without stopping the world. If different threads have different heaps, only a single thread needs to be stopped at any given time for the GC to be performed (on this thread's heap). AFAIK, Rust also supports manually managed references.
Shared mutable state: I believe that is more of a language restriction, not VM (i.e. sending messages could be implemented without copying). Simplifies debugging and makes some abstractions much easier (distributed computing in particular).
We've learned that, especially when it comes to concurrency, there really is no one model that supports everything you might want to do. Instead, the idea is to support safe, data-race-free language constructs, and to make those the easiest ones to use. Data races (and memory unsafety) are clearly marked in "unsafe" blocks, with the idea that if you find a concurrency bug in your software, you can grep for that keyword and go over those blocks only, instead of having to crawl through the entire codebase.
The same principle applies to null. You can get nullable pointers (use option<T>), but you have to declare that that's what you want. You also have to declare some strategy for handling the null case every time you use the pointer, or at least communicate your intent to fail on null via the .get() method. The vast majority of pointers in any program aren't nullable, so in practice we've found that this eliminates a lot of bugs.
> Every language is small compared to C++.
Good point. :)However, the devs are aiming to keep the language simple. They're PL experts (watching them at work is quite intimidating, actually, as someone who doesn't have a PhD in CS), but they absolutely reject the allure of the ivory tower. Note the header on the page linked in this submission:
"a safe, concurrent, practical language"
Note "practical". I've witnessed several exchanges on the mailing list where the developers attempt to excise language features. For example, in Rust, `if` is an expression rather than a statement, and thus is redundant with the `?:` ternary conditional expression syntax familiar to C-like languages (the latter was removed). Alternatively, they often acknowledge that having three types of pointers is suboptimal from a simplicity perspective, but they consistently conclude that the semantics unique to each type of pointer are valuable enough to justify the mental cost.
My colleague Dave Herman always says that language design goes through cycles: You identify a problem, add solutions to fix it, then discover that these solutions are best merged with some other ideas. The result is that, as a language evolves, complexity goes up and down. I think that we're coming off a peak of complexity and the language is going to evolve toward simplicity in the near term.
Just to name a few simple examples, removing the alias analysis pass and removing "native modules" are some simplifications that mostly have consensus at this point.
[1] I get the feeling that Go's main design goal is ease of use, on par with Python.
"Rust is a programming language that's supposed to fit the C++ niche, without the insanity of actual C++. If the project works out, and it's going swimmingly so far, Mozilla will try to apply it to writing a next-generation browser, without the constant danger of buffer overrun exploits and threading bugs that comes with C++. True to Mozilla's spirit, all development on Rust is happening in the open, on github."
http://smallcultfollowing.com/babysteps/blog/2012/03/28/serv...
That's the key question here...
What are the advantages to using white space?
Blocks easily identified by their indentation. It might take a little getting used to but I find it very pleasant.
Sure, you make it easier for the random onlooker to be prepared to always immediately understand what is going on, but at the same time, the programmer who writes for his own perusal or that of a small team of known others will find themselves restricted by a totalitarian scheme telling them what they can express and what they can't. The assumption that most code is written for most people to read is simply not true, and code that is intended for the masses has always been able to deal with the problem by imposing style guidelines.
Most projects/companies have indentation/style standards so that code can be communicated across individuals. Once you add in the indentation style, braces look redundant and are just extra noise and chances for error.
I must admit, though, totalitarian systems often help people work together :)
Enough with the bikeshedding! There are much more interesting things about Rust to discuss than this.
Significant indentation is the #1 thing keeping me at a distance from Haskell and Coffeescript.
Any decent editor lets you handle block indentation very simply, and it's typically easy to see what the indentation level should be.
In languages with () or {} I can hit a key to reformat copy-pasted code. In Python I have to do it manually.
When it comes to moving blocks of Python code around inside one source file, then it's a simple matter to hit the plus/minus indent hotkey.
Most editors even let you handle that on a filetype basis, so you can use 4 spaces for Python, and tabs for your C files.
That was supposed to be the compilers job. I am here to do mine.
No wonder so many people hate whitespace based parsing.
What are you talking about? Why wouldn't you have your editor just insert the correct number of spaces when you press the tab key? It's worked fine for all my python work.
Anyway, that's tab vs. space flamewar, best practices flame war, etc.
Long story short, I don't like spaces because editors do not make it as easy to navigate back/forward 4 (or 2) spaces as it is to navigate 1 tab. Most annoying instance of this: what combination of keypresses does it take to get from the middle of a line to the beginning of a line? In Notepad++ it's easy, but it Xcode its cmd-left-arrow then hit right-arrow for every space/tab you need to pass. (Or in general for a Mac text editor cmd-left-arrow, then opt-right arrow, then opt-left arrow, but that doesn't always work right. In TextWrangler it's cmd-left + opt-right, which is better but still slightly tricky hopping from cmd to opt key.)
If you assume that this is possible, and your eyes can get used to read code just by its blocking, then brackets are unnecessary, even superfluous.
As long as there are not too many newlines within blocks...
If all you know is {}, then other code is harder to read. Once you learn either a Lisp-like language or a Python-like language then you learn to see code blocks without {}. This is what happened for me. (I was forced into learning Scheme in school. Only after that did I decide that Python was an OK language after all.)
I'll grant, however, that the Python approach isn't quite as bad as I thought it would be, and that it can come close to matching the readability of "code with braces." But, for me at least, braces (and vertically aligned ones at that, dangit) absolutely make code more readable.
YMMV, IANAL, HTH, WTFBBQ, etc...
Let me ask you this, do you already indent your code? If not it is probably a tangled mess and I wouldn't want to continue the conversion with you. But, if you already indent your code, then why do you need brackets? You are wasting space and you are repeating yourself. It is like enforcing that every declaration of "int counter" to be followed by a comment saying "// declaration of counter as an int".
The only reason to use brackets is to minify a piece of code or to appeal to C++ or C programmers. So Javascript benefits from having brackets. I guess Rust does too because it is trying to appeal to C++ programmers.
I can't depend on having a "good" editor. I have 2 work machines, 2 home machines, ssh to a VPS, ssh to a bunch of machines at work, etc. So as often as not I have to use vim to do quick edits of code. I also am generally forced to use Apple's Xcode for Obj-C applications, but use other editors for anything else. Working on my own toys vs. working at work, vs. being in school instead of a commercial entity with nice software licenses also means I can't depend on having the same text editor available, other than free ones.
I'd prefer to use a programming language that was easy to read and write in just about any text editor. The only requirement I can't easily escape is that the editor must support auto-indent. (So MS Notepad is out.)
Actually you can apply that argument for whitespace only languages, because they produce code that is more consistent. So because the code is more consistent it is also easier to read and write (as opposed to say, dealing with someone's eccentric formatting).
Vim or emacs (the one I use) is available for any modern OS out there. It is free and has outstanding syntax highlighting and works through a terminal as far as I know.
In general it seems like this is a tail wagging the dog problem -- picking a language to work with (what seems to be a broken) editor.
I agree but in reverse. You're willing to give up a trivially parseable syntax just to avoid typing a few braces?
Minimalism for its own sake is an anti-pattern in language design. I will be very happy once this meme dies.
Incidentally, I'm the latter, and I'm very interested in Rust.
if(foo) { doSomething(); } else { doSomethingElse(); }
to be rather unreadable. My solution is to not write it that way.My observation is that code style is very important to Ruby and Python developers and less important to those from C-family backgrounds. That is, a lot of Ruby developers, for example, refuse to touch anything containing braces whereas few C-family developers require them.
I think the solution is that developers with a Python/Ruby background need to create a systems language, instead of expecting those with different backgrounds to be converted to the Python/Ruby-ists mindset. But in reality it seems that few Python/Ruby developers are all that interested in systems languages whereas those with C-family backgrounds are very interested (hence the situation that presently exists).
So, you can have a whitespace-based version of Rust easily.
The practical problem is that then you'd split the community between the two syntaxes since you couldn't copy-paste code examples from one syntax into the other. That could be problematic for building a large base of support. Take D for example where they had fragmentation problems with two standard libraries. Perhaps a split based on syntax would be less? (Since code written in one could be shared with the other.) But it would still cause problems in how the language is marketed to new developers.
Also besides semicolons don't cause any problem at the first place, so why eliminate them?
"Its design is oriented toward concerns of “programming in the large”, that is, of creating and maintaining boundaries – both abstract and operational – that preserve large-system integrity, availability and concurrency."
- "Programming in the large" - programming produced by lots of people and/or meant to last a long time.
- "creating and maintaining boundaries" - when you have a lot of people working on code, it's very useful to be able to isolate code and define the boundaries between code explicitly. Things like interfaces and type safety tend to help do this (the "abstract" in "abstract and operational"). On the "operational" side, having modules that produce dynamic libraries with good versioning semantics helps.
- "that preserve large-system integrity, availability" - again, type safety, in-built null pointer protection and garbage collection all help make sure that code doesn't fall over as much as it could without those (there are some philosophical arguments in here that I'm not exploring).
- "concurrency" - Consensus appears to be forming around the idea that a good way to manage concurrency is with lightweight processes and message passing rather than threads and shared state. Rust does the former. Rust also encourages the use of immutable state which also helps avoid concurrency issues.
Unfortunately in reality things are usually not that well encapsulated. Things like threads, integration withe the system, etc often interfere as does things like the desire to test a particular piece of software.
Basically think of it as enabling the same benefits you get from having a general count function over having specific functions for arrays, directories, lists, etc but to an enti system.
1. It's easy to break things accidentally, and it's hard to track down all the usages of something when you change it. This is especially true when functions and types can be aliased under different names, changing a class affects all subclasses, etc. The more complex the application, the more you get pervasive usage of types defined within the application. This is a real change from smaller applications where most of the pervasive types probably come from the language's standard library, which can be trusted to be stable between major releases.
2. A large codebase means that whatever finicky housekeeping the language requires is almost guaranteed to get screwed up somewhere in your application. If this affects the integrity of the whole app, it can be very bad. Invalid memory accesses are an infamous example. It doesn't matter if you have a million lines of awesome, feature-filled code; if one buggy line of code crashes your app every ten minutes by dereferencing an invalid pointer, your app is unusable.
3. Fragmentation of types and libraries. Programmer X adds a Flugelhorn library on one end of the app, programmer Y adds a Flugelhorn library on the other end of the app, and nobody realizes it until incompatible Flugelhorn types start bumping into each other in the middle. This is less of a problem for a community where "programming in the large" means many people writing many small independent projects, but it could be a major annoyance for a language where the goal is to write large, complex applications such as web browsers.
4. Concurrency. Concurrency can be a coupling factor that requires programmers to know too much about global design and global state. It can also destroy performance and stability. Finally, given principle #2 above (every large running application contains screwed-up code somewhere) runaway tasks are a threat to the whole system if not contained. When done well, however, concurrency can reduce coupling and improve stability.
5. It can take a long time to rebuild a large codebase and run its tests.
I don't know much about Rust so far, but here's my stab at matching the features of Rust against those five problems:
1. Compile-time type checking is a big help. Rust also has some ways to enhance types without subclassing.
2. Memory safety, garbage collection, errors that propagate upward by default, isolated tasks. Error handling is unappreciated in this category, I believe. It's important that an application not accidentally suppress an error and continue, because it could corrupt data, return incorrect results, or behave insecurely. A language like C where errors can be swallowed through oversight or programmer laziness is dangerous in that regard. In Rust, errors propagate upward, unwinding the stack until they terminate a task or are explicitly handled.
3. Generic types help, and built-in support for Unicode text is a necessity. It also helps that the organization shepherding the language is likely to be the biggest user of the language. It's important to note that anything that helps with #3 also helps with #1. For example, if the language has a standard string type you can use everywhere, then your tests don't need to protect against Doug down the hall (or across the world) changing the string type and not realizing he broke your code.
4. Immutability, message passing, isolated tasks, per-task GC. It sounds like Rust is trying to make task isolation the default way to firewall errors off from the rest of your app. For a web programmer, this is exactly like the way a Java web container is supposed to work. If one web app in the container goes haywire, the container and all the other web apps should ideally be able to continue running without their stability being compromised.
5. I don't know what techniques are used by Rust to speed up compilation. A compiled language is at a disadvantage on this count, but compiling to object code is necessary for a systems language. Also, static type checking means drastically fewer unit tests (I don't want to start a flamewar about whether this is a good thing; it's just the way people code) so you get a little bit of your lost compile time back when you run tests.
> I don't know what techniques are used by Rust to speed up compilation.
From what I've observed, forcing the developers to compile the language using itself is a great way to keep the programmers mindful of compilation speed. :)In Rust's case, I believe the bottleneck is LLVM. You can disable optimization if you just care about fast turnaround times, but you're always at the mercy of LLVM to do the actual code generation. To that end, the Rust devs have recently begun an initiative to profile the amount of LLVM IR that they generate in the compiler, and they've made some good strides so far just from picking the low-hanging fruit.
As far as comparisons to other languages go, I'm not sure if Rust's compilation model is set up to be as fast as Go's, although (IIRC) Rust avoids the template-generation step that bogs down C++.
Everything I'm reading here in the comments is talking about how this would be a replacement for c/c++, but wouldn't Mozilla be more interested in a language that's more web focused? As I see it, Rust would NOT be a web language, or am I missing something? Is this something they would try and develop future versions of Firefox in?
This is the whole reason why that language has such a big potential.
It has high level algebraic datatypes with pattern matching, so you can nicely model your control flow (like haskell or ocaml) but still remaining low-level.
Doesn't require JVM to run. I consider that a plus. But others might not.
I wasn't sarcastic or trolling, but I understand it's hard to know with a cryptic 3 words sentence.
ps: I gathered some thoughts. It reminded me of ADA because it's designed to be low-level, yet embed high-level concepts and typing (generics).
I also like Rust. I haven't tested it yet (will try it) but the first impressions are good. But I think Rust will not be on par with ADA 2012 until it supports range values (like x : Integer Range 1..100) and contracts at least.
Asserts are good for the beginning but a language for really big software should have verification mechanisms which are implemented in SPARK (a subset of ADA).
http://doc.rust-lang.org/doc/rust.html#typestate-system
The way I understand them (and I say this a lot, but I could be wrong) is that it's like a more powerful version of Eiffel's design by contract, which allows the compiler to test whether invariants hold at compile time rather than just throwing assertions at runtime.
E.g. SPARK allows static verification of bounded memory usage, which I am not sure if rust's `check` is able to express.
AFAICT this requires forbidding recursion, unbounded loops and use of heap allocators or types/procedures which in turn have access to such facilities.
Or somewhat equivalently: the SPARK subset of Ada is statically verifiable by not being turing complete, so bits of the code can be verified, and elsewhere the full Ada language can be used.
I am not sure if Rust can emulate this.
(Again, I am not an Ada/SPARK developer so all of what I wrote may be wrong, do not take life decisions based on what I write)
Another option (addon) would be to use commented invariants like in SPARK which are tested against the code by an automatic verification system even before compile time. To get an impression what it means, please read:
http://www.adacore.com/home/products/sparkpro/tokeneer/disco...
for downvoters : pun intended.