179 comments

[ 3.1 ms ] story [ 146 ms ] thread
(comment deleted)
(comment deleted)
Great to see Rustup reach 1.0 release. I like how easy it makes to test out different versions of rust and its toolchains.

I like the '..' addition for structs. It definitely improved the pattern matching over structs.

  let p = Point { x: 0, y: 1, z: 2 };
  match p {
    Point { x, .. } => println!("x is {}", x),
  }
Congrats to the Rust Team for another good release!!
Question from someone who don't know Rust: Why two dots instead of an ellipsis (three)?
Three dots doesn't look like an ellipsis in a monospaced font, it's far too wide.
It can if you use a monospaced font with ligatures.

Take a look at Fira Code [1]. I use it in Vim and IntelliJ, and it looks great with Rust and other functional languages.

[1] https://github.com/tonsky/FiraCode

Well, I'm sure you know what I meant.
I'm pretty sure he did know what you meant, and offered a serious response. I think he's suggesting that perhaps the aesthetics of the ellipsis is what prevented it from being selected.
(comment deleted)
It's already a keyword or operator (not sure which) used in range notation (1..2); why add a new operator when an old one will do?
Three dots are for inclusive ranges, two for exclusive
There must be some interesting reason why ".." and not the more common "..." - I wonder what?
They probably 'copied' Haskell here, which also uses "..".
Haskell doesn't have this feature though. I mean it does, but you can just leave out the ones you don't want matched, you don't have to put in any dots.
It's less to type. The double period is already used for lots of other things in the language, so it feels like the correct choice.
Reading through, they treat a range (like 1 .. 10 ) as pattern matching 1 2 3 4 5 6 7 8 9 10, with .. representing 2 3 4 5 6 7 8 9.

In that light, it actually makes sense.

Ah of course, that is quite widely used (e.g. Perl). If you already have that, I can see why you'd reuse the same token.

