I'm a die-hard C guy. My motto for years has been "you can pry pointers and address spaces from my cold, dead hands."
Of the new languages I've seen lately, Rust is my favorite. I love how it gives me better ways to express things I actually want to say without imposing GC on me.
But even so, I can't see myself actually using it for much, because writing in a language other than C means buying in to that language's runtime. Buying into one language's runtime means that your code won't play nice with other languages' runtimes.
If I write a library in Rust, how can I expose my types and algorithms to Ruby, Python, Lua, etc? How will Rust Tasks play with Python threads? What if I use a Rust Pipe to send a Python value between tasks? How do I keep Rust from doing a GC pass while I'm holding the Python GIL? etc. etc.
Programming Languages by their nature want to be at the center of your world. If you buy into their abstractions, everything works nicely. But if you try to mash two of them together in a single process, you start to suffer from the fact that their abstractions overlap and don't interoperate at all.
If you're only writing an application (ie. not a library) and never want to embed other languages into your application, then this might be ok. But I'm more interested in writing shared functionality that is useful across languages. Why should the whole stack of parsers, crypto, compression, etc. have to be written separately in each language? Life is too short to do some great work that is only usable by one language community -- computing is so big and changes so much that one-language-only functionality is at best limiting your market and at worst dooming your code to obsolescence when the next big language comes around.
So as much as I instinctively like Rust, I think I'll be sticking with C.
"If write a library in Rust, how can I expose my types and algorithms to Ruby, Python, Lua, etc?"
The same way you expose them in C. Rust and C are compatible at the binary level.
"How will Rust Tasks play with Python threads?"
More or less the same way C setcontext()/swapcontext() workalikes play with Python threads. We probably want a runtime-less Rust to allow users who aren't using tasks at all to just omit the whole system, though. The language itself knows nothing about tasks; they're purely part of the runtime library.
"What if I use a Rust Pipe to send a Python value between tasks?"
Should work as you expect. In Servo we're already sending Objective-C values (which require special APIs to perform the memory management) from task to task over pipes.
"How do I keep Rust from doing a GC pass while I'm holding the Python GIL?"
By not using the GC. It's easy to tell when you aren't using the GC; you can just avoid @ types, and there is a warning you can turn on to enforce no GC use. This sort of thing is the reason why we support manual memory management.
"If you're only writing an application (ie. not a library) and never want to embed other languages into your application, then this might be ok. But I'm more interested in writing shared functionality that is useful across languages."
We're already successfully embedding a JavaScript engine into a pure Rust program for Servo. JavaScript can access Rust types and vice versa.
"Why should the whole stack of parsers, crypto, compression, etc. have to be written separately in each language?"
I agree completely that this is undesirable. That's why Rust doesn't do this. For your three examples, Rust and Servo link to C libraries: Hubbub for HTML parsing, NSS for crypto, and zlib for compression.
> We probably want a runtime-less Rust to allow users who aren't using tasks at all to just omit the whole system, though.
I'd be really interested in reading more about this if/when it is available. I'm also interested in whether you'd ever ship the tasks library standalone, such that you can interoperate with Rust tasks from C (obviously you'd have to follow certain rules to maintain the integrity/safety of the runtime).
> I agree completely that this is undesirable. That's why Rust doesn't do this. For your three examples, Rust and Servo link to C libraries: Hubbub for HTML parsing, NSS for crypto, and zlib for compression.
Understood, but I'm interested in the story for the guy who is writing those libraries.
I just wanted to say, I totally understand where you're coming from here. I often end up writing libraries in C explicitly because that's the easiest way to hit as many targets as possible and not impose any unexpected runtimes on other languages, even if I know it would be easier to write in another language. So, I would say that not enough language designers think this way, and it's really refreshing to see you describing this point of view.
I've often thought that a useful exercise would be to come up with a language that adds just a bit more power than C but stays within the boundaries of the C runtime, just for this purpose.
However, if new languages like Rust can deliver this, all the better! One language that I once looked at with this in mind was Clay[1], which seemed to basically be C with more safety and generics. However, it doesn't seem to be as nicely supported as Rust, and perhaps Rust's static analysis and concurrency support will be more powerful.
You'd want a runtime-less Rust if/when it becomes available (there are no immediate plans for this, but we'd be happy to help). We use native OS dynamic libraries, so once it's possible to build Rust code without a runtime it should be pretty easy to call Rust from a pure C host app.
I'm not sure if this will alleviate all of your issues, but eventually the goal is to allow Rust programs to forgo the runtime entirely.
An old comment from pcwalton (sorry, I've lost the link):
"I'd like to see a 'runtime-less Rust' myself, because it'd be great if we could implement the Rust runtime in Rust. This might be useful for other things too, such as drivers or libraries to be embedded into other software. (The latter is obviously of interest to us at Mozilla.) Rust programs compiled in this mode would disable the task system, would be vulnerable to stack overflow (although we might be able to mitigate that with guard pages), and would require extra work to avoid leaks, but would be able to run without a runtime.
"If anyone is interested in this project, I'd be happy to talk more about it -- we have a ton of stuff on our plate at the moment, so we aren't working on it right now, but I'd be thrilled if anyone was interested and could help."
Tell you what I'm doing lately, that makes me less and less interested in the new-school elite, and just generally enjoying a language 'enigma' moment: putting Lua in everything.
That is, I mean to say, Rust is neat and all but we can do it all in Lua, pretty well, too. Table types are fabulous, kids!
And being able to take any collection of C libraries, and glue them together into 'ones own runtime' with a common language framework/boundary, means a lot.
So, yes, of course.. Lua isn't fast, it has weaknesses, there is luaJit and so on: its not about Lua. Its about the fact that you can choose whatever languages are out there, get competent at their adept usage, and win.
I believe that Rust will be a systems programming language when there is a bootable Rust OS that boots to an editor, a shell, a means of interacting with devices, and a Rust compiler sitting there, waiting for input .. until then, it sure is fun to watch the new school language paradigms get all twisty and bent in the rush to school someone on how systems 'should be programmed, instead of the way they are now'. Research in this field is a terrifically interesting social cache.
Has anyone done a RustOS? Is there one? I know of a couple LuaOS projects, and it sure seems to me like what was done with Linux on Android could be done to Linux, again, with Lua .. Rust .. and so on. Could be very cute times ahead, in the distribution mecca .. GoboLinux, but instead 100% booted to Lua? Hmm .. bogglethink .
No, really, I'm not being snide. I honestly believe that Rust is of great interest, as is the effort and front of new language exploration. However, there is an intrinsic quality of language: it is infinitely useful, or not useful, depending on one thing only: the user.
The whole idea of modern systems languages like Rust or D is actually to avoid the need of using Python, Ruby etc. The language covers all your needs in a nice coherent package from top to bottom.
This is exactly the "one language" myopia that I was arguing against. Anyone who tries to sell me on a language or programming system that asks for complete buy-in and offers no interoperability story is immediately suspect in my book.
(FWIW, I don't think the Rust guys actually sell this line, so I'm arguing against you, not them).
No one will ever invent "the last language you'll ever need." One reason for this is that different languages excel at different things. For example, Rust is not as easy to sandbox as Python, Ruby, etc. It's also not as simple to write quick scripts in.
Another reason is that you'll never convince everyone in the world to use the same language. Even if you convinced them that they should use the same language (which is impossible), there are billions of lines of code in use that is written in different languages. If you can't interoperate with them, you are a rock, you are an island.
There's nothing "modern" about the idea that "we're going to make the last language you'll ever need."
Grandparent has a point, and it's not quite as outlandish as you make it out to be.
Consider that a lot of Python developers write most of their code in Python, then rewrite critical parts in C to speed it up. Python is not a speed demon, and that becomes particularly problematic with tight loops or heavy math—but writing entire applications in C is error-prone and tedious.
Rust won't outright replace both of those, but it does offer a nice middle ground: it's safe, it has some higher-level constructs, it does away with some boilerplate, it builds fairly easily, and it still compiles essentially to machine code. Writing quick shell-like scripts or entire applications in a systems language is now a viable option for lazy jerks like me, even if it's not always the best one.
> Writing quick shell-like scripts or entire applications in a systems language is now a viable option for lazy jerks like me, even if it's not always the best one.
I agree completely. I love Rust for this reason too. That's not what the grandparent said, or what I'm arguing against.
Grandparent was dismissing my concern about language interoperability because new languages should cover "all your needs." This attitude is closed-minded and dangerous.
A language that covers lots of needs is great. A language that is so useful that you find yourself needing fewer total languages for your project is great.
But the moment you use that as a reason to stop caring about interoperability between languages, to argue that it doesn't matter whether your language can interface with others, that's the moment when I stop paying attention to what you are designing.
Of the new languages I've seen lately, Rust is my favorite. I love how it gives me better ways to express things I actually want to say without imposing GC on me.
But even so, I can't see myself actually using it for much, because writing in a language other than C means buying in to that language's runtime. Buying into one language's runtime means that your code won't play nice with other languages' runtimes.
If I write a library in Rust, how can I expose my types and algorithms to Ruby, Python, Lua, etc? How will Rust Tasks play with Python threads? What if I use a Rust Pipe to send a Python value between tasks? How do I keep Rust from doing a GC pass while I'm holding the Python GIL? etc. etc.
Programming Languages by their nature want to be at the center of your world. If you buy into their abstractions, everything works nicely. But if you try to mash two of them together in a single process, you start to suffer from the fact that their abstractions overlap and don't interoperate at all.
If you're only writing an application (ie. not a library) and never want to embed other languages into your application, then this might be ok. But I'm more interested in writing shared functionality that is useful across languages. Why should the whole stack of parsers, crypto, compression, etc. have to be written separately in each language? Life is too short to do some great work that is only usable by one language community -- computing is so big and changes so much that one-language-only functionality is at best limiting your market and at worst dooming your code to obsolescence when the next big language comes around.
So as much as I instinctively like Rust, I think I'll be sticking with C.