Live data from Hacker News

Rust: Not So Great For Codec Implementing

codecs.multimedia.cx

1–10 of 283 posts

Re: Rust: Not So Great For Codec Implementing

#2
A lot of good comments on Reddit, with answers/solutions/discussion of the points brought up here: https://www.reddit.com/r/rust/comments/6qv2s5/rust_not_so_gr...

These kinds of experience reports are so valuable. (I've been following the whole series and they're very interesting.) Even if solutions to these issues do exist, if people can't find them, well that's a problem too.

Re: Rust: Not So Great For Codec Implementing

#4
Not a Rust expert, but some thoughts on the negatives.

> Compilation time is too large

Can you try compiling incrementally? https://blog.rust-lang.org/2016/09/08/incremental.html. Might still only be on nightly.

> And, on the similar note, benchmarks.

I agree, profiling as well isn't as full featured as in more mature languages. Clojure, incidentally has great benchmarking due to being on the JVM.

> Also the tuple assignments.

Can't you just do

    fn main() {
        let (a, b) = (5, 2);
        println!("{}, {}", b, a);
    }
>There are many cases where compiler could do the stuff automatically.

I think this will be solved with the new non-lexical lifetimes RFC. Also a problem I had when starting, I generally assume referential transparency.

Re: Rust: Not So Great For Codec Implementing

#5
Some of the complaints are perfectly fair (compile time, powerful but unwieldy macros). Other complaints seem a bit odder to me:

>While overall built-in testing capabilities in Rust are good (file it under good things too), the fact that benchmarking is available only for limbo nightly Rust is annoying;

Okay, but what are you comparing it against? Neither C or C++ have builtin benchmarking or even tests.

>If you care about systems programming and safety you’d have at least one or two functions to convert type into a smaller one (e.g. i16/u16 -> u8) and/or check whether the result fits.

I don't understand this one at all. What's wrong with "as"? And if you need a checked conversion just write a small wrapper function? Again, if you're comparing to C or C++ I'd argue that Rust's semantic are friendlier and a lot less error prone at the cost of increased verbosity. C will implicitly cast and promote integer types without asking any questions, Rust makes it explicit.

I understand C promotion rules and I've still managed to get it wrong on occasions, to the point where I now force myself to make all casts explicit in C like I would in Rust. At least this way the intent is obvious, as I think it should be.

>Also the tuple assignments. I’d like to be able to assign multiple variables from a tuple but it’s not possible now. And maybe it would be nice to be able to declare several variables with one let;

So unless I'm missing something something like:

    let (a, _, b) = (1, 2, 3)
>Same for function calling—why does bitread.seek(bitread.tell() - 42); fail borrow check while let pos = bitread.tell() - 42; bitread.seek(pos);

Yeah, that's always been a minor annoyance of mine too. I intuitively think that

    a(b());
should be treated like

    let tmp = b();
    a(tmp);
That is b() would terminate and release its borrows before a is even considered and "tmp" would live until the end of the block.

I'm guessing that there must be a good reason why it isn't so however.

Note that in C and C++ parameter evaluation order is unspecified so calling functions with potential side effects in parameter lists should be done very carefully. The compiler won't ever stop you though, don't worry. I'm sure the foot will grow back eventually.

>Borrow checker and arrays. [...]

Now this whole section feels a lot like "I'm trying to code in Rust like in C and it doesn't work and it frustrates me". Which is fair, messing around with arrays in C is a lot easier than Rust, there's no doubt about that. C also makes it massively easier to spectacularly shoot yourself in the foot if you mess up.

Yes, if you need uninitialized arrays and these sorts of things you need to use unsafe. But that's mostly optimization and you probably don't want to start implementing your codec with that type of code. After all maybe the compiler will be clever enough to see what you're doing with the buffer and not actually run the init code. And if it doesn't you're free to add the unsafe code later, once your codec works, you have good tests and it's time to optimize more aggressively.

>And that’s why C is still the best language for systems programming—it still lets you to do what you mean (the problem is that most programmers don’t really know what they mean)

Ah, so after the Sufficiently Smart Compiler we have the Sufficiently Smart Coder. That seems like quite a definitive claim for somebody who didn't know about "split_at_mut" in Rust a few lines earlier. Maybe the author should experiment a bit more with the language before making bold statements like these?

It's not rare to find security vulnerabilities in codecs and they tend to be extremely exposed. Maybe it's worth the hassle of making array manipulation slightly less convenient for the sake of security?

>type keyword. Since it’s a keyword it can’t be used as a variable name and many objects have type, you know.

