Hacker News new | past | comments | ask | show | jobs | submit login

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.




> 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) = <something>
    }
    // use a and b here
currently you have to assign to (1+) temporary variables before porting that to the actual bindings you care about.


It's true that a "checked_as" would come handy from time to time and seems to be in line with the "Rust spirit". But again, since the author seems to be arguing in favor of C it seems like an odd complaint. C even makes it tricky to check for integer overflow while Rust has the checked_ family of functions. In C if you get it wrong it's undefined behavior territory baby.

Ditto with the tuple thing, C doesn't have tuples and won't let you destructure anything.

I guess my overall point is that these complaints seems to pit Rust against some other high level languages like Common Lisp or Haskell but his conclusion is basically "C rulez, Rust droolz".


Also, detecting overflow while casting seems pretty trivial to implement as a macro itself if you aren't willing to wait for the language to pick up the need.


There is an open issue (an old one!) about assignment to tuples, but it's not entirely a no-brainer as to how to implement it while keeping Rust's grammar LL(k): https://github.com/rust-lang/rfcs/issues/372


> 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.

That's because lifetimes in Rust are currently tied to a lexical scope - a borrow of a variable is kept alive until the variable goes out of scope, even if it's never used after a certain point in the function.

There's currently an open RFC that would allow the kind of nested calls described in the blog post: https://github.com/rust-lang/rfcs/pull/2025


> All languages have reserved keywords, that's strictly in bikeshed territory.

This is true, but it is unfortunate that a relatively common word like "type" has been reserved (whereas you very rarely want to call a variable "struct", and "class" at least has the homophone "klass").

This is actually something that I really like about Swift and miss when I come back to Rust. In Swift, most keywords are contextual keywords, so you can still use them as variables or functions. And for the ones that aren't (or the ones where the usage you want is in the keyword context), there's a syntax using `backticks` that lets you turn it into an identifier anyway (which is useful if the declaration runs afoul of the keyword, but the common usage doesn't, so you can use backticks when declaring and leave them off when using).


> 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".

A media codec is a very well understood, highly optimized thing with established idioms that are already well-matched to the capabilities of the hardware (and in many cases are taking advantage of hardware features explicitly designed for the codec being implemented!). Demanding that we start writing codecs differently isn't the same thing as telling a app UI developer they need to get used to traits instead of inheritance.

If rust can't handle the existing idioms for this problem area, that may need to be seen as a problem with rust, not the programmer.


That's not really the point.

I'm sure whatever the original code is doing could be copied directly, including calling raw assembly code (which optimized codecs often end up doing to micro-optimize as much as possible). You'll just need copious amounts of unsafe code.

But then what's the point? You might as well keep your existing code. I guess it would make sense if you wanted to standardize your cobebase and move everything to Rust, but I doubt that's much of a use case nowadays.

Now if you write a brand new codec it might be interesting to start in safe Rust and once you're ready incrementally add unsafe code where it matters to improve performance while limiting the unsafe code as much as possible. Rust gives you the choice, C is just unsafe by default.

Coders have to write things differently if they want a different result, as should be expected. If the only metric is performance at all costs then assembly beats everything else.


> A media codec is a very well understood, highly optimized thing with established idioms that are already well-matched to the capabilities of the hardware (and in many cases are taking advantage of hardware features explicitly designed for the codec being implemented!).

Hold on. We aren't talking about modifying the codec itself, or how it's implemented at the machine level. If it weren't straightforward to generate machine code that matches how the codec is designed to be implemented, that would be an issue with Rust—but that isn't what this thread is about. We're only talking about the particular language idioms used to create that implementation.


> 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".

Who's fault is that?

Rust seems like an attempt to take a lot of foreign concepts to C/C++ programmers and dress them up in ALGOLy syntax. If you look at Rust's influences page[1], there's stuff from ML, Haskell, Erlang... and yet Rust code examples I've seen all look like "slightly weird C++." If Rust wasn't meant to be written like C/C++, it could spend less time aping it and more time looking like languages where you expect to come across ADTs and the like.

1) https://doc.rust-lang.org/reference/influences.html


Well, like it or not, one of the primary audiences of Rust is C and C++ programmers. They're the people who write low-level code. There's not much we can do about that; we might as well serve our customers as well as we can.


> we might as well serve our customers as well as we can.

Sure, but what part of serving them involves dragging them on Hacker News when they try and write C-like code in Rust?


I don't think we should be upset with people for their legitimate frustrations. But I do think we should be honest with the basic limitations of what we set out to do. A safe language that has dynamic allocation without GC simply has to have a borrow checker, and as far as we know that borrow checker has to have some limitations. Those limitations prevent some kind of code from being written in the same way it was written in C.


Any language deserves to be assessed on its own merit, not what people's preconceptions are. I still believe that a lot of the flak Perl gets is from people that see that it looks somewhat like C and make assumptions, and are surprised when it turns out that it has a few surprises up its sleeve (e.g. context). The fault lies with the person who purports to learn a language, but then doesn't reassess their assumptions when confronted with evidence to the contrary.


I'm really glad it doesn't do this. I spend a fair amount of time writing or reading Rust, Python, CoffeeScript, Haskell, OCaml, etc (in no particular order) and I find Rust to be much more readable, largely due to braces, commas, and parens in intuitive places.


Good comment; shame about that gibe in the middle, it'd be better without making it personal.


Normally I would agree, but I think it makes an important point. The author is not at the same level in both languages. The author is actually new enough to Rust that they've missed the existence a common feature and used it's absence as evidence. This may or may not color how you assess the rest of the points being made by the author.


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

If you use CMake, you do get tests for free at least.

> Maybe it's worth the hassle of making array manipulation slightly less convenient for the sake of security?

On my computer I will always choose speed over security... especially for video processing & stuff like this. Wasting CPU cycles has a direct effect on my energy bill. Other people may do other tradeoffs.


>If you use CMake, you do get tests for free at least.

CMake is not part of C. Tests and (soon) benchmarks are parts of Rust. That makes a big difference in practice.

Besides if third party solutions are considered it won't be difficult to come up with one for Rust.

>On my computer I will always choose speed over security... especially for video processing & stuff like this.

It's true that the prospect of running unoptimized codecs is not very appealing. That being said when I think about it video and audio streams are probably the main source of untrusted 3rd party data that I actually handle on my computer. And it's not simple processing either, it's quite complex.

Imagine the havok if a zeroday in a popular codec library is found and an attacker manages to ship it on a popular tracker in the form of "Game of Thrones S07E04.mkv". The payoff would be immense. I wouldn't run a random executable found on bittorent but I won't think twice about opening a video file.


> On my computer I will always choose speed over security... especially for video processing & stuff like this.

What's the worst that could happen? It's not like video, image and audio codec implementations get exploited much, right?

In case that sarcasm was too subtle, I think you would be hard pressed to find a popular implementation of common media format (h.264, mp3, JPEG, GIF, etc) that hasn't had an exploit at some time.

It's your choice what to run, but I can't help but be somewhat annoyed at the professed position because it doesn't just affect you when it goes wrong.


CMake--not lack of static analysis--is the primary reason I moved to Rust from C++. Safety is something I came to appreciate later. Building binaries is a solved problem; there's no reason to allocate project time crafting and maintaining a build system for each individual project.

> On my computer I will always choose speed over security... especially for video processing & stuff like this. Wasting CPU cycles has a direct effect on my energy bill. Other people may do other tradeoffs.

Rust allows you to make that tradeoff, ridiculous though it may be.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: