Despite all of the "systems language" talk, it would not shock me in the least to see the same thing happen with Rust (or whatever new language comes along next year).
I don't intend for this to be a slight, but the plain fact of the matter is that "dynamic" languages come in and out of fashion every 5 years or so. Those people are accustomed to that cycle. They get bored easily and PREFER that cycle. The senior ones are usually on their second or third language cycle (or beyond).
In contrast, C++ and Java are ENTRENCHED in their areas (systems programming and business applications, respectively). Whatever ultimately displaces them someday... it will have to be an order of magnitude better, and it would still take years.
By all means, market your favorite new language(s) to all possible demographics. Just understand that the "PHP/Python/Ruby/Node/Go/Elixir/Swift" crowd are going to be your primary adopters (and conversely, the first to grow bored and leave when the next thing comes along).
Perhaps some developers in the "PHP/Python/Ruby/Node/Go/Elixir/Swift" crowd are trying to gain credibility in the OSS/Github world by making a not-yet-developed but vital library in the new language. If github is your resume, this could be a large win for their portfolio/resume.
Another take... For Python, there are dozens of projects that do the same manipulations, but are implemented slightly differently. People can, of course, contribute(patches, issues, etc.) to libraries they use the most... or they can make the 25th iteration. A new language presents a way to tickle the brain in a not-so-tedious manner by eliminating the technical debt in the other language's implementation while providing new paradigms to code around. I call that tickling the brain and it can be addicting.
If you go to a site like StackOverflow, that is related to getting actual work done... the questions for Java, .NET, C++, and PHP absolutely dwarf those for Ruby, Python, and other fashionable dynamic languages (JavaScript being a notable exception). If you look at the number of GitHub repos by language, you find a similar pattern.
However, you go to sites like Hacker News and others that are more about idle discussion, and it's hard to find people who will even admit to working with non-sexy industry standard languages. If you didn't know better, you would get the impression that there are more Nim and Forth programmers in the world than PHP ones.
I believe that is because most such discussion comes either from students, who haven't started a career yet, or from professionals who enjoy discussing the "side" languages that they learn in their personal time (yet are not using professionally).
I don't mean this in a negative way. I myself wrote OBSESSIVELY about Scala for years, even though my actual day jobs had me writing vanilla Java. But online discussion does create a bit of a "reality distortion field", that confuses young people just starting out. The #haskell channel on FreeNode is the most popular programming channel in all of IRC... yet the entire world's population of non-academic professional Haskell developers could hold a conference at the airport Holiday Inn. Rust is a fascinating language to learn and dabble with, but almost none of us will ever have a job working with it professionally. Etc.
People get "bored" and "move on" from these languages not due to economics, but due to lack of economics. They are playing with them for fun, not because they're getting paid to do professional work with them. Hence the constant search for newer shiny things.
Doesn't support what you said. C++, for example, is smaller than Python.
Ruby has about a 1/4 of the questions of Java.
They're certainly not "absolutely dwarfed".
Python is overwhelmingly the language of choice for scientists afaik.
> I've often thought that software developers were akin to Magpies, birds notorious for stealing shiny items to decorate their complex nests. Like Magpies, software developers are unusually smart and curious creatures, almost by definition. But we are too easily distracted by shiny new toys and playthings.
I actually think there's no room for any language to displace C++ in that way, ever.
The biggest reason that people give for bouncing off Rust is that the novel aspects of the language--lifetimes and borrowing--are too unfamiliar and/or hard to learn. Any language that is to be an "order of magnitude better" than C++ will necessarily have aspects that are unfamiliar and hard to learn. Long-time C++ users will bounce off that language for the same reasons they're bouncing off Rust.
No non-C++ language will ever appeal to C++ users who don't want to learn new concepts. C++ is very good at being C++, and for that reason it's immortal. Rather, new languages will continue to chip away at the uses of C++, making its use more and more marginal. This is a process that has been going on since the '90s--remember that in the '90s practically all software was written in C++, whereas in 2016 most new programmers aren't even learning it anymore. C++ has been declining not because it's being replaced but because its domains have become smaller and smaller. Rust is just a continuation of that trend: now there's a better option for security-critical software that can't be written in a GC language for performance and/or flexibility reasons (to name Rust's strongest domain), which has reduced the domain of C++ just as Java did 15 years ago for the server space and the rise of the iPhone App Store did in 2008 for the consumer app space. The continuation of this trend is what will gradually make C++ more and more niche going into the future.
I would expect the people bouncing off of borrowck to be those coming from GC'd languages where where and how long a value lives aren't things most programmers think about. Programmers coming to Rust from this environment have to learn about the fundamental concepts of lifetimes and in-memory representation/storage at the same time as they learn the limitations and reasoning model of borrowck. Without having seen the mistakes they're being prevented from making, I can imagine trying to fix borrow errors would feel more like a game of appease-the-adversarial-checker than a safety harness catching you when you slip up.
The only reason I see to keep writing C++ is the impedance gap between Rust and C++ making it less than pleasant to convert a large C++ codebase to Rust gradually. On top of name-mangling/linking concerns, Rust encourages composition and static method dispatch whereas it's rare to find a large C++ project not using inheritance and vtables extensively. You'd probably just end up going through the C ABI for all interop which is hard to argue would increase code quality compared to simply sticking to pure C++.
(1) The most common one: They think that they can write C++ safely with no memory management issues, and that people who don't are just bad programmers. This has been empirically refuted over and over again and I think there's no successful way to defend this idea, but it's a very appealing position on the face of it, so it's something I hear a lot.
(2) The less commonly expressed, but much more legitimate one: Memory management problems just aren't the biggest issues they deal with. I hear this from game developers from time to time (e.g. Jonathan Blow, though he's not by any means the only one). This is, in my mind, a totally legitimate position. Viewed in this light, C++'s memory management primitives are simple ways to eliminate the most obvious errors, which helps prevent some (not all) crashes and vulnerabilities from reaching production. Rust is entirely a move in the wrong direction for these projects, because it adds nontrivial cognitive overhead.
Interestingly, people rarely ever describe reason (2) in those words, probably because the idea that you would opt in to less safety makes people queasy. But that doesn't make sense to me; it's legitimate to want less safety if your app doesn't require it. (I do think, of course, that reason (2) is not legitimate if less safety makes your app vulnerable to e.g. remote code execution by network attackers and RCE would result in the leak of sensitive data or other game-over scenarios.)
I've actually been a proponent of solving (2) by adding easier ways to write unsafe code in Rust. But (2) is not a commonly-expressed position, so there's been little community interest in solving it (which I'm fine with).
I think syntax like fn foo(bar: int) -> string {}; is a step backwards. More glyphs, more arcane nomenclature, and I just get a ting of change for the sake of change or "I want to be a functional hipster".
What is wrong with rettype name<templates>(argtype argname): ?
Why am I still writing all these damn semicolons and curly braces? I'm already intending the code and newlining every statement.
Why are there so many damn macros when C++ is realizing having language features rather than preprocessor macros is a huge usability gain?
I still think Rust is the best language out there today, but the failures in my view drive me insane that its not perfect. Its so close!
I guess I kind of just want a native compiled statically typed Python, though.
I prefer Rust's syntax to whitespace-sensitive languages.
> I think syntax like fn foo(bar: int) -> string {}; is a step backwards. More glyphs, more arcane nomenclature, and I just get a ting of change for the sake of change or "I want to be a functional hipster".
No, Rust's type syntax is the way it is to avoid the lexer hack, which causes real problems in C++ (typename qualification, in particular).
> What is wrong with rettype name<templates>(argtype argname): ?
The lexer hack.
> Why are there so many damn macros when C++ is realizing having language features rather than preprocessor macros is a huge usability gain?
Rust macros are not preprocessor macros, not even close. Macros are language features.
I'm not arguing it, I'm just curious why Rust is using the prefix var pointer syntax when you are almost never supposed to use those in language.
I guess my point is more you could start from a clean unambiguous syntax (when is "rettype name<templates>(argtype argname):" ambiguous?) and rather than just verbatim copy C's glyphic syntax append vocabulary to the language to describe ill-used features.
One thing I have always considered a reasonable design choice going forward would be to start* with somethking akin to ptr(foo) rather than foo to denote dereferencing. In general I would like to see languages in this field start* with vocabulary and transition to glyphic grammar only on the most frequently used language features.
That would mean you could start with a language that does things like this:
int foo(5)
short bar(3)
long res(foo.plus(bar))
bar.equals(foo)
And then you could have just int, short, long etc classes that have operator overloads for =, +, etc and systemically avoid glyphic overload ambiguity because you are forced to handle that ambiguity in the operator descriptions.With modern compilers (particularly LLVM) this could probably work very well, because the optimizers are so good even if you start defining your primitives in object notation and handing off really ugly bytecode that is treating everything as a non-dynamic object the backend llvm equivalent asembly generator will almost certainly be able to strip all the overhead out and return you back to optimized platform specific math operators onregister-sized words.
I'm not a language designer (obviously). I'm just a developer frustrated with how every language but Python is so much harder for my uncle to read (who is not a programmer) and thus makes me spend more brain energy deciphering it than if it were less verbose and more plaintext. And after writing a few of the Rust tutorials on the weekend a few months ago and giving a crack at writing a webrtc library for it I was really frustrated with how much extraneous glyphic grammar I had to learn and deal with in the language, since it seems so much worse than C++ from my perspective.
Putting the type name before the variable name can grossly complicate your tooling (the aforementioned lexer hack, https://en.m.wikipedia.org/wiki/The_lexer_hack ), which is part of the reason why tooling for C and C++ is so relatively rudimentary despite thirty years of time to address it.
There are also semantic difficulties that can arise from putting the type name before the variable name. For example, C++ recently added a return-type syntax that resembles what you see in Rust:
auto multiply (int x, int y) -> int; // this is valid C++
The reason why this syntax exists is because, well... it's a bit complicated to explain here, read http://www.cprogramming.com/c++11/c++11-auto-decltype-return... instead. :)Furthermore, the `name: type` syntax is simplest solution when your language supports both patterns and type inference, as Rust does. IMO it also reads more nicely because when scanning code I care more about what a value's name is than its type (which may only be because Rust's type system is relatively strong, and I count on it to catch me if any types are out of place).
There's also the emerging historical trend: AFAICT, every language designed in the past ten years has put the type after the variable name. Rust, Go, Swift, TypeScript, Nim, Crystal, Pony... even Python 3 (https://www.python.org/dev/peps/pep-0484/). All the proposals that I've seen for optional types in Ruby and Javascript put the type after the name as well. And this syntax has roots in a much older language, ML, and is generally shared by ML's descendants (such as OCaml, and also possibly Rust).
The function syntax C++ has seems more like a bandaid around the broken scoping rules inherited by C more than anything. If you were writing a replacement it seems like it would be one of your first considerations to make each statement scope limited to the scope of the declaration. I mean, that is what auto is effectively doing in C++ nowadays - you have to evaluate the whole statement to resolve what auto is supposed to be at compile time.
I would take consistency of using postfix typing as a sign there is legitimacy and simplicity in compiler design to do so, but I don't think the Python example is particularly fair, since it (and the C++ ->) are both extending a language that already had declaration syntax and thus the kind of glyphic overhead imposed by colons and arrows is less condemnable because they had to maintain backwards compatibility.
My gripe boils down to the difference between "August 5th" and "5th of August". The latter can convey the information in a more meaingful sense (you usually care about the day more than the month if you are using both) but it comes with a grammatical overhead "of" that, if were writing and reading a lot of dates of this form, would have a tangible impact on overall reading and writing efficiency. It would of course be minor - that is why its a gripe, and I still love Rust from what I've done with it - but it nags on you like it could have been done better.
And I also can understand the concept of name over type, but as someone who strongly favors static typing over dynamic after about five years of Python and three of C++, I think just conceptually "Canister Bob" is easier to parse than "Bob the canister". It is almost certainly just habit, but I justify my appreciation of the habit because it doesn't need to involve those damn conditional constructs (be they the, if, or a colon) that clutter up my reading and writing.
I am saying this has a maily, Python programmer. The syntax is fine..... once you get what it does, until then it was hair ripping.
It's as if folks coming from C++ are supposed to "just get it". It's supposed to be "obvious" why Rust is a better choice than C++, yet I don't see it. Maybe if I was writing some sort of mission-critical software I would look into Rust. But I use C++ for cross-platform mobile applications. I've had trouble finding a compelling reason to invest my precious free time time in learning Rust over furthering my C++14 knowledge.
That being said, some projects are legitimately OK with some memory management errors and/or races creeping into production, in exchange for a lower learning curve in that area. If this describes your project, and you're happy with C++, then keep using C++.
(Note that I don't believe that "I write modern C++ so I never make memory management errors" is virtually ever true. Every large C++ app I've ever seen has fallen to some memory error or another. I think "I don't care (enough) about the errors" is a legitimate reason to use C++, but "I don't have to care" isn't.)
I very much agree. Although few people would say "I don't care about the errors", out loud, even if that sentiment is valid in certain contexts.
In that light, I have a question for you: What other concurrency features does Rust offer over C++ outside of data race freedom guarantees?
Rust has a few libraries that enable stack-scoped threads that are safe by virtue of ensuring that all threads created in the scope terminate before the data they reference is dropped (EDIT: and by preventing mutation of shared state without guarantees about atomic operations).
For example, I'm working on a project that uses crossbeam:
https://aturon.github.io/crossbeam-doc/crossbeam/
And there's a good blog post explaining some other things the library does:
It does in the same sense that it's safe to do anything in C++. Virtually nothing in C++ is safe, but you can pretty easily do it.
Just because you don't have to be explicit about it doesn't mean you don't need to have some mechanism to handle it somewhere, its just automatic instead.
I would say that the biggest win of Rust, once you get past the data race freedom, is that Rust's overall design puts the CSP model front and center like Erlang and Go do, while C++ is built on mutexes, locks, and futures. The way to get started with concurrent programming in Rust is thread::spawn, Sender, and Receiver, which will take you far. But C++ doesn't even have channels in the standard library; it encourages you to dive headfirst into shared memory, which makes simple concurrency needlessly difficult.
Rust doesn't restrict you from using shared memory when you need to (and verifies that it's safe when you do). But Rust's libraries and ecosystem encourage you to design your apps in shared-nothing fashion first, and only to introduce memory sharing when you need it for performance. That's a much friendlier way to deal with concurrency than mutexes, locks, and futures.
(I'm not sure how active that is worked on, though, I think I've seen basically the same version back in September.)
Which C++ subset should someone choose? All of it? What about the people who don't use exceptions? What about the people who don't use templates?
It's the same problem as writing a Perl to XXXX tutorial. The surface area of the source language is so huge that it's just not worth the undertaking.
Easy. The subset outlined in Effective Modern C++
> What about the people who don't use exceptions?
Rust doesn't have exceptions.
> What about the people who don't use templates?
Rust doesn't have templates.
So, C++ does. You asked about a tutorial for idiomatic Rust coming from C++, and then specified the full C++ set.
So, you have to give the Rust-y equivalents to exceptions, RAII, templates, reference types, virtual classes, etc.
Personally, I'd rather have a C to Rust equivalent--it's a lot easier. Especially a tutorial and primer on making Rust work in an embedded toolchain.
Being able to have a compiled, modern language actually work on embedded hardware would be excessively useful.
I think Rust does way better at most of Java's strong and weak points (aside from maybe ecosystem and current deployments), but it would be good at some point for Rust to have a good story to present to Java devs. Its type system is much better, its safety guarantees stronger, it has pretty good cache locality, its concurrency is approaching the ease of use of the JVM's and has always been safer, and its use of memory is far more reasonable and isn't prone to GC pause.
I've lately sort of been looking askance at how prevalent we dynamic language users are in the rust community, and I worry that we may skew the perception of how rust should evolve due to our potentially greater numbers on /r/rust, in the RFC process, on IRC, etc.
It would be nice to get some statistics, because it would be quite unexpected. Still, it seems like some major Rust contributors are coming from the dynamic programming fold. Also, we shouldn't compare Go and Rust, but Go seems to have influx primarily from dynamic languages as well.
(I come from a C/C++/Java/Prolog/some Haskell background, dabbling with Rust now.)
You are likely to have a mixed audience as well; even if not everyone has that mixed experience like I do, there will probably be a mix of people in the audience. So, it would probably be a good idea to have some examples and descriptions tailored towards those with a C++ background, and some towards those with dynamic language backgrounds.