(edit: ok, I see from other replies that it's not that simple)

Minor correction, to match a range the syntax would be

  1 ... 10
No particular reason.

`..` and `...` both exist in the language, `..` is exclusive range and `...` is inclusive range. `..` is only in expressions right now, whereas `...` is only in patterns. Eventually, both will be available everywhere, possibly. At very least, `..` in patterns is getting added soon.

Since this is a pattern thing, probably `..` was chosen when `...` was the only range available in patterns, to distinguish this from that range pattern more. However, `..` will now be available in patterns, so its just historical.

(This is a longstanding feature, what's changed is just making it apply to more patterns.)

I've seen the "..." used for matching a range of values, whereas ".." is used in other places where we disregard a value while patter matching.

I'm sure someone from the rust team can give a better answer, but to me this change looks like it was just bringing the pattern matching for structs to be consistent with other uses of ".."

Relevant RFC: https://github.com/rust-lang/rfcs/blob/master/text/1492-dotd...

This is such a win for pattern matching! I tried using this exact syntax last month and I was sad to see it didn't exist. It feels so natural to see it now.

Rust is such an awesome language. Every design decision feels so right. Go, Rust, go!

(comment deleted)
Anyone know if macros 1.1 will be in 1.15?
That is the plan, yes. It's not in the beta yet, but will be backported.

(For those of you who don't pay super close attention to Rust development, that means libraries like Serde and Diesel will be as convenient to use on stable as they are on nightly, today.)

Is this the first time a feature stabilization has been made to a version that has already moved into the beta phase? My understanding was that beta was pretty much frozen except for bug fixes.
Yes. It's a perfect storm of coincidences, basically. It's a combination of timing + a tiny feature.

Let's take a step back. Macros 1.1 is RFC 1681: https://github.com/rust-lang/rfcs/blob/master/text/1681-macr...

See the section saying "The initial implementation of librustc_macro is proposed to be incredibly bare bones:" it really is very, very small. So it landed, and while there was some questions that came up, people migrated to it, and it works well.

22 days ago, it was to be reviewed: https://github.com/rust-lang/rust/issues/35900#issuecomment-...

However, two things happened: one, the Mozilla all-hands in Hawaii, which shook things up, but secondly, that meant a lot of people, including one of the reviewers, took PTO around that time, to actually see some of the islands. That includes someone who was on the reviewers list. So in general, "oh hey this is waiting on one person who forgot to check a box but isn't reachable now" is awkward.

Luckily, in this case, we know that it was just forgetting to check the box; Felix did not have any objections that we were aware of. So we decided to sign off for him, and put it into FCP. This happened so that FCP technically passed the deadline for 1.15, but given how important it is to ship, we're planning on nominating it for a backport, and don't anticipate complaints.

So: tiny feature, code wise. Big win for being stable. Procedural mishap involving awkward scheduling. All these things played into it. Make sense?

I'm psyched to try wasm. Are there any crates which provide interfaces to things like a canvas object?
Depending on the cargo version, wasm might not actually work in 1.14 (couldn't check which version it uses yet). It's definitely broken in the next release, which is quite unfortunate :/
Why the heck do all the platforms have 'unknown' in them? It seems stupid.

> mips-unknown-linux-gnu > wasm32-unknown-emscripten > arm-unknown-linux-musleabi

What value does that garbage add to it?

Historically, that part of a target triple is used to indicate a specific "vendor," so you have "mips-unknown-linux-gnu" vs "mips-debian-linux-gnu", where the former is for all linuxes, but the latter is specific to Debian.

See here: http://clang.llvm.org/docs/CrossCompilation.html#target-trip...

So a target triple is really a target quad (makes perfect sense). Tbh, leaving it out would or using the word "generic" would be far better than unknown.
Leaving it out means that it's harder to parse, which isn't the worst thing in the world, but the explicitness is helpful, IMO.

"generic" would work too, but this is a long-standing convention, so that ship has probably sailed.

Harder to parse is one thing, but if it could match the output of config.guess, and/or allow to skip the "unknown" part so that the triples match what's used for GCC prefixes and clang's --target, that would be way nicer.

https://github.com/rust-lang/rust/issues/33147

You already leave out the ABI for some kernels (e.g. x86_64-apple-darwin), so it would be ambiguous otherwise.
That's how target triples work.

http://wiki.osdev.org/Target_Triplet

The "unknown" is the vendor field. Most linux OSes don't have a "vendor".

Target triples are of the form arch-vendor-kernel, and the -kernel is sometimes in the form -kernel-abi)

So you can have x86_64-pc-windows-gnu or x86_64-pc-windows-msvc or x86_64-apple-darwin with the vendor field set.

Most of the OSes with non-unknown vendors already have Rust binaries, so most new platforms will be unknown.

Thank you !

Maybe this could be documented somewhere on the rustup doc so new users like me aren't puzzled by this strange “unknown” everywhere. Or maybe it is, and I just didn't find it because I was too lazy to look explicitly for it …

Write your Rust app. Compile to a binary on the backend, wasm on the frontend, using asyncio to communicate transparently between the two. Update the DOM directly from wasm, with 60fps rendering from Servo's WebRender. Totally typesafe and lightening fast.

It could all be so beautiful.

And it will never happen (ok, maybe "never" is too strong - it will happen 10-15 years from now, at best and even then it will be unstable/unreliable/slow/half baked on some platforms, because reasons). The best we've got is the piece meal approach of HTML/Javascript/CSS.

And before you blame those standards, blame the Unix vendors^W^W, pardon me, the platform owners (Microsoft, Apple, Google).

Why won't it happen? If wasm can talk to the DOM, then you'll still be using HTML and CSS, and wasm in place of JS. There's no reason this couldn't be done already by just compiling to JS, and plenty of languages already do that.

You could also render everything to a canvas to avoid HTML and CSS, but at that point there are a lot of things to re-implement, especially around accessibility.

Well, first of all wasm needs to be implemented in all major browsers on all major platforms for it to be widely adopted. Since the major browser vendors are backing it, that should happen quite soon.

But that's just the initial implementation. It needs to be implemented fully, debugged, optimized and then it needs to trickle down to user devices, including those sold 3-4-5 years ago and still in use.

And then, in the second stage, wasm needs to get DOM access (as far as I know v1 won't have it). See stage 1, all over again.

I'd say that the mass adoption cycle for 1 stage is roughly 5 years (where 80%+ of the browsers out there support a major feature well). So 2 stages x 5 years = 10 years.

Maybe I'm too pessimistic...

Given the history of the web and what I know of the people/companies behind wasm, it seems very likely that there'll be a graceful degradation/shim in the form of a wasm interpreter written in JS/asm.JS (or even a JIT from wasm to one of them), so there'll be no need to wait for all browsers to have implemented it, it just won't live up to its performance on all platforms.
I think you are being too pessimistic about the speed of mass adoption.

On the desktop: Firefox, Chrome and Edge auto-update.

On mobile: Android 4.4+ (over 80% and rising fast) auto-updates its webview component. iOS receives yearly updates that are applied by a very large majority - though Apple's browser development does seem to have stagnated a bit.

So it seems to me that non-updating browsers are going extinct, and that we won't be dealing with another IE6 anytime soon. We're living in the future! :-)

The age of the evergreen-browsers is dawning. Although it will be years before the last corporate holdouts let go of their pinned IE9/IE10/IE11 browsers.
Why is 80% the magic number? 5% would reach more than 100 million people. That's enough to keep a team busy and a product growing while the competition sits on its butt waiting for the next 75%.
There is a shim so you don't need to wait for all the browsers to implement wasm
I hate JS but replacing it with Rust for front end is a bad idea, Rust is a low level systems programming language, it's very suboptimal for high level front end code from productivity standpoint and it adds no value because it's advantages (mem safety with 0 cost abstractions) don't really matter in frontend (JS is super bad at being optimizable but it's still more than sufficiently fast).
Rust is indeed known for memory safety and zero cost abstractions. But there is another side to Rust which is even more interesting - a type system that is almost as powerful as those of functional languages like OCaml and Haskell, but wrapped in approachable imperative syntax.

With such a type system, it is possible to encode the invariants of your application in types (using generics and algebraic data types). Then you can get very close to "if it compiles, it works".

JS, in particular, is the opposite. I am never really convinced that any JS I have written is "correct". It works, until one day it doesn't. This is such a problem that there have been multiple attempts to retrofit type-systems on top of it.

Rust needn't be the only language that brings strong typing to the frontend (Elm has been around for years now). But I think the prospect of speed and correctness both front and back is pretty exciting.

>But there is another side to Rust which is even more interesting - a type system that is almost as powerful as those of functional languages like OCaml and Haskell, but wrapped in approachable imperative syntax.

That type system is pretty verbose because it's aimed at manual memory management which you don't really care about in front end, and the compile times are huge compared to say TypeScript or something along those lines so yeah - I agree static typing is nice - but saying you should use Rust for front-end because it has static typing is like saying every gardener should have an excavator because digging holes with hands sucks - shovels exist.

I don't necessarily disagree with you, but when wasm is fully established I expect to see (another) step change in the complexity of the web. Fully-featured applications, 3D, VR, AR etc. We are on the brink of it already. And beyond a certain complexity (a relatively small amount of complexity, I would argue), a decent type system is essential.

Rust just happens to be well positioned to take advantage of all this.

Are you saying because it can do A it can't do B?

Are A and B mutually exclusive per se or is that just an unfounded assumption?

It's a design trade off. I don't get why people are so pissy about it - Rust makes design choices that are suited for low level systems programming language - but it has a lot of noise and complicated things from high level language stand point, and compile times + debugging + lack of run time tweak-ability make it very unproductive for front end compared to say TS/JS
I use Rust for web 1 year already and I can say it's awesome. Try.
But on the backend, not on the client, I presume? If you've really been deploying Rust over the wire via asm.js, then some commendations are in order for your persistence. :P
Yes, of course. But in parallel I write code in TypeScript (frontend) and after few months performance is equivalent in both languages. Only difference - no runtime errors in Rust.
Are you joking ? You can have hot module replacement in TypeScript meaning you don't even have to refresh the page to get new code in browser - and then you can fire up the REPL and prototype stuff - Rust has to go trough rebuild+redeploy on every iteration - you're saying that's the same speed ?
No. I don't use hot module replacement and I don't like this idea. And I don't prototype things often - maybe once or 2 per year - my contracts are usually long enough. It's all personal, as you see.

I'm saying that to implement feature in Rust takes same time as in Typescript or PHP (as PHP is a server side language also and comparison is more illustrative).

memory safety isn't the only advantage.

0 cost abstractions do matter a bit. In general abstractions let you do high level programming in lower level languages.

The type system matters a lot.

I used to do a lot of scripting. One thing I really missed was having a good static type system. These days I miss ADT enums in all languages.

Scripting is already moving in the direction of being more type safe (typescript, python type annotations), which is awesome, but I'd love to use something like Rust in that sphere.

I love JS (pretty unpopular opinion here on HN) and I love Rust also and I'm not convinced using Rust on front-end tasks would have any benefits. Yet, I strongly disagree with you on this point :

> Rust is a low level systems programming language, it's very suboptimal for high level front end code from productivity standpoint

Rust's type system is wonderful, and it's a real productivity boost. Fortunately people at Facebook developed an equivalent for JavaScript [1] because living without it would be really hard for me now. Furthermore, Rust offers a lot of syntactic sugar that makes it feel like a really high level language (compared to C, Go or even JavaScript pre-ES6 for instance).

>it's advantages (mem safety with 0 cost abstractions) don't really matter in frontend

It's indeed one of Rust selling point (especially for people coming from a C background) but it's not the only one. My favorite being the data-race free parallelism. I don't know the current status of multi threading in wasm, but being able to take advantage of all the cores of mobile devices could really help front-end frameworks.

[1]: http://flowtype.org, it's not inspired by Rust but inspired by OCaml, which also inspired Rust.

>Rust's type system is wonderful, and it's a real productivity boost.

Rust type system is verbose compared to higher level languages and it lacks a lot of the things that make higher level languages productive. It just focuses on low level code - which is good - but you wouldn't use it in place of C#, you would use it instead of C++, and you don't want to write GUI code in C++ either (even Qt uses JS for the frontend)

>My favorite being the data-race free parallelism.

Also mostly irrelevant in front end since you're dealing with single threaded event loops and doing parallel work that talks to UI thread is easy. Stuff that needs to do work in parallel can be written in Rust and talk to front end via FFI or RPC.

> even Qt uses JS for the frontend

Only if you use QtQuick. The traditional QWidget API is C++ all the way.

If you don't like it, you don't have to use it. The beauty of WebAssembly is that it can be targeted by so many other things. Finally, we can let JS sink or swim on its own, without being propped by an artificial monopoly on the web frontend scripting...
(comment deleted)
There doesn't seem to be anything unstable about it, even now. I've compiled tons of Rust code to asm.js over the last few months and there's not a single thing that didn't work. Modifying the DOM also works fairly well (you have to write wrappers though). And the code is 10x to 40x faster than the equivalent JS code. And you can run the exact same code natively on tons of platforms too. So it's already quite amazing.
One package that doesn't work yet, last I heard, is regex. That's a big one.
I'm not 100% sure if I tried it in any of my apps, but I think I did, and can't recall it not working. I'll try again soon and will tell you if it works.
Please fill me in too, possibly filling an issue on the regex repo if there's anything I can do to help. (This is the first I'm hearing of the problem.)
I had only heard of it second hand; I thought it was already communicated upstream. Oops!
Yeah, if your app happens to be the same on the frontend and backend.
There are benefits even if you aren't sharing the entire back-end. I develop an internal Mojolicious webapp, and there's been quite a few times where I would have loved to just have one or two of the backend libraries I've written available to JS, so I wouldn't have to write it again in JS or pass it to the server. Just knowing that I could write it once and have it be the same in both places, even if I changed it later, would be a real boon.
Exactly. Everytime I write a feature, I have to decide whether it's a backend feature or a frontend feature. Sometimes I get it wrong. I'd like to not lock myself into my choice.
That's a better fit for Scala imo. ScalaJS is great as is, and I'm sure a wasm Scala backend would be amazing.

Rust is way too low-level for that imo. It works for Emscripten because of legacy code, but Rust is still ways off in that regard (i.e. adoption).

My impression was that wasm doesn't provide GC. Since Scala needs GC, Rust seems better positioned to have a first mover advantage.
I did not know that. There is work being done in this area through the Scala Native project, so it's still feasible.
Having attempted this "isomorphism" across Scala and ScalaJS, it is not quite that easy. That goes for all setups (node -> JS, Java -> GWT, etc) that I have tried. There are a lot of what some might call "impedance mismatches" between the two targets especially when it comes to communication and DOM work. IMO only frameworks/middleware built to bridge the gap will make it seamless.
In my experience Scala(.js) works way better than "(node -> JS, Java -> GWT, etc)".

There is a large gap between those and the way Scala _just works_ across platforms.

The huge difference is that you can depend on libraries and have them "just work" regardless of whether they are implemented identical on each platform, or need specific variations to implement the expected features.

Neither JS/Node nor Java/GWT have that.

> using asyncio

Don't hold your breath.

Unfortunately, the community seems to be going the way of Ruby/Python/C++: massive fragmentation.

What evidence do you have of this? Almost everyone is rallying around tokio.
Yeah tokio and futures-rs rock. Have there been talks of futures becoming part of std?
Many feel that it's likely that the future trait itself could become part of libcore. It's still far too early days to tell, though.
> the future trait itself could become part of libcore

_Please_ make this so.

> still far too early

I've waited 3 years, more time probably couldn't hurt.

> Almost everyone is rallying around tokio.

Sure - just as everyone "rallies" around EventMachine in Ruby.

This discussion has been going on for almost 3 years now.

It's great that tokio is making community headwinds, Twisted, Gevent, Celluloid, EventMachine all did too.

The problem is, they've never reached critical mass, and their respective languages refused to bless them as "official."

> What evidence do you have of this?

The issue is inter-library compatibility.

https://github.com/tailhook/rotor

https://github.com/tokio-rs/tokio

Totally incompatible, even though they build on the same low level library.

https://github.com/mitsuhiko/redis-rs

Oh wow, a great redis library - objectively the most popular. Completely incompatible with all of the above AIO implementations.

Let's take it to the extreme:

- Incompatible memcached client implementations: - https://github.com/aisk/rust-memcache (sync) - https://github.com/zonyitoo/memcached-rs (sync) - https://github.com/samphippen/decachedmem (tokio, partially implemented)

- Incompatible redis client implementations: - https://github.com/tokio-rs/tokio-redis (async via tokio) - https://github.com/mitsuhiko/redis-rs (sync) - https://github.com/AsoSunag/redis-client

- Incompatible HTTP client implementations: - https://github.com/matt2xu/async-http-client/ (tokio, new) - https://gitlab.com/imp/requests-rs.git (hyper, sync) - https://crates.io/crates/reqwest (hyper) - https://crates.io/crates/request

The list goes on.

There are countless libraries implemented with synchronous I/O, there are countless (good) popular libraries implemented with non-Tokio-based concurrency primitives.

Let me just say it: I really, really like Rust.

But I cannot feasibly use it for network/server-related tasks until a single solution is blessed by the Rust team.

The "let's let the community handle standardizing async IO and concurrency" approach has _never_ worked in the somewhat brief history of programming languages.

A blessed solution though? - Erlang, Golang, Node/JS* All work flawlessly.

I would use Rust full-time for every server-related task if I could, but I've been observing for 3 years and unfortunately haven't seen much development after the abandonment of builtin green threading.

*- codestyles sometimes incompatible, but there was _never_ a litany of sync libraries or otherwise fundamentally incompatible systems.

> just as everyone "rallies" around EventMachine in Ruby.

You can't really compare things this way. Very few people even use EventMachine, as it has significant issues.

You can't just show that rotor and tokio are two different libraries; you've claimed that there's significant ecosystem fragementation. That's a very different claim. The same goes for the other three sets of links below: that you can find a bunch of GitHub repositories does not mean that there's actual fragmentation. Writing a memcached or Redis client is a good way to learn a language, even: I've known two people who independently did so for memcached + Rust, tossed them up on github, and that's it. (one of those is one of the links you've provided above, even.)

