13 ms·
"No segfaults, no uninitialized memory, no coercion bugs, no data races, no null pointers, no header files, no makefiles, no autoconf, no cmake, no gdb. What if
by taliesinb 11y ago
"No segfaults, no uninitialized memory, no coercion bugs, no data races, no null pointers, no header files, no makefiles, no autoconf, no cmake, no gdb. What if all the problems of c/c++ were fixed with one swing of a magic wand? The future is here, people"
It certainly is.
The advantages over C++ seemingly never end. I'd add to the list: rigorous portability, non-broken macros, ADTs and pattern matching, a careful language stability protocol, standard test and doc tooling, flexible namespacing via visibility and modules, the absense of vast lacunas of undefined behaviour, simple numeric promotion rules, meaningful compile-time errors for generic code. Plus things already mentioned in the post like Cargo.
People tend to focus on the safety side of Rust, but as impressive to me is just the... solidity on all these other axes. If you stripped out lifetimes and the borrow checker you would still have an incredibly compelling alternative to C++.
- gbersac 11y agoADT -> Abstract Data Type for those who wonder. It means no need to explicitly define the type of a variable, the compiler infer it based on context.
- evanpw 11y agoIn this context, ADT probably means algebraic data type: https://en.wikipedia.org/wiki/Algebraic_data_type https://en.wikipedia.org/wiki/Algebraic_data_type. And I don't think your definition for abstract data type is right either: usually the language feature that automatically determines types from context is called type inference.
- Robin_Message 11y agoIn this case, I think they meant algebraic data type, since they mention it next to "pattern matching". An algebraic data type is generally made up of two things: 1) structs or tuples, which are useful but in most (but not all languages); C/C++ has them for example; and 2) tagged or disjoint unions, which are different from C unions in that you can tell which one of the union choices is being used (A variant is a particular tagged union). Tagged unions are super-useful for pattern matching, so you get code like: match rv { Ok(_) => { None } Err(CacheError::KeyNotFound) => { Some(Resp::NotFound) } Err(ref err) => Some(from_cache_err(err)) } which has a nice syntax, is type-safe and can be compiled reasonably efficiently. The algebraic part means that these two features can be used in any combination with each other, and also refers to the link that, roughly 0 is the empty type, 1 is the unit type, structs correspond to multiplies (and gets called the product type), and unions to plus (so is called a sum type). Why? Because if I have a tuple of a union of A or B or C, and another union of X or Y, I have 6 possible values in total, and (1+1+1) x (1+1) = 6.
- tel 11y agoYou probably also want to complete your toolkit with functions which are then exponentiation. Also, in any ADT system 0 should be exactly the empty sum and 1 exactly the empty product. This is what makes things hang together properly.
- _asummers 11y ago0 and 1 are just idiomatic though, correct? The important part, from my knowledge of abstract algebra, is that there exist an identity for any operation function () such that for all x in your domain, x () identity = x.
- tel 11y agoOh sure, you can call them whatever you like. But if you have an ADT system which has a unit type that isn't quite the empty product then you'll be in for an interesting time at least. E.g., this is true in Haskell and it causes there to be some "extra structure" which often has to be smoothed over. Lots of library functions exist just to do this smoothing.
- fanf2 11y agoAnd differentiation, which is useful for functional update of persistent data structures. https://chris-taylor.github.io/blog/2013/02/13/the-algebra-of-algebraic-data-types-part-iii/ https://chris-taylor.github.io/blog/2013/02/13/the-algebra-o...
- tel 11y agoThat's nice, but I wouldn't call it particularly core to ADT systems. It also requires quite a bit more machinery to embed directly since you need to be able to talk about functors/containers.
- pjmlp 11y agoBesides what evanpw already answered. Abstract Data Type were introduced by languages like CLU, Mesa and Modula-2 among others. It means having modules that only export the type names, but not their definition, while exposing functions/procedures to operate in such types. It is not the same as the ADTs in functional languages, although they are quite similar.
- catnaroek 11y agoThey're not similar at all. Algebraic data types are finite sums and (tensor) products. Abstract data types are existential types, which are infinite sums indexed by a kind.
- tel 11y agoWhat makes them weak?
- catnaroek 11y agoWhen you unpack a weak existential type repeatedly, every time you get a fresh new type. When you unpack a strong existential repeatedly, you always get the same type. Anyway, my original comment was wrong: in ML, every time you project a type component from a module, you always get the same type. So it's more like a strong existential. My bad.
- tel 11y agoAh, gotcha. Thanks!
- pjmlp 11y agoThe purpose of my remark is how they look like in terms of usage for the humble programmer. They being similar how having a limited data structure (non extensible) with a set of functions that operate on it. Depending on the FP language ADTs can also partially hide their implementation like the Abstract Data Types in modular languages. But I can also happily discuss the math theory and the denotational semantics about them across languages, but I don't think it will help for many readers.
- catnaroek 11y agoThere are two conceptual errors here: (0) Rust doesn't really have much support for abstract data types. What Rust has is something not too unlike Haskell: you can hide `struct` fields [though not `enum` constructors], but the `struct` remains concrete. With a bona fide abstract data type mechanism, as in ML, you can give a module a signature that reveals the existence, but not the representation, of its type components. I'm guessing this much representation hiding isn't fully compatible with Rust's goals, which require knowing the sizes of types statically, unless they're behind a layer of indirection. (1) Abstract data types have no relation whatsoever to type inference. [Nor do algebraic data types for that matter.] An abstract data type is an existential type: a dependent pair consisting of a type `T`, and a value whose type is `F T`, for some type function `F`. The closest thing Rust has to existentials is trait objects, but these can't do everything that existentials can do.
- viraptor 11y ago> no gdb Just in case it's taken the wrong way - I don't know what the author meant, but gdb works very well with Rust. Actually it "just works" for the debug builds.
- YorickPeterse 11y agoThey probably meant not having to use it to debug any of the common C/C++ problems.
- pjmlp 11y agoI like C++ a lot (minus the C parts) and was once upon a time a C++ hipster (if that would be a thing in mid-90's). However I enjoy even more memory safe system programming languages. What I love in Rust, besides its ML influence, is making younger generations aware that systems programming languages don't have necessarily to mean unsafe by default or the primitive toolchains from C and C++.
- 72deluxe 11y agoDid you not find that C++11 fixes many of the shortcomings of older C++?
- catnaroek 11y agoRust is still miles ahead of C++11 and even C++14 in terms of safety. On the other hand, C++ still has the upper hand in the type-level programming department, especially now that Hana exists and will be added to the next Boost release: https://github.com/boostorg/hana https://github.com/boostorg/hana .
- pjmlp 11y agoOnly for skilled developers that care about safety. You cannot take C out of C++, so how much help is C++17 if some cowboys in the team keep doing C style coding? Yes, I know all about static analyzers and code reviews, but the sad truth is that in many companies there are lots of developers and management, that don't care a second about them. This is specially true across companies whose main product isn't software development.
- 72deluxe 11y agoUgh tell me about it. My colleague(s) and superior(s) all write C++ like it is C from 1989. Coding standards exist, but they basically enforce indentation rules. Const-correctness, use of references ("those things with ampersands by them...." said colleague A), exceptions are all unknown to them. Object-slicing is a risk ("what's object slicing??"). Pointers are thrown around, added to multiple lists, no RAII, no initialisation of variables, use of memcpy everywhere, no copy constructors, C-style casts EVERYWHERE (including casting to siblings and their descendants...). Arrays are used everywhere, occasionally vectors are used but used like arrays (which isn't so bad), but they're used alongside arrays instead of replacing them; naked new/delete, use of malloc and realloc periodically; for loops are using instead of STL algorithms. And this is a NEW codebase. I am desperate to leave. Does anyone need a C++ developer? Please, someone help!
- avar 11y ago> no autoconf Mentioning this in the same breath as "no segfaults" seems odd, does Rust use some other build configuration tool, or does it just not have the need for compile-time configuration detection? If it's the latter how does that even work? Are there no optional libraries? No outdated libraries whose version you have to detect? No obscure platforms whose architecture you have to detect for unsafe inline code etc.? Because if you can have any of those or any number of other cases where you need compile-time detection of configuration options you're going to need something like autoconf.
- eatsfoobars 11y agoBuild scripts[1] written in Rust are used for this. [1]: http://doc.crates.io/build-script.html http://doc.crates.io/build-script.html
- Tuna-Fish 11y ago> does Rust use some other build configuration tool Yes. Rust ships with cargo, which is probably the best build configuration tool ever written, and I've tried a lot of them, for a lot of different languages. It has clean, non-hacky solutions to all of the cases you listed, and a lot more besides those.
- dozzie 11y agoOh, far from that. Last time I checked Cargo didn't understand the difference between downloading things (dependencies) and compilation. Even its building process didn't have that separated, and happily downloaded a random pre-built ELF binary to build itself.
- steveklabnik 11y agoI'm not sure what you mean by not understanding it. It is true that if you don't have dependencies, "cargo build" will go get them, but if you don't, then it shouldn't. There have been some bugs that caused it to over-download, but those were bugs. > happily downloaded a random pre-built ELF binary to build itself. Yes, Cargo builds itself with Cargo, so you need to get a previous Cargo. The binary is very much not 'random'.
- thesz 11y agoNo...gdb. Enjoyed all this this in Haskell for almost 18 years now. 10 years for sure, I don't remember when --make switch in ghc was introduced.
- petke 11y agoLanguages come and go but C++ remains. I wonder if this one will be different. Im not trying to be a jerk. Just voicing my concerns. Learning a new language and producing code in it is a huge commitment. It better be around in 10 years. Will it still be as clean and simple, or will it have grown complex. What if Mozilla stops sponsoring it? C++ is 35 years old. It has stood the test of time. I would not be surprised if it was still popular in 35 years time, when I retire. There is so much C++ infrastructure code in this world, that its not going anywhere. In the meantime C++ has evolved. I cant remember the last time I had an uninitialized memory, null pointers, or buffer overflow -bug. Those are low level C problems. If you avoid C-style programming and stick with modern C++ (RAII, value semantics, STL, boost, etc) you wont get them. C++ is changing fast. In the next few years we are getting high level concurrency and parallel language support and libraries (no more low level thread problems), we are getting modules (no more preprocessor hacks), compile time reflection (no more manual serialisation), concepts (no more ugly error messages), ranges (no more cumbersome iterators), and a whole lot more. And finally there is "C++ Core Guidelines" which aims to be checkable by tools. So you get a warning when you are relying on undefined behaviour. I think C++ is still the future.
- steveklabnik 11y ago> Languages come and go but C++ remains. I wonder if this one will be different. As I said the other day, unfortunately, the only way to get an old language is to start with a new one, and then let time pass. You're not _wrong_, exactly, but with this logic, no new programming languages should ever be made. There are certainly valuable things about using a truly mature ecosystem, but we also need to build better mature ecosystems.
- valarauca1 11y ago> but with this logic, no new programming languages should ever be made Well I mean after LISP it was all down hill. /s
- sdegutis 11y agoThey do come and go. 90% of a language's success is legacy apps that use it and can't switch off. The other 10% is how powerful the hype train is for getting new apps written in it, which then form that language's own 90%. Rust can actually get that done. The community has the power, and they have the hype. It's happening.
- mcguire 11y ago"Rigorous portability"? There's an old adage: there is no portable software, only software that has been ported. What is the status of Rust on Windows? I understand there are ARM versions; are there any other supported architectures? I like Rust a lot. It's my go-to systems language at the moment. But let's do keep the hype train somewhere near the tracks.
- steveklabnik 11y agoRust works well on Windows. You can find details about platform support here: https://doc.rust-lang.org/book/installing-rust.html#platform-support https://doc.rust-lang.org/book/installing-rust.html#platform...
- mcguire 11y agoCross-compiling to MIPS and PowerPC Linux? Cool!
- phyllostachys 11y agoI haven't really been keeping tabs on it but I've heard from a former coworker that cross-compiling for ARM Cortex-M parts is fairly easy too.
- nickpsecurity 11y agoSee Pascal/P. Wirth wisely started with a stack machine (P-code) that could map efficiently to about any architecture and be re-implemented by non-compiler experts. He then targeted a Pascal compiler to that. I believe he targeted a standard library to it. The result was Pascal/P applications ran on 70+ architectures without modification outside of system-specific code like I/O. So, it's definitely achievable. Was done by Wirth at least twice (Pascal/P & Lilith) plus System/38 (later AS/400) at microcode level. Just takes modularity and a good intermediate language. Your adage is still true in that most screw up portability by using ineffective practices or not using effective ones. I rarely believe it when I see the word in a feature list.