Rust's Complexity Problem – A Warning

栏目: IT技术 · 发布时间: 4年前

内容简介:“Every application has an inherent amount of irreducible complexity. The only question is: Who will have to deal with it — the user, the application developer, or the platform developer?”— Larry TeslerThere has been a trend circulating the web in the past

Rust's Complexity Problem – A Warning

“Every application has an inherent amount of irreducible complexity. The only question is: Who will have to deal with it — the user, the application developer, or the platform developer?” [1]

— Larry Tesler

There has been a trend circulating the web in the past couple years called “Rewrite it in Rust” (RiiR). Many big companies are rewriting core parts of their applications in Rust — Discord [2] , Microsoft [3] , and Cloudflare [4] , are just a few. The tech avante-garde’s positive reports on Rust’s resource efficiency and memory safety sound great, but those attributes come at a price, and they are far from being the only measures of software quality [5] . Especially in applications that don’t require maximum resource efficiency and memory safety, adopting Rust in 2020 is irrational at best.

I will not suggest programmers avoid Rust on account of its immaturity [6] , its often-false sense of security[7], or its lack of true freedom [8] . However, I do suggest programmers avoid Rust because it makes the programmer manage complexity that can, in most cases, be sufficiently managed by the machine.

The Problem of Complexity in Computing

A major purpose of any high level programming language is to manage the complexity of controlling a computer. Communicating a command directly to a computer requires machine code — a whole bunch of 1s and 0s. That gets complicated. Assembly language hides some of that complexity by converting English-like commands into the 1s and 0s of machine code. Higher level languages, like C, hide that complexity even further. The complexity is still there, but languages like Assembly and C manage the complexity so that the programmer doesn’t have to think about it. These well-established tools are much better at handling complexity than our human brains.

Computers are complex. Most of that complexity is essential to their existence, so it will always be there. If we are to use computers, their complexity must be dealt with. When not managed properly, complexity leads to errors [9] .

There are a few ways a computer’s complexity can be managed. The tools used to manipulate computers can manage it (e.g. a high-level language translates English-like commands to machine code); the programmer can manage it (e.g. the programmer writes machine code directly); or the end-user can manage it (e.g. the user writes machine code directly). There can also be various combinations of these three.

Who should manage complexity?

In all software projects, the end-user’s experience should be the main concern. That could mean that an astronaut’s space ship lands safely on the moon, or it could mean that an office administrator’s calendar application never loses data. The programmer’s goal is to give the end-user the tools necessary to accomplish a task. A part of that is making sure the end-user doesn’t have to think about the computer’s complexity. It is expected that the end-user has the least amount of understanding of a computer’s complexity. That means he/she is the most likely to cause errors when managing that complexity. Most programmers aren’t fond of fixing errors caused by end-users, and most end-users aren’t fond of managing a computer’s complexity.

That leaves the programmer and the tools to manage the complexity. Our tools are imperfect, so they are incapable of managing all of the complexity. However, some tools manage complexity better than others, leaving the programmer to manage varying degrees of complexity. The less complexity a human has to manage, the less room for error.

Where does this leave Rust?

The brilliant thing about Rust, and the primary reason for its low resource usage, is that it enforces memory safety without the use of a garbage collector (a program that frees computer memory when it is no longer needed). Most programming languages either leave memory management up to the programmer or they use a garbage collector. The languages that leave memory management up to the programmer are less memory safe, but also less resource intensive. These include C, C++, and Assembly [10] . The languages that use a garbage collector are safer from a memory standpoint, but use more computing resources when the garbage collector is running. These include C#, JavaScript, and Python [11] .

Rust neither uses a garbage collector nor leaves memory management up to the programmer. Instead, it uses its compiler to make the programmer manage the program’s memory in a specific way. Before a Rust program can be compiled, it is subjected to the scrutiny of the borrow checker which reviews the program for improper handling of memory [12] . A programmer can make the compiler allow an unsafe program, but that is not the default [13] .

Rust’s way of managing memory is unique and clever. Unique and clever are generally seen as good things, but in software development they usually lead to difficulties with long-term maintenance, among other issues [14] [15] .