> Oh wow, a great redis library - objectively the most popular. Completely incompatible with all of the above AIO implementations.

Because it's synchronous. Once tokio has an actual 0.1 release of the full stack, which is to happen any day now, you'll see more consolidation.

> until a single solution is blessed by the Rust team.

Two of three of tokio's core team members are Rust core team members. We had a full talk on it at RustConf, and it was mentioned in the keynote. Mozilla has sponsored development of it in places.

  > their respective languages refused to bless them as 
  > "official."
Tokio is literally developed by 1) the Rust developers and 2) contractors paid by Mozilla to work on Tokio. It's as official as Cargo is. :P
The "Rust team" isn't picking winners, but they do happen to be contributing to and creating the leading solutions. There is a lot of energy around futures and tokio, very early on in the story of Rust. Sure, Rust has already been around for a while, but 1.0 was only last year.

If you like Rust, and you want to use it for network and server related tasks, get involved. Write the redis, memcache, HTTP clients of your dreams. Rally the people who've solved those problems in Rust (and elsewhere) in the past.

Please try to state your concerns (or better yet, ask questions) in a more thoughtful manner.

>The "Rust team" isn't picking winners

It would be better if they would, though, is what some of us are thinking.

Between "totally chaotic third-party libs landscape" and "official lib designed with the language and part of the standard library", picking winners is a great middle ground.