All languages have reserved keywords, that's strictly in bikeshed territory. Of course when you get to a new language with a new set of reserved keyword you have to learn new habits. You never name anything "struct", "class", "switch" or "break" in C or C++ because you're used to have these keywords removed. Rust lets me name variables "class" but not "type". Oh well.

>Not being able to combine if let with some other condition (those nested conditions tend to accumulate rather fast)

I tend to agree with this one, although I guess it could become messy quickly if you mix refutable lets with regular boolean conditions.

Re: Rust: Not So Great For Codec Implementing

#6
post #5

Some of the complaints are perfectly fair (compile time, powerful but unwieldy macros). Other complaints seem a bit odder to me: > While overall built-in testing capabilities in Rust are good (file it under good things too), the fact that benchmarking is available only for limbo nightly Rust is annoying; Okay, but what are you comparing it against? Neither C or C++ have builtin benchmarking or even tests. > If you ca…

> I don't understand this one at all. What's wrong with "as"?

That it silently overflows.

> And if you need a checked conversion just write a small wrapper function?

A better suggestion would be to wait for TryFrom/TryInto which IIRC should be stabilised soon-ish.

> So unless I'm missing something something like:

Assignment (https://doc.rust-lang.org/reference/expressions.html#assignm...) not declaration (https://doc.rust-lang.org/reference/statements.html#declarat...). So

    (a, b) = (1, 2)
given pre-existing non-redeclared a and b. Of course this is not very useful for such a trivial example but a common case is some sort of procedural loop e.g.

    let (mut a, mut b) = (0, 0);
    for it in thing {
        (a, b) = 
    }
    // use a and b here
currently you have to assign to (1+) temporary variables before porting that to the actual bindings you care about.

Re: Rust: Not So Great For Codec Implementing

#7

Not a Rust expert, but some thoughts on the negatives. > Compilation time is too large Can you try compiling incrementally? https://blog.rust-lang.org/2016/09/08/incremental.html . Might still only be on nightly. > And, on the similar note, benchmarks. I agree, profiling as well isn't as full featured as in more mature languages. Clojure, incidentally has great benchmarking due to being on the JVM. > Also the tuple a…

> Can't you just do

That's a declaration not an assignment, TFA is (somewhat oddly) using the language precisely and fittingly: https://doc.rust-lang.org/reference/expressions.html#assignm...

And there are cases where shadowing is not acceptable e.g. when updating bindings within a loop, you usually want to see the updates from outside the loop.

Re: Rust: Not So Great For Codec Implementing

#9

Not a Rust expert, but some thoughts on the negatives. > Compilation time is too large Can you try compiling incrementally? https://blog.rust-lang.org/2016/09/08/incremental.html . Might still only be on nightly. > And, on the similar note, benchmarks. I agree, profiling as well isn't as full featured as in more mature languages. Clojure, incidentally has great benchmarking due to being on the JVM. > Also the tuple a…

> Clojure, incidentally has great benchmarking due to being on the JVM.

Eh? Benchmarking on the JVM is notoriously difficult bordering on impossible. There's things like Google Caliper but test runs take forever due to attempting to force JIT warmup and doing GCs after every run. And the project's own wiki tells you the results are basically meaningless for a variety of reasons.

Benchmarking things like C++ or Rust are trivial by comparison since when you call method foo() it's gonna do pretty much the same instructions every time. Highly consistent, highly repeatable, highly benchmarkable. Call method foo() in a JVM language and there's not a single person on the planet that can reliably tell you what's going to get executed on the metal.

That's why you typically profile JVM languages rather than benchmarking them.

Re: Rust: Not So Great For Codec Implementing

#10
Whilst unrelated to the article, my complaint about codecs in Rust is that they seem to be slow. Whilst the reason for this might be the immaturity of the libraries that I've used, but they've always been slower than their C counter-parts. The native JPEG decoder spins up 4 threads to decode the same amount of frames at 3x the time as the libjpeg-turbo does. There's a similar story for the FLAC decoder.

I don't think that any of this has anything to do with the language itself, it's just that it takes time for things to mature. As for the issues outlined in the article - the language is different enough from C and C++ that one just has to accept the fact that you cannot write idiomatic C and C++ in Rust and expect it to be comfortable, performant or safe. However, with Rust, I'd say, that one can achieve 99% of what one can achieve in C today. The only thing that Rust is missing currently is the ability to arbitrarily jump around the call stack due to the way destructors are implemented, but there's a way to mitigate this and it's being worked as far as I was aware.

Post reply on HN