6 ms·
Looking at the example, I can't find a thing in there that is not required (except the obvious `:Vec<_>` type that is not required). We need `.iter` to tell tha
by nercury 10y ago
Looking at the example, I can't find a thing in there that is not required (except the obvious `:Vec<_>` type that is not required). We need `.iter` to tell that iterator is imutable (there is mutable version), we need `.collect` to actually run the iteration. I also don't think objects should have default constructor functions.
It may be possible to implement `.zipped` on tuples though.
- steveklabnik 10y ago> (except the obvious `:Vec<_>` type that is not required) It is required, otherwise, `collect()` doesn't know what type of collection to collect into. > It may be possible to implement `.zipped` on tuples though. This is impossible without varargs, no?
- pcwalton 10y ago> This is impossible without varargs, no? Nah, you'd just implement it as an impl over and over on tuples of reasonable size (up to 16 or so). It wouldn't be elegant, but it'd work in practice.
- steveklabnik 10y agoOh right, I see now.
- __s 10y agoThis technique is used a lot by specs: https://github.com/slide-rs/specs/blob/master/src/join.rs#L50 https://github.com/slide-rs/specs/blob/master/src/join.rs#L5...
- cbreeden 10y agoWhich is what itertools does I believe https://bluss.github.io/rust-itertools/doc/itertools/struct.Zip.html https://bluss.github.io/rust-itertools/doc/itertools/struct....
- nercury 10y ago> `collect()` doesn't know what type of collection to collect into. Yes, unless there is some other mention of Vec, i.e. it is returned from the function. > This is impossible without varargs, no? Varargs would definitely help, and would allow Rust to borrow more ideas without workarounds. But one can do it manually for each tuple variant.
- nimish 10y agoHaskell just brute force implements zipWith3, zipWith4 etc Not elegant, but it works.
- tome 10y agoThe un brute force way is to use the Applicative instance of ZipList.
- epidemian 10y agoYep, but it's still an unfortunately big difference in expressiveness between the two languages, where one might think that they would be more or less on par, given the languages' similarities (both are more or less contemporary in their design, statically typed, with similarly powerful type systems, etc). My question is then: is there something fundamentally preventing Rust from achieving similar levels of expressiveness to this Scala example without incurring in unnecessary runtime overhead? Given that both languages are statically typed, my inclination would be to say no: the information is there, the compiler should be able to figure it out. But, alas, i know very little about these things, hence my question :) Update: pcwalton gave some nice insight on why Rust needs some of these constructs on an uncle comment.
- Veedrac 10y agoActually Rust already has izip and IntoIterator that covers the early differences. The type annotation `Vec<_>` is also optional since it can be inferred from the context. The `map` is uglier in Rust because * the comparison was against a constructor with positional, rather than named, arguments * the Scala code didn't need to dereference any arguments, and * and Scala's `Zipped` is a special type with a special `map` function that takes three arguments, unlike a normal iterator. The first and last points could be easily copied in Rust: you'd build a constructor for HuffmanCode and augment iterators of tuples with with a starmap method (that can be done in a library). The middle point can be done before the zipping. The result would be let codes = izip!(data_table.iter().cloned(), code_lengths, code_table) .starmap(HuffmanCode::new) .collect(); Rust's collect is never implicit, like Scala's CanBuildFrom. This prevents accidental collects, which helps writing fast code, but in principle I don't see why it couldn't be implicit - it would just require the whole standard library to be overhauled.
- Veedrac 10y agoActually the last two `.iter()` aren't needed at all because of IntoIter. All three can all be removed if you use Itertools' izip! let codes: Vec<_> = izip!(&data_table, code_lengths, code_table) .map(|(&value, length, code)| { HuffmanCode { length: length, code: code, value: value, } }) .collect(); (If HuffmanCode was a tuple type, this could even be #![feature(fn_traits)] let codes: Vec<_> = izip!(data_table.iter().cloned(), code_lengths, code_table) .map(|args| (&HuffmanCode).call(args)) .collect(); but now I'm just playing around.)