> Twisted, Gevent, Celluloid, EventMachine all did too. The problem is, they've never reached critical mass, and their respective languages refused to bless them as "official."

At least in the case of Twisted, it probably didn't help that for a long time it was GPL licensed with all community contributions requiring copyright assignment to the lead developer.

Rust is a magnet for creative, intelligent people. There are bound to be lots of implementations for things like low-level I/O because lots of people want to explore the relationship between the OS, the application and the hardware. That is different than fragmentation in the sense you're implying.

The Rust community is pretty unified, esp. as its communication channels are well defined. For asyncio, I am pretty sure that Tokio will be the tool for most applications.

> That is different than fragmentation in the sense you're implying.

It is! But there are a mass of completely incompatible, overwhelmingly popular libraries.

> For asyncio, I am pretty sure that Tokio will be the tool for most applications.

When?

> When?

Tokio was only released along with futures like 3 months ago? It takes time to rebuild software on top of that. It definitely took me time to port from directly using MIO to using tokio.

After evaluating others options, I do believe tokio will be the default for most people.

Tokio is already eating the ecosystem, voluntarily. The authors of the only other two competitors, Rotor and GJ, told me at Rust Belt Rust that they're planning on deprecating their projects and throwing in with Tokio (perhaps largely thanks to the fact that the Rust/Mio devs asked them both for their input during the design of Tokio).
>There are bound to be lots of implementations for things like low-level I/O because lots of people want to explore the relationship between the OS, the application and the hardware.

