Announcing Rust 1.0 Beta(blog.rust-lang.org)
blog.rust-lang.org
Announcing Rust 1.0 Beta
http://blog.rust-lang.org/2015/04/03/Rust-1.0-beta.html
111 comments
Just my 2cs, but the complexity of this code is here to remind you there are a lot of cases you have to take into account :
let path = Path::new(&app_path);
if let Some(ostr) = path.file_name() {
if let Some(str) = ostr.to_str() {
println!("file name : {}", str);
} else {
println!("WARNING : file name is not a valid unicode sequence ! (file name : {:?}", ostr);
}
} else {
println!("Path is either a root directory or a dot entry, it has no filename");
}I think unwrap calls are mainly meant for quick and dirty stuff and if you find yourself doing it it may be the wrong solution.
The 'String', '~str' dichotomy is really unfortunate.
Presumably you mean String/&str? (~str hasn't existed for a long time.)
On the contrary, the lack of the string/string-view distinction is widely considered a flaw in the C++ standard libraries. C++14 introduces std::string_view to correct it. Rust's String/str distinction is just the same as C++14's std::string/std::string_view.
On the contrary, the lack of the string/string-view distinction is widely considered a flaw in the C++ standard libraries. C++14 introduces std::string_view to correct it. Rust's String/str distinction is just the same as C++14's std::string/std::string_view.
Apart from the Rust's usual rule to invent some abbreviations, but only apply them half the time.
Then "types start with an uppercase letter" except when the language creators break their own rule.
Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing".
Then the various insanities with ::.
Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson?
I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations), because many ideas of Rust are not only good but brilliant and deserve to be put into languages which don't belong to the purely-academic category.
I really wish Rust to succeed, but can we stop this approach of "3 steps forward and 2 steps backward" to language design?
Then "types start with an uppercase letter" except when the language creators break their own rule.
Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing".
Then the various insanities with ::.
Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson?
I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations), because many ideas of Rust are not only good but brilliant and deserve to be put into languages which don't belong to the purely-academic category.
I really wish Rust to succeed, but can we stop this approach of "3 steps forward and 2 steps backward" to language design?
>
Apart from the Rust's usual rule to invent some abbreviations, but only apply them half the time.
Do you have an example?
> Then "types start with an uppercase letter" except when the language creators break their own rule.
They always start with a capital letter, except for built-in types or FFI bindings to libraries such as libc where the original types used a lowercase letter. This convention is exactly the same as Java.
> Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing".
I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing.
> Then the various insanities with ::.
The double-colon is very useful so that you can tell the difference between module lookup and field projection/method calling. Early Rust used . for module lookup, and it was confusing to tell at a glance whether a function was being called or a method was being invoked.
> Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson?
Using square brackets like Scala wouldn't actually help with the ambiguity, because it would be ambiguous with array indexing. The only syntax I've seen that actually solves the ambiguity is D's `!()`, which was deemed too unfamiliar. Angle brackets were chosen because they are familiar and aren't really any worse than the other mainstream options.
> I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations)
The underscore naming convention was actually taken from Python's PEP 8. Rust doesn't really have any more abbreviations than most other languages at this point.
Do you have an example?
> Then "types start with an uppercase letter" except when the language creators break their own rule.
They always start with a capital letter, except for built-in types or FFI bindings to libraries such as libc where the original types used a lowercase letter. This convention is exactly the same as Java.
> Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing".
I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing.
> Then the various insanities with ::.
The double-colon is very useful so that you can tell the difference between module lookup and field projection/method calling. Early Rust used . for module lookup, and it was confusing to tell at a glance whether a function was being called or a method was being invoked.
> Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson?
Using square brackets like Scala wouldn't actually help with the ambiguity, because it would be ambiguous with array indexing. The only syntax I've seen that actually solves the ambiguity is D's `!()`, which was deemed too unfamiliar. Angle brackets were chosen because they are familiar and aren't really any worse than the other mainstream options.
> I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations)
The underscore naming convention was actually taken from Python's PEP 8. Rust doesn't really have any more abbreviations than most other languages at this point.
> > Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing".
> I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing.
Maybe referring to the ability to use either type of brace with macros?
> I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing.
Maybe referring to the ability to use either type of brace with macros?
Yeah, you can use any type of delimiter with macros, but I think that's an important feature, especially since macros can expand to declarations. Early versions of Rust required parentheses for all macro invocations, and that looked really ugly for anything that looked like a block. Delimiter interchangeability is a feature from Racket that works really well when it comes to macros and I'd hate to give it up.
Agreed. They allow you to naturally create vectors with the bracket delimiter `vec![1, 2, 3]`, create spawn-like macros with the brace delimiter `spawn { code }`, and in the normal case just use parentheses `println!("testing")`
> () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing.
Array indexing is a function call, because an array is a function from its index set to the set of the values the array stores, or -- equivalent -- a partial function from integers to the value set.
Scala gets this right.
Array indexing is a function call, because an array is a function from its index set to the set of the values the array stores, or -- equivalent -- a partial function from integers to the value set.
Scala gets this right.
> Scala gets this right.
I don't know, I never liked how all FunctionNs are sort of "unofficial" partial functions (because they may throw), and PartialFunctions are then made a subtype of FunctionN, because they have an extra method where you can ask whether they are defined at given points. Especially since throwing seems to be falling out of favor in Scala, being replaced by Try[] return types.
I don't know, I never liked how all FunctionNs are sort of "unofficial" partial functions (because they may throw), and PartialFunctions are then made a subtype of FunctionN, because they have an extra method where you can ask whether they are defined at given points. Especially since throwing seems to be falling out of favor in Scala, being replaced by Try[] return types.
This is an orthogonal issue. Arrays are clearly partial functions. The Try[.]-vs-exceptions issue is to do with the question whether failures should be reflected in types (the Try[.]-option) or not (exceptions). There are good arguments for and against both options, but both options go well with the understanding that arrays are functions and indexing is function application.
I don't think anything's much orthogonal to partiality of functions in languages with strong type systems, unfortunately :)
You wrote that array indexing is "a partial function from integers to the value set". If we're to take the suggestion seriously, then the practicality of it depends on how partial functions are represented in the language. Which itself is certainly not orthogonal to the Try-vs-exceptions issue.
You wrote that array indexing is "a partial function from integers to the value set". If we're to take the suggestion seriously, then the practicality of it depends on how partial functions are represented in the language. Which itself is certainly not orthogonal to the Try-vs-exceptions issue.
I'm not sure I can agree. I didn't say that the type of the array function is independent of the choice of error propagation mechanism. If you think an array is a partial function from integers to some value domain, say A, then in the exceptional POV the array type is int -> A, and in the Try[.] POV the array type is int -> Try [ A ].
I was talking about the mechanism for array indexing. In both cases, indexing is function application. So the choice of error representation is orthogonal. This is even more evidence that we should not use a different operator for array indexing as Rust does alas.
I was talking about the mechanism for array indexing. In both cases, indexing is function application. So the choice of error representation is orthogonal. This is even more evidence that we should not use a different operator for array indexing as Rust does alas.
OK I can agree with that, I think I was taking what you wrote as a wider endorsement of Scala's approach than what you intended.
What about '{}'? It's a nice pair of opening/closing characters.
frowaway001(1)
In this example the dichotomy is between String (which is guaranteed by the type system to be valid UTF-8) and OsStr (which might be in an unknown encoding or otherwise not decodable to valid Unicode).
This is exactly when you want a systems language to require explicit conversions, rather than converting things silently and possibly losing or corrupting data.
This is exactly when you want a systems language to require explicit conversions, rather than converting things silently and possibly losing or corrupting data.
rather than converting things silently and possibly losing or corrupting data
Exactly. Python3 went down the "silently converting" route, and it's not pretty[1]. I would go so far as to call it harmful.
http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/
I understand the difficulty in this space; much of it is caused by forcing the Windows unicode filesystem API onto python as its world-view, rather than sticking to the traditional Unix bytes world-view. I'm unixy, so I'm completely biased, but I think adopting the Windows approach is fundamentally broken.
Exactly. Python3 went down the "silently converting" route, and it's not pretty[1]. I would go so far as to call it harmful.
http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/
I understand the difficulty in this space; much of it is caused by forcing the Windows unicode filesystem API onto python as its world-view, rather than sticking to the traditional Unix bytes world-view. I'm unixy, so I'm completely biased, but I think adopting the Windows approach is fundamentally broken.
The problem there is overblown - it's basically all due to the idea that sys.stdin or sys.stdout might get replaced with streams that don't have a binary buffer. The simple solution is just not to do that (and it's pretty easy; instead of replacing with a StringIO, replace it with a wrapped binary buffer). Then the code is quite simple
import sys
import shutil
for filename in sys.argv[1:]:
if filename != '-':
try:
f = open(filename, 'rb')
except IOError as err:
msg = 'cat.py: {}: {}\n'.format(filename, err)
sys.stderr.buffer.write(msg.encode('utf8', 'surrogateescape'))
continue
else:
f = sys.stdin.buffer
with f:
shutil.copyfileobj(f, sys.stdout.buffer)
Python's surrogateescape'd strings aren't the best solution, but I personally believe that treating unicode output streams as binary ones is even worse.There is no ~str, but when there was it was largely identical to what String is now.
Yes, it's true. Code like this is going to be more verbose. Often, it's due to Rust being a systems language and exposing low-level details to you, combined with the type system ensuring safety. In this instance, `Path` is actually fairly complex. From the RFC: https://github.com/rust-lang/rfcs/blob/master/text/0474-path...
In systems programming, details matter. As such, our stdlib APIs try to expose those details. I expect some people will write higher-level abstractions that hide all this if you don't care as much.
Tradeoffs tradeoffs tradeoffs...
> The design of a path abstraction is surprisingly hard. Paths work
> radically differently on different platforms, so providing a
> cross-platform abstraction is challenging. On some platforms, paths
> are not required to be in Unicode, posing ergonomic and semantic
> difficulties for a Rust API. These difficulties are compounded if one
> also tries to provide efficient path manipulation that does not, for
> example, require extraneous copying. And, of course, the API should
> be easy and pleasant to use.
So, in this case, you have to call `file_name` to get the filename, but that returns an `Option`, since it might not be a file, it could be a directory. The `unwrap` says "crash if it's not a filename." You then have an `OsStr`, which is a string type that handles the kinds of cross-platform issues alluded to in the above paragraph. `to_str` will then attempt to turn it into a `&str`, but because `&str` must be unicode, if the conversion fails, it _also_ returns an Option, which is the last unwrap.In systems programming, details matter. As such, our stdlib APIs try to expose those details. I expect some people will write higher-level abstractions that hide all this if you don't care as much.
Tradeoffs tradeoffs tradeoffs...
"Often, it's due to Rust being a systems language and exposing low-level details to you, combined with the type system ensuring safety."
I'm not convinced it's being a "systems language" (in the sense I think you mean). The last three languages I've learned to fluency have all, in various ways, been very concerned about errors: Erlang, Haskell, and Go. Yes, they have widely varying opinions about what to do with them, but they all agree that you have to be fairly constantly worried about them. You can't sweep them under the rug; you need a strategy, and you need to deal with the resulting issues head on.
Despite their differences, what I feel like I've learned from them is that historically speaking, the vast majority of popular languages and their communities have been downright cavalier about errors. It's often in all the little details rather than a consistent, stated design goal, but the presence of various nils and nulls, APIs that will happily return empty strings for paths instead of errors, and all kinds of APIs and libraries that seem to be subconsciously written with the belief that returning an error is a failure on the part of the library and will go to what now seem to me to be absurd lengths to somehow keep klunking along in the presence of already-manifested failure. Even for languages that think they're being really good with exceptions, I find that when I go back to them, they end up using the exception support to "permit" themselves to be sloppy and hope the exceptions will pick up the pieces... and they often don't. Not because of some theoretical weakness, but because allowing developers to think they don't have to think about the error cases means precisely that they don't!
People are used to errors not poking them in the face until deploy time. It seems to me there's a strong, broad motion towards developing languages that will in one way or another force you to deal with them at compile time. It's a culture shock for people, but, I'll tell you this, get really good at Rust or any of these other languages and go back to any of those other languages, and you will find your code changes in those other languages to suddenly look a lot more like your Rust does anyhow, which means this putative disadvantage of Rust evaporates anyhow. Once you see how sloppy you were being, it's hard to go back in good conscience.
I'm not convinced it's being a "systems language" (in the sense I think you mean). The last three languages I've learned to fluency have all, in various ways, been very concerned about errors: Erlang, Haskell, and Go. Yes, they have widely varying opinions about what to do with them, but they all agree that you have to be fairly constantly worried about them. You can't sweep them under the rug; you need a strategy, and you need to deal with the resulting issues head on.
Despite their differences, what I feel like I've learned from them is that historically speaking, the vast majority of popular languages and their communities have been downright cavalier about errors. It's often in all the little details rather than a consistent, stated design goal, but the presence of various nils and nulls, APIs that will happily return empty strings for paths instead of errors, and all kinds of APIs and libraries that seem to be subconsciously written with the belief that returning an error is a failure on the part of the library and will go to what now seem to me to be absurd lengths to somehow keep klunking along in the presence of already-manifested failure. Even for languages that think they're being really good with exceptions, I find that when I go back to them, they end up using the exception support to "permit" themselves to be sloppy and hope the exceptions will pick up the pieces... and they often don't. Not because of some theoretical weakness, but because allowing developers to think they don't have to think about the error cases means precisely that they don't!
People are used to errors not poking them in the face until deploy time. It seems to me there's a strong, broad motion towards developing languages that will in one way or another force you to deal with them at compile time. It's a culture shock for people, but, I'll tell you this, get really good at Rust or any of these other languages and go back to any of those other languages, and you will find your code changes in those other languages to suddenly look a lot more like your Rust does anyhow, which means this putative disadvantage of Rust evaporates anyhow. Once you see how sloppy you were being, it's hard to go back in good conscience.
Great comment. I have run into this problem exactly in inherited codebases at my last couple of jobs:
> libraries that seem to be subconsciously written with the belief that returning an error is a failure on the part of the library and will go to what now seem to me to be absurd lengths to somehow keep klunking along in the presence of already-manifested failure.
It's a big problem with hairy repercussions if this idea is allowed to take root.
> libraries that seem to be subconsciously written with the belief that returning an error is a failure on the part of the library and will go to what now seem to me to be absurd lengths to somehow keep klunking along in the presence of already-manifested failure.
It's a big problem with hairy repercussions if this idea is allowed to take root.
> The last three languages I've learned to fluency have all, in various ways, been very concerned about errors
Yeah, maybe I should revise my statement a bit: systems languages, overall, tend to expose more details. I meant this in a broader context than errors. As a simple example, manual memory management exposes more details than GC. There are many languages that care dearly about errors, as you've rightfully pointed out.
I broadly agree with the rest of your post. Error handling is hard and tedious, and programmers don't like doing it. I myself had an embarrassing bug in `rustbook` where I did `let _ =`. I only intended to start off that way! Programming is hard. But using Haskell, Rust, and other languages like this have certainly changed my code in other languages.
Yeah, maybe I should revise my statement a bit: systems languages, overall, tend to expose more details. I meant this in a broader context than errors. As a simple example, manual memory management exposes more details than GC. There are many languages that care dearly about errors, as you've rightfully pointed out.
I broadly agree with the rest of your post. Error handling is hard and tedious, and programmers don't like doing it. I myself had an embarrassing bug in `rustbook` where I did `let _ =`. I only intended to start off that way! Programming is hard. But using Haskell, Rust, and other languages like this have certainly changed my code in other languages.
[deleted]
[deleted]
If you were willing to allow for potential escape characters and acknowledge (to the user) the fact that the path might not have a file name, you could write:
I/O has lots of tricky error cases, and Rust usually requires you to acknowledge that. You can avoid dealing with those cases with unwrap(), or you can explicitly handle them. Personally, I much prefer this to being surprised only when the weird error case unexpectedly turns up because I never considered the situation in question, and that's generally how Rust handles things, but it depends on the task. It may make Rust less appropriate for quick scripting tasks, for example, where the domain is well-defined and the script is not likely to be reused (but I find that those scripts have an annoying way of getting reused anyway).
println!("file name: {:?}", path.file_name());
or just for escape characters, but only if the file name existed: if let Some(name) = path.file_name() {
println!("file name: {:?}", name);
}
Note that the unwrap() isn't boilerplate, in either case: if you are using `unwrap()` you are implicitly saying that you know for a fact that the file name is present (the first time) and a valid UTF-8 string (the second time), which isn't guaranteed in the general case on all platforms. If you wanted to write this more robustly, and these weren't guaranteed, you would need to explicitly take care of those cases.I/O has lots of tricky error cases, and Rust usually requires you to acknowledge that. You can avoid dealing with those cases with unwrap(), or you can explicitly handle them. Personally, I much prefer this to being surprised only when the weird error case unexpectedly turns up because I never considered the situation in question, and that's generally how Rust handles things, but it depends on the task. It may make Rust less appropriate for quick scripting tasks, for example, where the domain is well-defined and the script is not likely to be reused (but I find that those scripts have an annoying way of getting reused anyway).
However, rust would be relatively well-suited for a "dirty quick scripting task". You could make a more traditional wrapper for the operations you like to use that assumes these rare edge cases don't happen, and panic otherwise.
This is sort of rust's philosophy; being explicit. Rust has no problem with failing, it just has a problem with failing without you telling it to. If you write a wrapper that implies you are willing to fail on these cases, then you're being explicit by choosing to use these functions instead :)
This is sort of rust's philosophy; being explicit. Rust has no problem with failing, it just has a problem with failing without you telling it to. If you write a wrapper that implies you are willing to fail on these cases, then you're being explicit by choosing to use these functions instead :)
I would say it is familiarity, but in another sense. You can use something like
Where familiarity comes in I believe is in what that line communicates to me: There might not be a file name (like having '/' as path), and that getting a string slice out of it might fail (the kind of string the platform uses for paths might not be UTF-8 compatible).
Plus, the unwrap()s tell me that whoever wrote the code considered it an assertion failure if one of those is happening.
I read a lot more Rust than I write, and it really helps that the code communicates a lot. And with knowing about OsString/OsStr beforehand, I only had to lookup when file_name() returns None, the rest is rather implicit by convention, or familiarity.
path.file_name().and_then(|f| f.to_str()).unwrap()
but that really doesn't buy you much.Where familiarity comes in I believe is in what that line communicates to me: There might not be a file name (like having '/' as path), and that getting a string slice out of it might fail (the kind of string the platform uses for paths might not be UTF-8 compatible).
Plus, the unwrap()s tell me that whoever wrote the code considered it an assertion failure if one of those is happening.
I read a lot more Rust than I write, and it really helps that the code communicates a lot. And with knowing about OsString/OsStr beforehand, I only had to lookup when file_name() returns None, the rest is rather implicit by convention, or familiarity.
I wish `and_then` were named `flat_map` so badly.
We have `flat_map` for iterators. (`and_then` works for Options, which are basically nullables)
You can convert an Option to a zero-cost iterator and then use `flat_map` though.
You can convert an Option to a zero-cost iterator and then use `flat_map` though.
To add to the other comments, Rust prefers to make error cases explicit. We have memory safety. You can opt out of it, but you have to opt out explicitly. We have exhaustive match. You can use a wildcard, but you need to explicitly do so. We have nullables and Results. You need to explicitly acknowledge the error/null case, or use `unwrap()` to say that you don't mind a panic at this point.
This leads to verbosity at times, but usually its a good verbosity.
This leads to verbosity at times, but usually its a good verbosity.
I'm sure I'm not the first (or the hundredth) to say this, but `unwrap` has always struck me as a horribly innocuous spelling of "yes, feel free to crash here".
I presume there is (or could be) a standard lint to prevent this getting into production code, but it still feels kind of icky.
I presume there is (or could be) a standard lint to prevent this getting into production code, but it still feels kind of icky.
We almost changed it to `assert` but that made some people _really_ upset.
[deleted]
Dammit, I kept wondering why it wasn't named unwrap_or_panic/unwrap_or_assert but it could be worse at least unwrap is a less friendly name then scala's get.
`.expect()` is slightly better (you can give it a string that will become a part of the panic message)
> surely something like should be easier?
That would be nice, but as others hinted that wouldn't actually work:
* there are paths without a file_name (`/`) so it returns an Option to make that evident
* to_str attempts to convert the OS-dependent thing to a Rust string. Rust strings are valid unicode, but many filesystems don't have such strict requirements[0]. Again Rust returns an Option to makes that evident although there's a "to_string_lossy" method which will simply replace invalid sequences with U+FFFD if you don't really care
The Rust philosophy is generally to expose these issues upfront and force the developer to consider them (and either handle or explicitly ignore them). It is indubitably less convenient than e.g. Python 3's `PurePath(app_path).name` returning an str, but you'll have had to decide what happens in case of failure.
Paths are really a good example of something which looks simple, should be simple, and is actually anything but simple for historical and technical reasons, especially in a cross-platform context.
[0]
* Unix paths are the most troublesome: they're arbitrary bags of (non-NUL) bytes, they don't have to be in a known encoding, they don't have to be in any encoding.
* Windows paths are not guaranteed to be Unicode either: they're UTF-16 code units aka UCS2 + surrogates, and the surrogates may be unpaired, leading to invalid Unicode.
* OSX paths are guaranteed to be valid Unicode.
That would be nice, but as others hinted that wouldn't actually work:
* there are paths without a file_name (`/`) so it returns an Option to make that evident
* to_str attempts to convert the OS-dependent thing to a Rust string. Rust strings are valid unicode, but many filesystems don't have such strict requirements[0]. Again Rust returns an Option to makes that evident although there's a "to_string_lossy" method which will simply replace invalid sequences with U+FFFD if you don't really care
The Rust philosophy is generally to expose these issues upfront and force the developer to consider them (and either handle or explicitly ignore them). It is indubitably less convenient than e.g. Python 3's `PurePath(app_path).name` returning an str, but you'll have had to decide what happens in case of failure.
Paths are really a good example of something which looks simple, should be simple, and is actually anything but simple for historical and technical reasons, especially in a cross-platform context.
[0]
* Unix paths are the most troublesome: they're arbitrary bags of (non-NUL) bytes, they don't have to be in a known encoding, they don't have to be in any encoding.
* Windows paths are not guaranteed to be Unicode either: they're UTF-16 code units aka UCS2 + surrogates, and the surrogates may be unpaired, leading to invalid Unicode.
* OSX paths are guaranteed to be valid Unicode.
Also, OSX applies unicode normalization to the filenames, which can cause some interoperability problems with unix, e.g. you try to copy files forth and back between the systems and end up with two copies of a file, with identical-looking filenames that differ in their unicode normal form.
I am somewhat underwhelmed by this because I can't really come up with a problem that can't be solved by C++, Java, Python or Go (or some combination hereof) which could be solved by another low-level language without garbage collection.
❯❯❯ brew install rust
Warning: rust-1.0.0-alpha.2 already installed
:(
:(
Sub in the version and sha256 and you should be good to go: https://github.com/Homebrew/homebrew/pull/38346/files
Actually, this isn't enough. You also want to set --release-channel=beta, otherwise you effectively get a nightly build of the beta tarball (unstable features available) instead of a proper beta channel build of that tarball.
https://github.com/Homebrew/homebrew/pull/38346 should interest you
Two big things:
As of today, my job gets harder: "things are always changing" is no longer an excuse for missing docs. The six weeks until release is largely about polish, and I have some pretty big plans...
> the beta release represents an accurate preview of what Rust 1.0 will include.
and > We don’t plan on making functional changes to stable content,
> though naturally we may make minor corrections or additions to the
> library APIs if shortcomings or problems are uncovered (but the bar
> for such changes is relatively high).
This is the first release we've promised this kind of stability. The team and community has been doing an incredible amount of work lately to make this happen. We really hope you'll like what we've been up to, but Rust isn't for everyone, so no worries if it's not for you. Constructive criticism always welcome. <3As of today, my job gets harder: "things are always changing" is no longer an excuse for missing docs. The six weeks until release is largely about polish, and I have some pretty big plans...
Can't wait to play around with this!
Great work everyone involved!
Rust is very exciting.
It has gotten many things right -- a really good approach to safety, didn't sacrifice performance, powerful well thought out type system. I think we might finally see the next generation "systems language". We've heard promises before but hopefully this is finally it.
Rust is very exciting.
It has gotten many things right -- a really good approach to safety, didn't sacrifice performance, powerful well thought out type system. I think we might finally see the next generation "systems language". We've heard promises before but hopefully this is finally it.
Question for Rust peeps out there:
Is there a documentation on how to build single binary executable for Rust?
Is there a documentation on how to build single binary executable for Rust?
I'm assuming you're referring to static linking.
Right now, we depend on glibc, and it cannot be statically linked. By default, Rust applications statically link everything but glibc already.
At least one core team member is strongly advocating for musl support for truly standalone binaries in the 1.1 timeframe, but nothing is likely to change for 1.0, and it's too early to decide on 1.1 features yet :)
Right now, we depend on glibc, and it cannot be statically linked. By default, Rust applications statically link everything but glibc already.
At least one core team member is strongly advocating for musl support for truly standalone binaries in the 1.1 timeframe, but nothing is likely to change for 1.0, and it's too early to decide on 1.1 features yet :)
> Right now, we depend on glibc, and it cannot be statically linked.
Could you expand on this? Why can it not be statically linked?Name resolution libraries are loaded dynamically [1,2], so glibc can't be linked statically if you want NSS to work. I gather there might be a way to explicitly link to a specific resolution library but this is practically unsupported/poorly documented.
[1]: https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked...
[2]: http://stackoverflow.com/questions/3430400/linux-static-link...
[1]: https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked...
[2]: http://stackoverflow.com/questions/3430400/linux-static-link...
I understand this limitation. I can currently get around this by using --enable-static-nss.
Does rust currently expose any way to do this? Could I perform linking myself as a workaround?
Does rust currently expose any way to do this? Could I perform linking myself as a workaround?
> Could I perform linking myself as a workaround?
You can but it requires lots of black magic, and certainly a nightly rather than beta Rust ;)
http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-... is an old blog post that can get you started.
You can but it requires lots of black magic, and certainly a nightly rather than beta Rust ;)
http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-... is an old blog post that can get you started.
Wonderful -- thanks Steve! Best of luck on the upcoming release.
It's generally considered a poor idea to statically link glibc, but if you don't rely on certain features, you can do it. For example, NSS won't work unless you add a bunch of flags for other libraries you specifically use, see https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked...
Most people who focus on 100% statically linking just use a different libc. For example, Stali Linux, [1] has this to say: http://sta.li/faq
> it [is] nearly impossible to use glibc for static linking in non-trivial programs.
That said, if you want to give it a shot, it's technically possible, though we don't expose it for Rust yet, due to these kinds of landmines.
1: which got linked here a few times, most recently https://news.ycombinator.com/item?id=7261559
Most people who focus on 100% statically linking just use a different libc. For example, Stali Linux, [1] has this to say: http://sta.li/faq
> it [is] nearly impossible to use glibc for static linking in non-trivial programs.
That said, if you want to give it a shot, it's technically possible, though we don't expose it for Rust yet, due to these kinds of landmines.
1: which got linked here a few times, most recently https://news.ycombinator.com/item?id=7261559
I'm looking forward to using rust in a constrained embedded environment where I control 100% of the software. I don't have to worry about such problems.
Awesome, then yes, you have several advantages here :) You'll be using nightly Rust for a while, as several features that target this use case are still unstable, like inline assembly. But it's a use case we do care a lot about.
Most of the people I've seen targeting this use case stub out their own stdlib, although that obviously gets cumbersome the more stuff you want to do.
If you statically link libc, and then another library you use (potentially transitively) dlopen(3)s a library, you are going to have a bad time.
Of course, but that doesn't mean we shouldn't have the option, right?
Is there plans to drop glibc dependency? Rust should be able to do system calls itself and glibc should be as optional FFI library IMO.
That's funny, I always thought that GHC's lack of support for shared libraries and requiring static linking were serious obstacles to its adoption, but people are actually asking for this kind of thing now?
If you want to re-use any of the huge number of mature C libraries out there, you will need to link against glibc anyway.
Directly invoking system calls is quite the violation of the UNIX philosophy :)
If you want to re-use any of the huge number of mature C libraries out there, you will need to link against glibc anyway.
Directly invoking system calls is quite the violation of the UNIX philosophy :)
May be I misunderstood something, but dropping dependency on glibc doesn't imply static linking.
Of course reusing C library means linking with libc and reusing C++ library means linking with libstdc++. But in a long perspective those libraries should be implemented with Rust to have all advantages of the better language.
And using rust without libc might help with some embedded use-cases, where people don't want to put unnecessary stuff. Rust as a 0-cost systems language theoretically could be used there instead of C.
Of course reusing C library means linking with libc and reusing C++ library means linking with libstdc++. But in a long perspective those libraries should be implemented with Rust to have all advantages of the better language.
And using rust without libc might help with some embedded use-cases, where people don't want to put unnecessary stuff. Rust as a 0-cost systems language theoretically could be used there instead of C.
Does Rust have a UNIX dependency? If not, I don't see what the UNIX philosophy has to do with anything.
Possibly glibc itself, but not a libc in general. While it's true that Rust can make system calls itself (though inline assembly isn't stable yet), we're not interested in re-implementing all of that.
Finally. I had been holding off on implementing things in rust because of the time spent getting libraries up to date with the nightlies. This is huge for the rust ecosystem
Indeed. So many times over the last few months things just suddenly broke. I understand and all but it will be nice to see some stability.
I really feel the community, which is already awesome, will start to build new things at a rapid pace.
I really feel the community, which is already awesome, will start to build new things at a rapid pace.
I'm impressed with how thoughtful the entire Rust development cycle has been. They've managed not just to strike a balance between stability and language redesign, but to approach to API and syntax standardization in a way that made tracking the changes relatively painless. Some of this is done in the language itself, with opt-in statements and stability annotations in the API, but the tooling around compatibility in the ecosystem is quite useful as well. Now they're going to doing CI on their own nightlies against packages in the ecosystem:
> To help ensure that we don’t accidentally introduce breakage as we add new features, we’ve also been working on an exciting new CI infrastructure to allow us to monitor which packages are building with the Nightly builds and detect regressions across the entire Rust ecosystem, not just our own test base.
> To help ensure that we don’t accidentally introduce breakage as we add new features, we’ve also been working on an exciting new CI infrastructure to allow us to monitor which packages are building with the Nightly builds and detect regressions across the entire Rust ecosystem, not just our own test base.
CI against package ecosystems is a really great idea. We do it for Julia too [1], and it can identify some really subtle issues that would otherwise take longer to become apparent.
http://pkg.julialang.org/pulse.html
http://pkg.julialang.org/pulse.html
I'd imagine that such a bank of tests would be helpful in tuning performance too. Though perhaps the reality of each tweak only contributing a fraction of a percent would be considered depressing compared with the standard practice of saying that a microbenchmark is now 2x or 4x faster.
Good job, guys! This is an exciting language. Really happy about the "native" language revival going on lately.
I'm reading the docs, and they say that for I/O, use the 'old_io' module, which is...deprecated?
If I were to start doing any I/O in Rust beta, would that code be essentially throw-away as soon as the 'new' io module lands?
I'm reading the docs, and they say that for I/O, use the 'old_io' module, which is...deprecated?
If I were to start doing any I/O in Rust beta, would that code be essentially throw-away as soon as the 'new' io module lands?
They should absolutely not say to use `old_io`, that must have slipped through. New IO has fully landed, you can't even use `old_io` in the beta. Which page? I'll fix it right now. :)
http://doc.rust-lang.org/nightly/std/index.html
"Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, timers, and process spawning, are defined in the old_io module."
Following the "old_io" link leads me to http://doc.rust-lang.org/nightly/std/old_io/ which says "don't use me"
"Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets, timers, and process spawning, are defined in the old_io module."
Following the "old_io" link leads me to http://doc.rust-lang.org/nightly/std/old_io/ which says "don't use me"
Ah, thank you! We used to mention it from io's page, and I removed that, but this one slipped. https://github.com/rust-lang/rust/pull/24022
Looks like libstd/lib.rs still points to old_io, which shows up on http://doc.rust-lang.org/1.0.0-beta/std/
Same with libcollections/fmt.rs defining the write! macro as taking an old_io::Writer
There's also a bunch of old_io in http://doc.rust-lang.org/book/concurrency.html
Same with libcollections/fmt.rs defining the write! macro as taking an old_io::Writer
There's also a bunch of old_io in http://doc.rust-lang.org/book/concurrency.html
I just submitted a fix for the first, the second I'm not as sure about, and I just opened up https://github.com/rust-lang/rust/issues/24023 for the third. It's non-trivial because Duration isn't yet stable, I thought it might be, so I didn't prioritize updating, but it didn't quite make it in. Thank you!
Shouldn't the third be trivial, since thread::sleep_ms takes a u32?
Still building beta, but shouldn't this work? https://github.com/rust-lang/rust/pull/24024
Still building beta, but shouldn't this work? https://github.com/rust-lang/rust/pull/24024
Ahhh, so this was one of those last-hour changes, specifically so this works out, iirc. sleep will take a Duration, sleep_ms takes a u32. Anyway, let's keep talking in-ticket.
The doc's, and more specifically the tutorials, can be a bit stale. If you're referencing the one I think you are (building the number guessing game) it's old. I'm sure it will be updated eventually. [1]
One of the hardest things about learning Rust right now is that because it is not 1.0, lots of the tutorials, sample code and 3rd-party documentation is outdated - or parts of it are.
Learning Rust "the right way" will certainly get easier after 1.0 is finally out and reliable/stable the tutorials, code bases and doc's will follow.
[1] I just checked and it is in fact updated.
One of the hardest things about learning Rust right now is that because it is not 1.0, lots of the tutorials, sample code and 3rd-party documentation is outdated - or parts of it are.
Learning Rust "the right way" will certainly get easier after 1.0 is finally out and reliable/stable the tutorials, code bases and doc's will follow.
[1] I just checked and it is in fact updated.
Six weeks to 1.0-stable! And it's going to be a hell of a ride, since there's still tons of polish to do with respect to tooling and documentation and bugfixes. In other words, no time to celebrate. :P
If you'd like to help out, one of the best things that new users can do is simply to write a toy project or library in Rust and record their experience. If you crash the compiler somehow, file a bug! If you're confused by a poorly-worded error message, that's a bug too! If our docs are lacking, heck yes that is also a bug! If we're missing some crucial API on the stable branch, let us know so that we can prioritize which APIs to stabilize! We care about every aspect of the experience of developing Rust, and though our resources are finite we'll do our best to address the most common pain points first.
https://github.com/rust-lang/rust/issues
If you'd like to help out, one of the best things that new users can do is simply to write a toy project or library in Rust and record their experience. If you crash the compiler somehow, file a bug! If you're confused by a poorly-worded error message, that's a bug too! If our docs are lacking, heck yes that is also a bug! If we're missing some crucial API on the stable branch, let us know so that we can prioritize which APIs to stabilize! We care about every aspect of the experience of developing Rust, and though our resources are finite we'll do our best to address the most common pain points first.
https://github.com/rust-lang/rust/issues
So would you say that usability has been a primary focus of Rust from the beginning? Is it the primary focus?
If so, what kind of research did you do to make Rust usable? Any surveys or anything like that?
I'm genuinely curious because, as far as I know, none of the major languages were designed to be usable (which is not the same as "concise" or "easy"). Some of them have made huge strides in usability, but (understandably) none of them started that way.
Usability involves more than syntax --package management, interoperability, docs, and error messages. Since you mentioned those things, it made me wonder whether Rust were designed in a more user-focused way.
If so, what kind of research did you do to make Rust usable? Any surveys or anything like that?
I'm genuinely curious because, as far as I know, none of the major languages were designed to be usable (which is not the same as "concise" or "easy"). Some of them have made huge strides in usability, but (understandably) none of them started that way.
Usability involves more than syntax --package management, interoperability, docs, and error messages. Since you mentioned those things, it made me wonder whether Rust were designed in a more user-focused way.
I'm genuinely curious because, as far as I know, none of the
major languages were designed to be usable...
I think that's a little narrow-minded. Of course languages are designed to be usable. "Usable" is almost meaningless on its own, as every language is intended for use by developers to solve problems (toy languages notwithstanding).As for your specific goals, "package management, interoperability, docs, and error messages," I think there are in fact major languages designed with very specific goals in those areas. Node.js for example was designed to leverage the immense popularity and familiarity with JavaScript, and it has a clear story for package management that has enabled an enormous ecosystem. Go is a language that from the get-go was designed with a coherent story of how to build large and maintainable systems, encompassing package management and the module system, language features chosen for their simplicity such as interfaces and the lack of generics, and a canonical source formatting tool to attempt to make the whole ecosystem more readable and understandable.
Rust of course has its own answers for usability. They too have a package system that can enable a thriving ecosystem. Their approach to memory management is a naked attempt to make their language "usable," an attempt to make programming more user-friendly language in contexts where interpreted languages, bytecode and even garbage collection are untenable. Their docs are coming along nicely, their error messages perhaps less so.
To say that no major languages are designed for usability is laughable. In fact, I would say that every major language since and including x86 machine code has been designed with usability concerns front and center. The more recent wave of languages especially -- practically no one is trying to beat C and C++ on technical capabilities. They are trying to beat them on ergonomics.
I wouldn't be so dismissive. For starters, we seem to have different definitions for "major" and "usable".
I'd say the major languages are C, C++, C#, Java, JavaScript, Objective-C, PHP, Python, and Visual Basic. I wasn't even thinking of Ruby in that list, and I definitely wasn't including the new kids on the block (Rust, Go, Elixir, etc.) I'm not trying to get into a huge argument about what is a major language -- this is just a rough list that I had in my head and not something I'm set on.
Of those, the newest (PHP, JavaScript, and Ruby) are now 20 years old.
I'm certain that none those came with the important usability features we think of now. I'd also like to think that the science around programming has improved in 20+ years, and we're designing better languages in the 2010s than we were in the 1990s.
Again, this isn't just about syntax or the standard library. The docs and tools around the languages above are mature now, but they didn't start out that way. Rust is interesting because, unlike any of those languages, it's trying to start out with the mature docs and tools we expect in 2015.
And although I can't speak for them, everything I've read suggests that Go was not primarily designed to be usable. The creators intentionally left things out (generics are the obvious example) in their attempt to favor simplicity over usability. I'm not saying it's a bad choice, but it is a polarizing one.
I'd say the major languages are C, C++, C#, Java, JavaScript, Objective-C, PHP, Python, and Visual Basic. I wasn't even thinking of Ruby in that list, and I definitely wasn't including the new kids on the block (Rust, Go, Elixir, etc.) I'm not trying to get into a huge argument about what is a major language -- this is just a rough list that I had in my head and not something I'm set on.
Of those, the newest (PHP, JavaScript, and Ruby) are now 20 years old.
I'm certain that none those came with the important usability features we think of now. I'd also like to think that the science around programming has improved in 20+ years, and we're designing better languages in the 2010s than we were in the 1990s.
Again, this isn't just about syntax or the standard library. The docs and tools around the languages above are mature now, but they didn't start out that way. Rust is interesting because, unlike any of those languages, it's trying to start out with the mature docs and tools we expect in 2015.
And although I can't speak for them, everything I've read suggests that Go was not primarily designed to be usable. The creators intentionally left things out (generics are the obvious example) in their attempt to favor simplicity over usability. I'm not saying it's a bad choice, but it is a polarizing one.
I'd guess that many of the worst parts of PHP, and some of the best, were introduced in order to make it more usable.
If Go isn't geared towards usability, I don't think it is same definition of usability most adhere to.
Having to write a ton of boilerplate is not "usable". There are several things in Go that I've never seen written in a way that doesn't use a lot of boilerplate.
In fact, if you search for criticism of Go, that's going to be near the top.
Another is that the packages don't have version-matching.
Edit: And, again, this is not to say Go is a bad language or that people shouldn't use it. I'm just pointing out one example of where the Go authors prioritized simplicity over usability. I'm not commenting on the whole language.
In fact, if you search for criticism of Go, that's going to be near the top.
Another is that the packages don't have version-matching.
Edit: And, again, this is not to say Go is a bad language or that people shouldn't use it. I'm just pointing out one example of where the Go authors prioritized simplicity over usability. I'm not commenting on the whole language.
You started off this comment thread by asking what kind of research was done to achieve something that is usable. I like that tact because it implies that "usability" isn't something you can reason about from first principles and come up with the right answer to, "Is this software usable?" Instead, it acknowledges the fact that usability should be data driven. What do people using it think?
But your last few comments in this thread seem to have taken a different tact. You've projected some definition of usability that you hold instead of acknowledging that others may think differently. For examples, I can promise you that the Go authors don't think they "prioritized simplicity over usability." They would say that Go is very usable because it is simple.
You disagree, and that's totally cool, but we should be careful to frame it as a difference in perspective.
P.S. Rust and Go are very usable (to me). :-)
But your last few comments in this thread seem to have taken a different tact. You've projected some definition of usability that you hold instead of acknowledging that others may think differently. For examples, I can promise you that the Go authors don't think they "prioritized simplicity over usability." They would say that Go is very usable because it is simple.
You disagree, and that's totally cool, but we should be careful to frame it as a difference in perspective.
P.S. Rust and Go are very usable (to me). :-)
I can see where you're coming from, but I've posted a lot of comments on this topic, and I absolutely acknowledge that I don't feel certain about these things. For example, I'm not certain that I agree with Go authors that "simplicity = usability", but I really don't know. I plan to master Go, and then maybe I'll have a better idea.
I've also acknowledged that even my definition of "simplicity" isn't the same as everyone else's.
You seem to be reacting to my argument that boilerplate != usability, and I stand by that. Typing the same thing over and over is fragile, and it's antithetical to the concept of programming. If there's anything that I can say with absolute certainty is vital to usable programming, it's DRY.
Other than that, I really am curious to know what usability really means. I've seen a lot of interesting studies on HN that contradict commonly held notions (e.g. refactor often). It'd be so cool and important for a language to base itself entirely off of such research, rather than a small group's experiences.
I've also acknowledged that even my definition of "simplicity" isn't the same as everyone else's.
You seem to be reacting to my argument that boilerplate != usability, and I stand by that. Typing the same thing over and over is fragile, and it's antithetical to the concept of programming. If there's anything that I can say with absolute certainty is vital to usable programming, it's DRY.
Other than that, I really am curious to know what usability really means. I've seen a lot of interesting studies on HN that contradict commonly held notions (e.g. refactor often). It'd be so cool and important for a language to base itself entirely off of such research, rather than a small group's experiences.
Something being usable doesn't imply boilerplate being present or not. In fact I think most if not all languages have boilerplate. They might mitigate it with some macros, but the boilerplate is there.
Usability just means ease of use and learnability. In context of computers languages, I think having a smaller set of idioms/stuff to learn is more vital to usability than to have less stuff to type.
Usability just means ease of use and learnability. In context of computers languages, I think having a smaller set of idioms/stuff to learn is more vital to usability than to have less stuff to type.
They say generics aren't usable because they aren't simple.
I don't understand them, but they say those words.
I don't understand them, but they say those words.
The creators of Go seem to think that simplicity is achieved by removing everything that isn't totally necessary.
I'm not sure if I agree philosophically. If I do, then I'm not sure I like that kind of simplicity for writing software. I'd rather have slightly DRYer code than slightly simpler code.
I'm not sure if I agree philosophically. If I do, then I'm not sure I like that kind of simplicity for writing software. I'd rather have slightly DRYer code than slightly simpler code.
> The creators of Go seem to think that simplicity is achieved by removing everything that isn't totally necessary.
Not really. That path leads to a Forth, a Scheme, a Smalltalk.
There are plenty of things which are not necessary in Go. Many of them are eminently convenient, but could be libraried with generics: most of the built-in magically generic-even-though-the-language-doesn't-have-generic collections for a start. the special-cased multiple return values, the magical builtin functions (which generally exist as support for the aforementioned magical collections).
I've read it before, Go is not simple, it's simplistic. A simple language would by necessity give a lot of power to the developer, that's not what Go does.
There's a difficult balance to strike of course, get too simple and you end up with turing tarpit, and simple languages may make it harder to create cohesive communities. Still, calling Go simple is an insult to simple languages.
Not really. That path leads to a Forth, a Scheme, a Smalltalk.
There are plenty of things which are not necessary in Go. Many of them are eminently convenient, but could be libraried with generics: most of the built-in magically generic-even-though-the-language-doesn't-have-generic collections for a start. the special-cased multiple return values, the magical builtin functions (which generally exist as support for the aforementioned magical collections).
I've read it before, Go is not simple, it's simplistic. A simple language would by necessity give a lot of power to the developer, that's not what Go does.
There's a difficult balance to strike of course, get too simple and you end up with turing tarpit, and simple languages may make it harder to create cohesive communities. Still, calling Go simple is an insult to simple languages.
they've definitely had feedback from all the crate creators and actual daily work through - at minimum - Servo's implementation.
the primary focus has always been systems-language speed and memory safety without a gc.
the primary focus has always been systems-language speed and memory safety without a gc.
Actually the no-GC thing is pretty recent. Memory safety was the big deal, and IIRC they didn't think it could be done without a GC until sometime in the last couple years.
Ancient Rust accounted for the existence of garbage collection, but still tried to prefer zero-overhead memory management via linear types and move semantics. You are correct that it wasn't evident until much later that it would be possible to get by without GC entirely.
[deleted]
It seems like safety/correctness in general and not just memory safety is a major focus.
I should first disclaim that I'm not a member of the Rust core team, but I have been closely following and contributing to the language since 2011 and so have rather extensive insight into the arc of its evolution.
That said, my personal opinion is that usability is absolutely a primary focus of Rust. The notion of "regions" (renamed to "lifetimes" in Rust to be more user-friendly) has existed in academic literature for a while, but Rust has spent an enormous amount of effort and tried a wide variety of approaches in its quest to make this concept as accessible as possible to the everyday programmer. In other words, Rust is a research project focused on advancing the usability of safe and zero-overhead memory management.
I wouldn't say it is the primary focus, because first achieving the task of safe and zero-overhead memory management is itself a major undertaking.
Getting feedback on usability hasn't generally been achieved by formal surveys, but instead generally by brainstorming possible changes to the language and taking part in the resulting discussion. These discussions have happened in a variety of forums over the years so I can't point you to any comprehensive collection of them, but very often the ideas themselves are initially presented on the blog of Niko Matsakis, who is currently Rust's technical lead ( http://smallcultfollowing.com/babysteps/blog/categories/rust... , which is a fascinating read for those looking to understand the language's volatile history). It also involves being open to proposals from people using the language in the community, which eventually turned into the current RFC process ( https://github.com/rust-lang/rfcs ) and which is a bit like Python's PEP process.
That said, my personal opinion is that usability is absolutely a primary focus of Rust. The notion of "regions" (renamed to "lifetimes" in Rust to be more user-friendly) has existed in academic literature for a while, but Rust has spent an enormous amount of effort and tried a wide variety of approaches in its quest to make this concept as accessible as possible to the everyday programmer. In other words, Rust is a research project focused on advancing the usability of safe and zero-overhead memory management.
I wouldn't say it is the primary focus, because first achieving the task of safe and zero-overhead memory management is itself a major undertaking.
Getting feedback on usability hasn't generally been achieved by formal surveys, but instead generally by brainstorming possible changes to the language and taking part in the resulting discussion. These discussions have happened in a variety of forums over the years so I can't point you to any comprehensive collection of them, but very often the ideas themselves are initially presented on the blog of Niko Matsakis, who is currently Rust's technical lead ( http://smallcultfollowing.com/babysteps/blog/categories/rust... , which is a fascinating read for those looking to understand the language's volatile history). It also involves being open to proposals from people using the language in the community, which eventually turned into the current RFC process ( https://github.com/rust-lang/rfcs ) and which is a bit like Python's PEP process.
> Usability involves more than syntax --package
> management, interoperability, docs, and error messages.
Rust's first stab at a package manager (the original namesake for the current Cargo) was in 2011, and we had at least two others in between. The fact that Mozilla was eventually willing to contract out development of the current package manager to domain experts (the Bundler developers) should show how much we care about having a good solution to this problem early-on. It has also been a goal from the beginning to have a rock-solid and very transparent means of interoperating with C, and being able to expose Rust libraries as C libraries was also something that was desired from the outset even if it took a while for the design and implementation to materialize. Having good error messages has always been taken very seriously, and I'm happy to see that people praise us very often for the niceness of our compiler messages (though we can still be doing better in many places). As for docs, Mozilla's been contracting Steve Klabnik for over a year now to not only write a comprehensive tutorial for Rust (now a book: http://doc.rust-lang.org/nightly/book/ ), but also to write up documentation and usage examples for every single type and function in the standard library.
Hopefully this is just a case of unfamiliarity, but surely something like should be easier?