notes-computer-programming-programmingLanguageDesign-prosAndCons-interop

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


pcwalton 117 days ago

link

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

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


radarsat1 117 days ago

link

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.

[1] http://claylabs.com/clay/


pcwalton 117 days ago

link

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.


pron 116 days ago

link

> The language itself knows nothing about tasks; they're purely part of the runtime library.

How are they implemented? Do you provide access to low level concurrency constructs such as CAS, threads etc.? "

---

" Rust does currently depend on a language runtime which expects to control the execution of all Rust code (in particular managing the task scheduler), and the runtime does not have an embedding story yet. Even with an embeddable runtime though, the process would be more involved than loading a library through `dlopen` and executing a function. "