You say it like it's a good thing.

> You say it like it's a good thing.

Why wouldn't it be? Let people experiment. As long as there's a standard, go-to library for applications that need to "just-work", I don't see any reason not to explore new ideas and find potentially better solutions for the future.

I agree it's an issue. Java and C# also suffer from it. In Java probably each webserver implements it's own network framework on top of NIO and in the end you have dozens of incompatible event loops runing.

However it's not an easy issue to solve for a general purpose language, unless you want to tie all those IO semantics (and probably a big runtime environment) directly to the language. C++ and Rust don't want to do that, since they want you to be able to use the language even on bare metal with zero runtime.

What you can do as a library developer for these languages is to try to make them as integretable as possible into all kinds of surrounding environments. I normally would try to make my library usable for blocking calls as well as in a nonblocking way within an external eventloop. You can do that by spawning your own thread/eventloop, handle all the library logic in there and provide thread-safe external APIs that communicate with our eventloop.

Framework development (in the sense of Netty/Tokio/etc) is harder. If often won't be possible to develop code that runs in multiple frameworks.

> experimental support for WebAssembly as a target, wasm32-unknown-emscripten [...] check out Tim’s example of the classic TodoMVC project.

On one hand this is really cool and potential for client-side Rust. On the other hand:

    let id = node.parent().unwrap().parent().unwrap().data_get("id").unwrap().parse::<usize>().unwrap();
Eh, no thanks. :) If I could get a macro or shorthand for that, I'd welcome all the other benefits of a large scale client-side platform with strong typing.
(comment deleted)
When the carrier trait lands this becomes:

    let id = node.parent()?
                 .parent()?
                 .data_get("id")?
                 .parse::<usize>()
                 .ok()?;
I'd also expect that someone will write higher level libraries so that you aren't doing raw DOM manipulation. A rust vdom wasm library would probably be blazing fast.
> A rust vdom wasm library would probably be blazing fast.

Most of the cost of vdom is the resulting DOM ops and reflow/restyle the browser needs to do. It may be faster than the fastest today, but you're unlikely to see any kind of performance leap or even anything noticeable.

Small note, we don't _technically have to stabilize Carrier to land this, just implement it for Option. (yay standard library types) However, ? for Option is a bit controversial, so we'll see...
> However, ? for Option is a bit controversial