Rust does not manage the complexity for the programmer like garbage-collected languages, and it does not put the complexity solely in the hands of the programmer like most non-garbage-collected languages. Instead, the Rust compiler guides the programmer in managing a single aspect of the complexity, memory (which is responsible for a large portion of security vulnerabilities [16] ), in a specific way. That works fine for memory management, but in order to manage memory the way the borrow checker wants, the programmer is at best tempted, and at worst forced, to add complexity to the program. That is the crux of the problem.

The compiler helps the programmer handle the complexity of memory management, but it does so by forcing the programmer to write the program in a specific way. The Rust way limits the program and the programmer. In order to create a working program under Rust’s limitations, the developer often adds workarounds or extra moving parts. These are added so that memory can be managed safely, but at what cost? What other bugs or flaws arise from the new complexity that the programmer must handle? Sure, the added complexity probably won’t result in memory management problems, but it will result in other problems because humans are not good at managing complexity.

The brilliant thing about Rust is also the most dangerous. Many software developers take great pleasure in learning about new and interesting tools. Rust is certainly that, and I will never hesitate to recommend that a programmer learn Rust. At the same time, new means the tool has not stood the test of time, and interesting means it is probably unique and clever, and we know where that leads.

In the world of computer programming, simplicity results in fewer bugs and less downtime [17] , so complexity should be moderated as much as possible. Rust’s novel way of managing memory adds complexity that must be managed by the programmer. On the other hand, garbage collected languages manage memory for the programmer. For that reason, if a program can run sufficiently using a garbage-collected language, choose the garbage-collected language.

If a program needs to use as few resources as possible, Rust may be a viable option. But also keep in mind that Rust’s assurance of memory safety does not negate the need for careful planning and thoughtful design. I won’t try to argue whether Rust is better than C or C++ in resource-critical applications, but if I did, it would be a hard case to make on either side, and there would be many things to consider including team size, expected program size, and whether the program will be exposed to the internet.

Considering the facts that a good portion of software does not need to run at C’s close-to-the-metal speeds, and Rust obtains memory safety by encouraging the programmer to manage and add complexity, Rust is not a good choice for many programs.

References

[1] http://nomodes.com/Larry_Tesler_Consulting/Complexity_Law.html

[2] https://blog.discordapp.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f

[3] https://msrc-blog.microsoft.com/2019/07/22/why-rust-for-safe-systems-programming

[4] https://blog.cloudflare.com/tag/rust/

[5] https://www.tutorialspoint.com/software_quality_management/software_quality_management_metrics.htm

[6] https://blog.debiania.in.ua/posts/2020-03-01-rust-dependencies-scare.html

[7] https://medium.com/@shnatsel/smoke-testing-rust-http-clients-b8f2ee5db4e6

[8] https://internals.rust-lang.org/t/rust-s-freedom-flaws/11533

[9] https://www.microsoft.com/en-us/research/publication/the-influence-of-organizational-structure-on-software-quality-an-empirical-case-study/

[10] https://wiki.c2.com/?LanguagesWithoutGarbageCollection

[11] https://www.memorymanagement.org/mmref/lang.html

[12] https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html

[13] https://kk.org/thetechnium/triumph-of-the/

[14] https://softwareengineering.stackexchange.com/questions/25276/why-is-cleverness-considered-harmful-in-programming-by-some-people

[15] https://news.ycombinator.com/item?id=20386073

[16] https://msrc-blog.microsoft.com/2019/07/16/a-proactive-approach-to-more-secure-code/

[17] https://www.gkogan.co/blog/simple-systems/


以上所述就是小编给大家介绍的《Rust's Complexity Problem – A Warning》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C陷阱与缺陷

C陷阱与缺陷

凯尼格 / 高巍 / 人民邮电出版社 / 2008-2-1 / 30.00元

作者以自己1985年在Bell实验室时发表的一篇论文为基础,结合自己的工作经验扩展成为这本对C程序员具有珍贵价值的经典著作。写作本书的出发点不是要批判C语言,而是要帮助C程序员绕过编程过程中的陷阱和障碍。.. 全书分为8章,分别从词法分析、语法语义、连接、库函数、预处理器、可移植性缺陷等几个方面分析了C编程中可能遇到的问题。最后,作者用一章的篇幅给出了若干具有实用价值的建议。.. 本书......一起来看看 《C陷阱与缺陷》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器