7 ms·
Rust 1.26 released
- steveklabnik 8y agoSo, so, so much stuff in this release! The next few are shaping up to be similar. Very exciting times! As always, happy to answer questions, provide context, etc.
- zer 8y agoimpl Trait and the second edition of the book; very nice! Congrats on the release! Question: Is there any way to preview what the book's typesetting looks like, since there's praise in the release note?
- steveklabnik 8y agoI am not sure to be honest, I think NoStarch has a preview chapter on the page for the book, which would show it off.
- zer 8y agoYou're right, I totally missed that link. Thank you! It shows off Chapter 3, and yes, it really looks great.
- squiguy7 8y agoIn this example: fn foo(x: i32) -> Box<Iterator<Item = i32>> { let iter = vec![1, 2, 3] .into_iter() .map(|x| x + 1); if x % 2 == 0 { Box::new(iter.filter(|x| x % 2 == 0)) } else { Box::new(iter) } } Why is it that I can't return `impl Iterator<Item = i32>`? Doesn't the `Filter` type implement `Iterator` for the same associated type?
- wcrichton 8y agoThe guarantee of `impl Trait` is that if I want to call a trait method on the returned object, e.g. for iterators if I want to call `foo(0).next()`, then the function pointer will always be in the same place on the object in memory (static dispatch). By contrast, if I returned a boxed trait, then calling the trait method requires a dynamic lookup to find the method on the boxed object, and then jumping to that function (dynamic dispatch). In this example, `iter.map(..)` and `iter.filter(..)` return two different implementations of the Iterator trait, so dynamic dispatch is required. In general, if your function returns multiple possible implementations of a given trait, then the compiler cannot know where the trait methods will be statically, so it is impossible to do static dispatch. Since impl Trait wants to guarantee static dispatch, it requires that only one possible implementation of the trait be returned.
- naasking 8y agoI think your explanation of static and dynamic dispatch is either wrong, or incredibly confusing. The offset of the function pointers is always statically known for a given trait/interface type, it's just the actual vtable instance that may not be known, ie. the concrete type implementing that trait/interface. A statically known vtable instance that can be inlined/monomorphized is static dispatch, and if it's not known at compile-time it must be dynamically dispatched.
- deleted 8y ago[deleted]
- burntsushi 8y agoI don't understand what's so confusing about it. GP says "calling the trait method requires a dynamic lookup to find the method on the boxed object" It sounds like all you want to say is "calling the trait method requires a dynamic lookup to find [the vtable instance, which is then used to find] the method on the boxed object"
- naasking 8y agoThat's not the clarification I was making. For instance, I simply can't interpret this line from the original post as anything but incorrect: > then the function pointer will always be in the same place on the object in memory (static dispatch) As I said, static vs. dynamic dispatch is about knowledge of the vtable instance, not about the offset into the object or the vtable. All of the offsets are always known statically, it's merely what you're indexing into that may or may not be known statically. Maybe I'm being pedantic, but I've found that there's a lot of misunderstanding surrounding static vs. dynamic dispatch.
- tylerhou 8y agoI think because returning two different types requires dynamic dispatch when using the returned objects, which requires Box; if the function only returns one type then that type can be determined at runtime and further function calls can be implemented with static dispatch instead.
- the_mitsuhiko 8y agoRust could generate a bespoke internal proxy type.
- Rusky 8y agoThat would still require dynamic dispatch of some kind.
- the_mitsuhiko 8y agoBut it wouldn’t require a heap allocation.
- lmm 8y agoWhere is the proxy implementation going to go if not the heap?
- GolDDranks 8y agoThe proxy object would have statically known size (maximum of the size of the types it dispatches between, plus some metadata such as a vtable pointer or an enum discriminant). Now, because you know the size statically, you can store it in the stack.
- shepmaster 8y agoUntil then, we use `Either` (https://stackoverflow.com/a/50204370/155423 https://stackoverflow.com/a/50204370/155423)
- steveklabnik 8y agoThe mismatch isn’t about the associated type, it’s about the actual, underlying type. One is a Map and one is a Filter. It’s not possible to determine which is returned, so you inherently need dynamic dispatch. There is some discussion about it possibly being sugar for an anonymous enum in the future, but that’s not what it is right now.
- khuey 8y agoIs there an RFC for the anonymous enum thing? I would gladly write the implementation ... :D
- steveklabnik 8y agoI don’t believe so? I feel like there’s several internals discussions but no RFC yet.
- the8472 8y agothere's some discussion, but no RFC yet. https://github.com/rust-lang/rfcs/issues/2414 https://github.com/rust-lang/rfcs/issues/2414
- deleted 8y ago[deleted]
- Soft 8y agoMy understanding is that impl Iterator<Item = i32> in return position means that there is some single concrete type that implements the Iterator trait that we are simply not going to name. This way, the compiler can do dispatching statically. If different paths returned values with different types there wouldn't be just a single type that is known at compilation time. That is why the extra indirection via trait objects is required in the example.
- bluejekyll 8y agoI'll take a stab at explaining this in the way that I finally started grokking the issue (coming from the land of Java). In Rust (most languages), by default the compiler needs to set aside space on the stack for each return value. So it needs a constantly known size (and shape) to create the slot on the stack. You need to flip to dynamic dispatch, ie a pointer to an object (Java's default), that will be placed on the stack as a reference to the unknown size/shape of the thing at the end of the pointer when the size/shape is unknown. A pointer always has a constant size on the stack. In this example, `impl Trait` is just saying I want the compiler to figure out the size/shape of the thing being returned for me, and allocate that to the stack at the call site of the function. What this means is that even with `impl Trait` you must return a thing that has the same size/shape. Steve's answer mentions a common pattern used to create constant size/shape by using an enum for the wrapper type to return two different types on the stack from the function. The only other option is to put something with unknown size behind a pointer, ie Box<Trait> or &Trait, and thus pay the expense of dynamic dispatch.
- neptvn 8y agoCongrats to the Rust team and all contributors! Awesome work! Is the non-lexical lifetime improvements work locked to a particular release yet? Also, now that the async/await RFC has been merged, is its implementation in nightly or stable going to be squeezed in for the 2018 roadmap plans?
- Manishearth 8y agoYeah, the plan is for async/await to be part of the 2018 edition, but it's going to take some time.
- kibwen 8y agoasync/await has been on the 2018 roadmap from the start: https://blog.rust-lang.org/2018/03/12/roadmap.html https://blog.rust-lang.org/2018/03/12/roadmap.html As for non-lexical lifetimes, there's lots that's been implemented but much of it is still experimental; follow Niko Matsakis' blog series at http://smallcultfollowing.com/babysteps/blog/2018/04/27/an-alias-based-formulation-of-the-borrow-checker/ http://smallcultfollowing.com/babysteps/blog/2018/04/27/an-a... to stay up to date with what's happening.
- DC-3 8y agoThis more than makes up for a couple of slightly sparse releases. Congratulations to the whole team, and to you especially for the completion of the new book:
- ucarion 8y agoAmazing work on this release! I've needed so many of these features in stable Rust, and I'm so excited to get to use these. I mean, just yesterday I had to do some weird stuff to a for loop in order to iterate over all u8s in a cleanish way. Lovely, lovely work. I'm especially excited to see how clever the ref/ref-mut `match` inferring is. If it's reliable, that's gonna remove quite a bit of friction for newcomers. So cool!
- steveklabnik 8y ago<3
- pests 8y agoCongrats on the release, I've been following Rust for a long time. While I'm sure it won't mess anyone up, the range for the i128 is hard to interpret. It looks like -xxxxx - xxxxxx but with the extreme number of digits it looks like two negative numbers or a subtraction problem. [edit: u128 -> i128]
- steveklabnik 8y agoHeh, thanks. I mostly put it in there because it looks ridiculous, so that's sort of a feature, not a bug. I hear you though.
- curun1r 8y agoWith the release of impl Trait (easily the feature I've been most looking forward to), has there been any talk of/proposals to allow anonymous trait implementations? (see: https://github.com/rust-lang/rfcs/pull/2406#issuecomment-384300637 https://github.com/rust-lang/rfcs/pull/2406#issuecomment-384... for an example of what it might look like) Being able to return anonymous trait impls from inside functions could eliminate a lot of what seems like boilerplate structs/impls from Rust code. As an example, the code in futures-util that adds combinators to a Future defines a type (Then, Fuse, Map, etc) for each combinator function. With those functions now able to use 'impl Future<...>' as the return type, being able to actually type 'return impl Future<...>' could make code like that a lot less cluttered.
- steveklabnik 8y agoI’m not aware of any real proposal.
- kaoD 8y agoI feet Rust was getting pretty boring... and that's amazing! As a hobbyist I'm pretty happy to see the language maturing. I remember release 1.0 and thinking it was maybe too rushed. How wrong I was! Is there anywhere I can get a quick recap of major features Rust is planning to eventually maybe implement, and their state? I mean major features like NLL, impl trait, etc. IIRC: NLL are nightly already, const generics in planning stage, and what happened to CTFE? For us not in the know, a sneak peek on what's coming/being discussed is very exciting, but browsing the issue/RFC tracker is sometimes a PITA and it's hard to keep up to date, especially after getting used to the workarounds.
- steveklabnik 8y agoYes and no! We’re gearing up for a big release, and so a lot of stuff is landing. I don’t have that text ready at the moment but rest assured that in the next couple of months you’ll see something. “2018 Edition” :)
- GolDDranks 8y agoThere's so much long-awaited features that are finally stabilised. impl Trait is HUGE. And there's tons of other stuff too. This must be the biggest single release since 1.0.
- dikaiosune 8y agoI recently found myself inserting &/*/ref/ref mut into match expressions before I'd even seen a compiler error. My first thought was "aha, look at how experienced I am with Rust now!" Followed immediately by "I can't wait until this isn't something you have to learn to be productive with the language." And now that day has come! Really exciting for me. I also need to go and find all of my impl Trait TODO comments and get to work on cleaning those up! What a good day. I should also say that while I haven't read the second edition of the book yet I am excited to have some new Rust-related content to read. The first edition of the book was a really eye-opening learning experience for me (both about computers and Rust and also about how to build a community and prioritize teaching) and I can only imagine what an improvement on that is like.
- eyko 8y agoNicer `match` bindings was easily my favourite feature of this announcement. I can't recall the number of times I've been trying to show some rust code to someone and then pattern matching comes in and I get a cold drip of sweat expecting their reaction/questions as to why do we need to be so verbose. Happy day for me as well indeed!
- kibwen 8y agoSo yeah, 1.26 is the most substantial release since 1.0, but there's lots more goodies coming in the pipeline. :) It just so happened that all the initiatives from last year are preparing to land at approximately the same time. For example, coming up next in 1.27 is stable SIMD: https://github.com/rust-lang/rust/pull/49664 https://github.com/rust-lang/rust/pull/49664 (though only for x86/x86_64 at first; more platforms and high-level crossplatform APIs are on the way).
- pimeys 8y agoThe features I'm highly expecting are pinned references and async/await, that will make most of my paid Rust to be so much more readable and maintainable. I know these are coming this year, but any chance they might be already in 1.27? 1.26 has impl Trait, which is one of those things that really makes your life easier as a Rust developer. I've been using beta already with the new API I'm building just to get that feature, now on stable right before I'm actually thinking of deploying the API. Nice.
- steveklabnik 8y agoPin is in nightly, but async/await is not. Both will certainly miss 1.27, and my guess is MAYBE 1.28, probably 1.29.
- kibwen 8y agoThe RFC for async/await was actually just accepted two days ago! https://github.com/rust-lang/rfcs/pull/2394#issuecomment-387550523 https://github.com/rust-lang/rfcs/pull/2394#issuecomment-387... :) It's a priority for this year, but it'll be a few months yet; unless something goes unexpectedly wrong, I'd expect it no later than 1.30, releasing on October 25th.
- Scarbutt 8y agoSo yeah, 1.26 is the most substantial release since 1.0, but there's lots more goodies coming in the pipeline Will rust users get a break someday?
- 8y ago
- sushisource 8y agoSuper excited to see how much better my code will look with impl Trait and the "no need for &/ref in pattern matches" stuff. Keep it up Rust team. The language is incredible! Really my only daily complaint is IDE support is still abysmally slow, in both IntelliJ and VSCode.
- shmerl 8y agoCongrats on impl Trait release! By the way, how is the progress of supporting XDG base directory spec for rustc and cargo?
- steveklabnik 8y agoMoving forward still. It’s non-trivial.
- runevault 8y agoEveryone keeps talking about impl Trait (which is great) but I'm super pumped for ? working in main now. Was recently writing some code as I finally got back to rust and forgot about that edge and had to write a match block when ? would have been good enough (felt silly to make a method just to handle that).
- kibwen 8y agoAgreed, being able to get rid of spurious unwraps in trivial code and small code examples and replace them with idiomatic error handling is lovely. :)
- bvinc 8y agoThe first thing I always do is immediately make a function "main2" and make main an error handling function. It'll be nice to not have to do that.
- cjcole 8y ago"Speaking of print, you can pre-order a dead tree version of the book from NoStarch Press. The contents are identical, but you get a nice physical book to put on a shelf, or a beautifully typeset PDF. Proceeds are going to charity." Which charity/charities?
- steveklabnik 8y agoBlack Girls Code is the intention today, but originally it was going to be a different tech charity that is no longer around, OpenHatch.
- cozicoolmail 8y agoBlack Girls Code, in my opinion, is a great organization with a well executed mission and good reach (several major cities throughout the US). Glad Rust picked them. Source: I've volunteered for them in the past as an instructor.
- steveklabnik 8y agoI have only heard wonderful things; I'm glad your experience is consistent :) I have no idea how big the donations will be, but we're giving it a shot!
- vvanders 8y agoSo freaking excited about impl trait. This and not being able to do paramterized array sizes for things like SoA, AoSoA where the two things that I feel like were missing from Rust. Really happy to see the first landing(and I understand work is going on for the second).
- steveklabnik 8y agoThere was some sort of SoA derive going around, I thought. Regardless, you’re right; we’re hoping const generics lands in nightly this year and stabilizes early next year.
- ben0x539 8y agoHooray, congrats to the rust contributors, once again. :) Personally, not a fan of the match change. But then I was already not a fan of autoderef in method calls.
- bluejekyll 8y agoThe biggest negative I've seen is this: let example: (String, String, String) = ("ref".to_string(), "to".to_string(), "ref".to_string()); let example: (&str, &str, &str) = match &example { (ref1, to, ref2) => (ref1, to, ref2), }; Which might look confusing to people, it's converting from &(1,2) to (&1,&2)... but it's still type safe. Besides something like this, is there another reason to be worried about it? https://play.rust-lang.org/?gist=e37f9b31cc5e5c7b9d19c6b0a4c44441&version=stable&mode=debug https://play.rust-lang.org/?gist=e37f9b31cc5e5c7b9d19c6b0a4c...
- ben0x539 8y agoReading (or even writing!) rust code, you can get increasingly far without knowing what level of indirection you're operating on. I don't enjoy that. I don't personally feel like the notational burden for explicitness is enormous. For field access/method calls, autoderef is a bigger convenience because we don't have the C++ -> operator, but I think I'd have preferred a syntax change here over the current behavior.
- Rusky 8y agoThe match changes here don't bother me anywhere near as much as deref coercions do, because they preserve the level of indirection. Deref coercion makes a &Box<T> behave like a &T (removing a level of indirection). Default binding modes only make a &(T, U) behave like a (&T, &U). I've idly wondered whether it would have been possible to replace deref coercions with something like this. Making Box<T> behave like &T kinda works but loses you the ability to control `&T` vs `&mut T`, but maybe `x.y` where `x: &T` could "pass the reference on" giving you a `&U`.
- bpicolo 8y ago> Inclusive ranges are especially useful if you want to iterate over every possible value in a range Out of curiosity, why was the (or an alternative) choice not to make the compiler understand that the 0..256 was not inclusive, and somehow correct the literal value to do what's intended? Would that have been unusually complicated or? Edit: Overall, still an amazing release, this was just the bit I'm curious about :) Great work by the whole Rust team/community
- steveklabnik 8y agoEvery language I’m aware of has different syntax for inclusive vs exclusive range; making it situational would be quite confusing, I’d imagine.
- bpicolo 8y agoDefinitely agree that having the inclusive syntax makes sense either way (..= was mildly jarring at first but makes complete sense syntactically) - I just mean the exclusive ranges arriving at that compiler error definitely seems unexpected
- steveklabnik 8y agoAh! Yeah, I mean maybe. At the same time, special cases can make things harder to understand. This would also technically be a breaking change, though probably not changing any realistic programs.
- Animats 8y agoGo deliberately left that out.[1] Probably a good decision. [1] https://groups.google.com/forum/#!msg/golang-nuts/7J8FY07dkW0/goWaNVOkQU0J https://groups.google.com/forum/#!msg/golang-nuts/7J8FY07dkW...
- pjmlp 8y agoGo left almost everything out.
- Promarged 8y agoCongrats on the release! Would the book be updated as new features are added to Rust? I see some useful things being incorporated slowly into the language...
- steveklabnik 8y agoYes and no. Think of it like release trains; the second edition has left the station, and so isn't being updated directly. It's actually pinned to 1.21; it left the station a while back. Work on the "2018 edition", which is the next version after "second edition", is just starting. It will be getting updates as new stuff lands, though there may be a bit of lag. In general, docs are going to be a bit weird up to the Rust 2018 release; it's all coming together, but slower at first, faster at the end. (This means that, as of right this moment, there aren't great docs for impl Trait. I'm working on them right now.)
- ovao 8y agoThe post doesn’t go into much detail about how the new i128 and u128 types are implemented, so for anyone who’s as curious as I was, the RFC is here: https://github.com/rust-lang/rfcs/blob/master/text/1504-int128.md https://github.com/rust-lang/rfcs/blob/master/text/1504-int1...
- pcx 8y agoThe wonderful thing about Rust is that despite being fairly new and rare to get paid for working on it, it is still enticing( to most programmers I've met). The consistent effort to improve it is really paying off. I hope it gets to a place where it's `batteries included` like Python. There are some glaring holes in the stdlib I would like to see fixed sometime soon.
- gamegoblin 8y agoWhich glaring holes are there in your point of view? Rust devs are on HN a lot, so maybe they will see your comment. All that said, Rust definitely errs on the side of preferring to put things in 3rd party crates instead of stdlib, even for things that are very common to put in std for other languages (e.g. random number generation).
- pcx 8y agoA couple of commong APIs I can think off the top of my head: - HTTP client - CSV parser/generator I know Hyper and rust-csv are popular. But having an stdlib that's much more feature complete would be great.
- steveklabnik 8y agoYeah, I can totally appreciate the perspective, but without a significant set of policy changes, I don't see either of these happening. We'll see!
- oblio 8y agoMaybe after the community chooses a few “winners” the Rust devs could promote them as being “suggested” packages? Also, some suggested metapackages/bundles wouldn’t hurt for newbies, like a set of crates for developing command line tools, for example. Something like this: https://marketplace.visualstudio.com/ https://marketplace.visualstudio.com/
- 8y ago
- _zachs 8y agoI'm super excited about the "Basic slice patterns". I've been learning some Elixir at the same time and was blown away by the different style of programming you can write in using matching. Glad to be able to try it out in Rust as well.
- jmhain 8y agoIs it possible to match the end of a slice with slice patterns? Something like: fn foo(s: &[char]) { match s { ['a', 'b'] => (), [.. 'b', 'c'] => (), _ => (), } }
- steveklabnik 8y agoNot today, but it's coming. This kind of thing does work on nightly.
- Lev1a 8y agoI was mostly excited about slice patterns because of a pattern I wanted to be able to write: some_collection.windows(2).filter(|[a,b]|a==b).map(|[a, _] |a).collect(); Turns out the compiler rejects that with a "refutable pattern" error, because the args part of the filter/map closures do not handle the situation where the slice could be empty, which AFAIK can not occur when using windows/chunks/... Maybe there has to be some special case handling for this pattern to be valid?
- steveklabnik 8y agoHm, interesting. I think this isn't possible without integer generics.
- Lev1a 8y agoBecause the pattern in the filter closure would have to be generic over the length or am I mistaken?
- nikolay 8y agoI really wonder why is Golang so popular today when Rust is just killing it?
- steveklabnik 8y agoThey're very different languages, so different people like them for different reasons. Why is salt so popular today when pepper is just killing it?
- nikolay 8y agoWell, every two languages are different, but at least for systems programming, Golang unfortunately started to replace Python, but given how vitally important security is in that domain, Rust makes a lot more sense than Golang, won't you agree?
- steveklabnik 8y agoI don't think "systems programming" is a coherent concept anymore, so I'd reject the premise of the question. Go has already moved away from that word, Rust will be as well. That you see them as being so different languages reinforces my premise above; they're good at different things, so comparing them doesn't always make a ton of sense.
- nikolay 8y agoI have to agree with you.
- Thaxll 8y agogVisor is a security product ( Container Runtime Sandbox ) made by Google in Go and runs in production so I'm not sure what you mean by "how vitally important security is in that domain". https://github.com/google/gvisor https://github.com/google/gvisor
- nikolay 8y ago
- leshow 8y agoI have been so excited for this release! impl Trait is wonderful, thanks everybody
- pjungwir 8y agoOh wow, this sounds great! I've hit both the long signatures when returning iterators, and also the dereferencing song-and-dance with match, and my Rust projects have been very limited. So I think these are huge improvements that will help a lot of other newbies like me. I can't wait to start using 1.26 instead. Thanks Rust team! :-)
- freeopinion 8y agoYeah, but can it run Rocket? :-)
- steveklabnik 8y agoNot yet; working on it! https://github.com/SergioBenitez/Rocket/issues/19 https://github.com/SergioBenitez/Rocket/issues/19 is getting shorter and shorter!
- stmw 8y agoDefinitely excited by all the progress on the "run Rocket" front!
- deleted 8y ago[deleted]
- kccqzy 8y agoExistential types are great! Although I must mention that existential types are basically the way to model OO-style information hiding. It's a great tool to have in any mature type system, although I do wonder how it is compiled. Trait objects are kind of easy to imagine: a heap-allocated dictionary of methods for that trait. I do wonder how heap allocation is being avoided in this case. EDIT: I didn't read closely enough. Only a single type is allowed, so the traditional existential type construct ("trait objects") are still needed.
- kibwen 8y agoThere's intentionally no heap allocation or virtual dispatch when using `impl Trait`; if we were content with that, we wouldn't have bothered implementing it and just continued on as we were with `Box<Trait>`. :P
- hardwaresofton 8y agoAs a person who started writing rust this last week, I think I might have picked the best possible time to get in on it. The community is amazing, and I actually understand all these features that were released I've run into about half of the issues they fix already. Rust is coming along very very nicely.
- MuffinFlavored 8y agowhat else would you say it is missing?
- Rotareti 8y agoNot essential but keyword arguments / named parameters / default arguments. I love those in Python and OCaml/ReasonML.
- Lev1a 8y agoYou can make functions with default arguments right now (a little easier thanks to Impl Trait): http://play.rust-lang.org/?gist=4f74d3dcee0031e99cb99bb54da521b1&version=stable&mode=debug http://play.rust-lang.org/?gist=4f74d3dcee0031e99cb99bb54da5... Concerning keyword args as I remember them from Python you would probably have to hack something together with an Into<Option<HashMap<some_type_for_arg_names, some_enum_with_variants_containing_acceptable_types>>> Concerning "named paramters" I think you would have to apply some of the same trickery in order to be able when calling the fn to leave out args or give them in a different order than specified in the fn header. Or what I've sometimes seen written was (e.g. for configuration passing) structs created with Option<some_type> that were then passed to one or more functions which in turn get the values (named params/default args if you will) from that "object", being able to pick and choose the appropriate values to get in a given function/method.
- hardwaresofton 8y agoUnfortunately I don't have a good full response to this (otherwise I could contribute it and actually help), but off-head I was surprised by the lack of a `cargo install` (https://github.com/rust-lang/cargo/issues/2179 https://github.com/rust-lang/cargo/issues/2179). A few minutes later though I was used to googling for the package i wanted, and getting the version I wanted to use and adding it to Cargo.toml, and that's arguably a better way to do things to start with. I haven't used it enough to have much more to say -- I've found everything pretty ergonomic so far (especially for a C/C++-tier language), I was most frequently confused when thinking of the most idiomatic way of doing something, but that's remedied by reading more (the rust book first/second edition, the rust cookbook). This should change over the coming weeks. This isn't a particularly useful comment, but I chose Rust over Common Lisp recently for this new project, and I've found the std library's google-ability to be excellent for rust -- very few pages about steel have come up so far ("result rust" in DDG brings up rustlang related links). When I explored CL, I did not find that to be the case, but maybe I just didn't know where to look -- hyperspec is close but it is a terrible document to navigate through, and the 90s graphics didn't help (though they were nostalgic). Rust documentation is very often concise, well structured, and passably beautiful. I was also pleased with the Abstract Data Type solution in rust -- tagged unions. Some code: #[derive(Debug)] pub enum ConfigLoadError { EmptyFilePath, IO(IOError), TomlParse(TomlError) } The abstraction enabled here is just right for me, super similar to code that I'd write in Haskell, and helps me abstract over errors thrown by utility libraries (in this case `toml-rs`).
- mathw 8y agoI wrote a program yesterday in 1.25 which did some simple file I/O right there in main, didn't need to be fancy at all... and then this morning I come online and find that we now have fs::read_to_string and main can return a Result... great! But I needed this yesterday! Seriously though, this is an amazing release and so much stuff in here I've been looking forward to for ages. impl Trait is going to change the way I write Rust.
- jeffdavis 8y agoWhy is a filtered iterator a different type than an unfiltered iterator?
- GolDDranks 8y agoThis is hard to answer as a one-liner; do you know about monomorphic vs. polymorphic code and static/dynamic dispatching? Rust is, by default statically dispatched, so because the two kinds of iterators do different things, they have to be of different types.
- jeffdavis 8y agoAh, that makes sense, thank you. One iterator simply returns the value and increments, and the other needs to apply the filter first and potentially advance several times.