Because people wouldn't expect it to return due to behaviour of existing languages yet that's what it does in Rust?

More because Option is not really intended to handle errors while Result and ? are.
Yes, that's correct. If we make ? go to more than just result, you could implement it for any type, and it's not totally clear that changing it from "error handling" to "general control flow" is a good idea.

Many are in favor of doing it, though. I'm personally against it.

Whether it's ? or something else, having a very concise form of syntactic sugar to unwrap option types is desirable. Most languages that don't have it, eventually acquire it due to demand.
The "?" operator looks like a more specialized, error/success-specific version of monads. Has there been any discussion about generalizing everything into monad-style chaining operators?

I see that there is some discussion here [1], including a suggestion to add a Haskell-style "do" block. But that's just one guy's blog post.

[1] https://m4rw3r.github.io/rust-questionmark-operator.

Yes, that was endlessly discussed as part of all of this. The TL;DR is: it's not simple. ? is very straightforward and helps people out a lot today. So if and when (and it is a big if) Rust ever gets do notation, this might be a little redundant, but blocking one of people's largest pain points today is worth the (possible) little bit of redundancy.
Thanks, that makes perfect sense. I haven't followed the internal discussion at all.

It sounds like there are some that would like to move Rust in the direction of becoming more Haskell/ML-like (which is to say more purely functional) rather than the current balance between imperative and functional? Is there any internal tension in that regard?

It's not even a philosophical difference, really, there are technical objections that would have to be addressed somehow before it would even be possible, let alone figure out if it's a feature that's desired. These involve things like "it's still unclear if HKT is going to end up in Rust or not, and how", which is a pre-requirement, as just one example.
I believe one of the biggest obstacles to a general monad system in Rust is that the type system can't actually handle it at the moment - it requires higher-kinded types, which may or may not ever actually be added to the language.
There's another problem too: a monad trait would unify types behind a monadic interface, but many things that in Haskell are types, are traits in Rust. This is because Rust requires a single type to have uniform memory representation and to be statically dispatchable (save for trait objects). So in Rust, there is not just an "iterator type", but multiple types that have the Iterator trait. The same goes for Future trait.

This leads to a situation where, if there were to be a monad trait, that trait should abstract over not only types, but another traits generically.

Not to speak about some other hurdles, like lifetimes. The design space is inherently more convoluted than in languages with boxed, possibly dynamically dispatched types. It may be possible, but it's not easy, and we can't copy the monads straightforwardly from Haskell or Scala.

Good point! A whole other set of things also need to be hoisted to make this work.
The semantics of ? are different from monadic bind and fit better to Rust's language context of strictness, imperativeness, and mutability than Monad (which is a problematic type class in Rust for some separate reasons).
Even without the ? sugar I don't see what's so offensive about this; the least little formatting effort produces:

    let id = node.parent().unwrap()
                 .parent().unwrap()
                 .data_get("id").unwrap()
                 .parse::<usize>().unwrap();
If there is something horrible about that I don't see it.
It hurts to type sometimes. Typing at work isn't really an issue since I have an ergonomic keyboard, but big side projects can sometimes hurt.

? is far easier and faster to type than .unwrap().

So no, there's nothing horrible that I see, there is something horrible that I feel though.

> If there is something horrible about that I don't see it.

Isn't unwrap():

a) boilerplate

b) repetitive?

It's boilerplate in a certain sense. Those are all points where what you've written might not work. Rust makes you deal with possible problems _somehow_. Specifically, this is a replacement for null. If you legitimately don't care, then it can feel boilerplate-y, but it also lets you start by not having to care, and then searching for unwrap and replacing it with better handling.

In other words, it's boilerplate here because this particular operation has many possible failure modes, and Rust is pointing those out to you.

It's repetitive in this particular instance, but doesn't have to be in general.

c) a bad practice since it will make your program crash is a node has no parent.

if the node always having a parent is a invariant of your application, you should use `expect` with a clear error message when the invariant is broken.

if your node can have no parents then you want to handle this case explicitly with a `if let Some(parent) = node.parent() {` pattern.

(comment deleted)
Some people prefer their languages to be more concise, and the safety of the the option objects (and the requirement of the unwrap() calls in the function chain) feels unwieldy. Moreover, as the unwrap() calls could panic if there's no attribute, the more complete handling of it is even longer (match calls and following the successful path).

This could be a function to isolate just the attribute you need, but seeing the example as it is presented can be off-putting from people used to scripting languages like ruby/python, which are more concise.

Unwrap will panic if no parent is found, whereas the `?` operator allows for a clean handling of this situation.

Dealing with this case properly without using a single `?`, gets really ugly with a lot of nested

    if let Some(parent) = node.parent() {
This is NOT idiomatic Rust. If you're new to Rust, please don't let this give you a taste for the language. Clean Rust code looks very elegant.
how would this be written idiomatically today?
With proper error handling instead of unwrap(), which means "I don't care about errors here".
What does proper error handling look like when I want to use the same "invalid node" error for most of those unwrap calls?
Use "try" or "?" if possible, pattern matching otherwise.
You can use map or and_then, you can write a macro, you can use try!, you can use if let, etc. There are lots of ways to handle errors in rust.
There are so many nice options here.

For the cleanest code, I would use `?` and a `From` impl for the error transformation.

If I didn't want to use `From`, I'd use `map_err`, `and_then`, etc. Both the Result and Option types have wonderful interfaces for chaining.

I wish it were u and e rather than unwrap/expect. Or just "yolo" or "!" or something.

Is there a way to rename / alias methods like that?

edit: I see ? is going to be a trait you can implement to do that, so that'll be nice (probably).

There is: make a trait called SimplerUnwrap<T> or something with the method u(self) -> T. Implement it for Option<T> and you are good to go!
Why not use C instead? I see no benefit to use complicated language which cares about errors and then completely ignore that care.
Because while you may not care at first, you will later, and Rust will help you out then.
You're not ignoring errors with unwrap(): if there is an error, the program will print out a stack trace and exit. If you have some operation that could potentially fail but you know it won't (like if you are sure that node has a parent) what do you do? If the operation actually does return an error, it means what you thought to be true was wrong, and in some cases that means something has gone seriously wrong, and your program should immediately stop so you can debug it. You can try to handle the error yourself, using try! or the ? operator, but unless you plan to be able to recover from that error, or you want to output a more end-user-friendly error message than a stack trace, what's the point?
(comment deleted)
I'd like to see some sort of macro for DOM navigation that takes a node and an XPATH expression or something, and the macro expands it to the above. Never played around with macros in Rust, so I don't know how involved that would be, or even if it would be possible.
Every unwrap() is the point, where you need to check return value for an error, unless you are writing one-time code.

If you don't care about errors, don't use Rust. Use C instead. Simple solution.

So, I see tons of unwrap() in Rust code I've looked at in the wild. I understand the concept of unwrap() and Option types. What would this type of code look like with proper error handling? It seems like it'd devolve into a ton of if-then statements like in C.
First, you'd use match statements instead of if-then so the worst case scenario already looks much better than in C, especially since Rust has enum decomposition and makes expressions first class (you can do let y = if (...) { y } else { z }). There are a lot of ways of combining control flow and assignment operators to decompose union types like Option and Result (which is Option with error E instead of None). For example, you can do if let, while let, or let x = match(y) { ... } that allow you to handle errors without jumping through hoops like you would with C returns or C++ exceptions. For a library consumer this covers a large number of cases.

Second, most of the time you can use the ? operator to greatly simplify error handling. Any code path that shares the same error type can just pass through errors as if they were an exception. The ? operator is also aware of Into/From trait implementations so in many (or even majority of) cases you can use the ? operator even if the function you're calling has a different error type! If I remember correctly, you can even exploit the module system to provide a per-file Into/From implementation for your custom error type if it doesn't map cleanly across use cases (they just have to be in the same module as the type). Rust's zero cost abstractions and trait system make it really easy to reduce boilerplate without compromising on readibility or discoverability.

Third, the Result type has a number of functional operators for responding to and combining results. You can do Result.and_then(...) with a closure or function call to do something when there is no error and Result.or_else(...) to do something when there is an error. You can use the and or or operators to combine multiple results and there are many other utility functions that are universal to Rust error handling that make the entire experience very pleasant, composable, and readable with a little experience.

It does turn into if-then statements (some implicit, e.g. via try! or ?), if done properly. But I don't understand the objection or calling it "devolving". Errors have to be handled. This way is as efficient as any other. And, in my view, is cleaner than exception handling systems.
Errors have to be handled

This is a highly contentious assertion, and I don't think it's true for most programs, at least not in the way you're suggesting.

Most of the point of exceptions is that errors don't have to be handled; or rather, in most application software, almost all errors should be handled high up in the stack, near the event loop or server request / response dispatcher.

This is the same in rust. Panics end at thread boundaries. So you'd have some event loop with threads / coroutines doing stuff and if they panic you handle it at the top level.
There are errors, and there are errors.

The kind of error that you'd handle high up the stack is, say, a general I/O error reading a file.

But when you look up an item in a collection (or a node in a DOM tree), and it is not found, the only place where you can sensibly handle that is right where the lookup happens, usually.

In a language that doesn't follow this philosophy, what you get instead are random NullPointerExceptions etc. If you go and look at a random C# or Java project on GitHub and check its tracker, you will see that - surprise, surprise! - that is exactly the type of error that shows up most.

Null pointer exceptions are programming errors. They're usually better handled up the stack too.

An item not found in a collection or tree is not an error.

How exactly do you handle a null pointer exception?
Programming errors in production are usually handled by logging and then either exiting the process or going back around the request / response loop again (presuming global state hasn't been polluted, which is unusual in most modern application servers since they're usually stateless).

Null pointer exceptions are little different.

"feature request": please announce what is new in beta also. Maybe I'm not alone on beta and if I would knew about web-assembly in beta, I'd test it 6 weeks ago :)
We used to do this, but it made release announcements feel redundant, and part of the beta process is making sure that we don't need to back anything out, so we can't even 100% guarantee that beta is absolutely going to have whatever feature.
I have a question for Rust users: let's say I'd want to write a system tool that has to run on multiple platforms (Windows/Linux/Mac) and that would integrate with all sorts of command line utilities.

I'm interested in using Rust, but would Rust be a good fit for this? The tool would be long lived so I'd want a statically typed language with a modern type system and as many safety guarantees as possible. But I'd also want a high level programming language and also libraries that would help with that integration (launching processes, capturing output, monitoring progress, parsing output: text, JSON, XML, etc., etc.). I'd also want a tool that runs quickly but I figure there's no point in mentioning that in a thread about a language that compiles to native code and that has no garbage collector :)

This should be an area of strength in Rust, at least conceptually. If a systems language can't write system utilities, well...

There is at least some degree of support for everything on your list, though it's kinda hard to tell with some of the ways in which you're being vague (not that that's bad, mind you, just recognizing that this answer is also kind of generic because of it.)

I'm not quite sure what you mean when you say "integrate with all sorts of command line utilities", but based on the other things you write I could not think of a better language than Rust.

Since I started to write some Rust code about 6 months ago, Rust has replaced Python as the language I think in. Static typing with a modern typing system is awesome, and not having to think about a GC is also awesome (see also the recent Medium article about all the ways GC's need to be tunable).

Rust sounds perfect for what you want to do. It takes a bit of practice to get used to its parsing, since it's extremely safe, but when you get things running, they run very well. As for cross-platform capabilities, it has fairly mature support across all the mainstream OS platforms, and developing support for others such as ARM. Check out this page (https://forge.rust-lang.org/platform-support.html) for more information on Rust's platform support.
I totally agree.

@oblio you should have a look at the “24 days of Rust” blog series[1] which covers a lot of aspect of the Rust ecosystem (serialization, error handling, path management, configuration handling etc.)

[1] https://siciarz.net/24-days-of-rust-working-json/

I'd recommend Scala(JVM, .js, Native, season to taste)
In short: Yes!

Process launching/capturing output/etc is there and very robust across platforms. Most of the other stuff you've mentioned I've seen support for but haven't used it in anger yet.

Bonus: Cross-compiling to other platforms is straightforward so you can build OSX/Linux/Windows all from one box.

You just asked in a Rust thread if Rust was a good language to use...
For years we actively told people not to use Rust, to run far far away, because we were still breaking things and didn't want anyone mad at us. Now that we're past 1.0, we've got a lot of catching up to do. :)

(But seriously, we're usually quick to tell people when Rust isn't a good fit for their problem domain. It just so happens that the grandparent comment is describing a domain that Rust is really quite suited for.)

  > let's say I'd want to write a system tool that has to run 
  > on multiple platforms (Windows/Linux/Mac) and that would 
  > integrate with all sorts of command line utilities.
Sounds like you'd enjoy taking a closer look at ripgrep, which is exactly what you describe: http://blog.burntsushi.net/ripgrep/
Congratulations and thank you to the Rust team! As always, I've updated my Rust Docker image[0] for 1.14 (both the latest and 1.14.0 tags) for anyone who has Docker installed and wants to try Rust out quickly. Although with how easy Rust is to install via Rustup now, the value of this image is diminished somewhat. :}

[0] https://hub.docker.com/r/jimmycuadra/rust/

Love Rust. That said, I have not figured out the following, and I'm sure that there has to be a canonical solution for this:

I have a Rust application that depends on 1 crate from crates.io. I want to build it on an embedded device over serial that has no networking capabilities. Does Cargo have an 'offline mode' or something that I can use to say "I don't want to depend on the Internet to build this, just fetch this version of the crate and keep it?" Because I have not been able to find anything like that. I'm sure there's a good solution for it because Rust is billed as a systems language.

I read the first and last link, had not seen the second. Looks like what I need, thank you. Surprised that Rust seems to expect people to have Internet access to build.
As the FAQ says, it only expects it when it needs to get something from the internet, which is a pretty reasonable default. I am biased, though ;)
Is this similar to nuget, if your familiar with that? Ie, do you have "pinned" versions in a project and only need to access the internet when a package is missing?
I haven't used nuget a whole ton, but yes, that sounds like it. Basically, you have two files: Cargo.toml and Cargo.lock. The toml file declares what version ranges you want to use, then after a successful build, the exact versions used were put into the lockfile. After that, nothing will hit the network or change up versions until you either modify the version ranges in the toml file or use the command-line interface to ask to upgrade.
In that case, it may also make sense to consider using the cross compilation capabilities in rust rather than building on the actual device.
Yes, I considered cross compiling. However I have run into this problem often enough to want a real offline solution and to me it is simply unacceptable for a systems language to depend the Internet for builds involving external packages.
Sure, I don't think the two are incompatible. One could want to cross compile and not want to require internet access.
Fork it as a submodule in your repository, then change the Cargo.toml to point to the path by using

    [dependencies.somepackage]
    path = "./somepackage"
Sorted.
Any plan to integrate rusti (or another REPL) in the basic tool kit, the way cargo is part of it?
If one comes along, it's very possible. rusti describes itself as experimental still, as far as I know.