Have there been any discussions on newer memory mo...
# thinking-together
c
Have there been any discussions on newer memory models like rusts borrowing opposed to RC/GC?
s
I don't know of any discussion but @Wouter mentioned his language Lobster does borrow checking now too. (http://aardappel.github.io/lobster/memory_management.html)
👍 3
w
I’ve written a fair amount about Rust. Explaining the memory model: http://cs242.stanford.edu/f18/lectures/05-1-rust-memory-safety.html and http://cs242.stanford.edu/f18/lectures/06-1-smart-pointers.html Replacing LLVM with Rust: http://willcrichton.net/notes/rust-the-new-llvm/ Usability issues with the borrow checker: https://arxiv.org/abs/1901.01001 Teaching PL theory with Rust: https://arxiv.org/abs/1904.06750 Jon Goodwin, who works on the Cone language, has also thought about this a lot: http://jondgoodwin.com/pling/gmm.pdf
👍 3
o
@Will thanks for sharing. Your teaching looks very intersting, I wish I could have followed your course! (but I am both too old and too far...)
🤗 1
@Carlo Kok and @shalabh, I found this page in the Lobster's documentation, that contains a short list of languages that follow the path of ownership models: http://aardappel.github.io/lobster/memory_management.html
w
@shalabh @ogadaki thanks for linking my doc 🙂
@Will that looks cool, will have to check those out
Using Rust as a backend for languages sounds.. difficult.. if the new language doesn't map closely to Rust. You'll end up emulating an unrelated memory model in an array and it will neither be very typesafe nor efficient (compared to C)
w
What would you say is an example of a language that wouldn’t map closely to Rust?
c
@Will Not the person you answered to; but really any OOP language wouldn't easily map to Rust?
I do quite like the ownership model of rust; it's something I want in my languages too, though the way rust enforces it is a bit too invasive to tackle on now (the compiler has been around for a few years and this would be fairly breaking)
w
@Will almost all of them. A language that also has ownership might map well, but Rust wants this done statically, so the semantics would have to map almost 1:1 for this to work. Beyond that, you are in the territory of emulating things. A reference counted language would work decently well for Rust. Most dynamically typed languages, or GC languages, are so far removed from Rust that there's no meaningfull advantage to Rust's type safety and ownership anymore. Some dynamically typed languages could be implemented directly using a Rust enum, but if you look at the crazy shit many language implementations do with memory, you'll end up with.. the array of bytes as the only translation mechanism. And random access arrays in Rust will not compete with C because of bounds checking, correct me if I am wrong.
Or let me put it this way: take the 100 most popular or well known programming languages, and their most well known implementation, 99% or which will be in C/C++, and try and translate them to Rust. You'll a) be in a world of pain trying to find a mapping, assuming you don't default to "array of bytes", b) be less efficient, and c) for at least 90% of them, don't gain any of the safety and other benefits of Rust you claim in your article
And I say that as a total fanboy of Rust, who wishes he could wave a magic wand and have all the piles of C++ he has to work every day with translated into Rust. I just don't see how it is a good target for codegen or runtimes, compared to C/C++, llvm IR or x86/arm 🙂
w
I don’t think I buy “so far removed from Rust that there’s no meaningfull advantage to Rust’s type safety and ownership anymore”. If you’re implementing a statically typed language, you get the type system. If you’re implementing a dynamically typed language, you get both a safe interpreter implementation and simple type-level interop to Rust. And GC can work with Rust, although that is an active area of work.
The main point there is that if you have a struct in your higher-level language, then you get a struct at the Rust-level, just wrapped in a smart pointer. That’s the dream.
And that smart pointer might be extremely complicated depending on the complexity of the high-level language runtime, but at least Rust can understand the type at some level above
u8*
.
That said, I understand that the vision in that blog post is very much a pie-in-the-sky kind of idea. It’s less a “we can go out and literally convert every language today” and more a vision statement on the possibilities for more deeply integrating the target language with the host language in a compiler/runtime, and what opportunities that affords.
c
@Will a high level "llvm" would help a lot advance the progress of programming languages for sure. If the Rust internals are that is hard to judge for me, though, for sure not until it's stable (stable as in, a stable api).
w
@Will most statically typed languages will not have Rust's ownership system, so they do not map 1:1 to Rust, and will need to subvert Rust's ownership at least with Rc.. to implement GC.. I guess you could have 1 array per struct type, with pointers being typesafe indices, and then GC that somehow.. but that is way less efficient than the "bump allocator" efficient GCs rely on, and lets not speak of generational or concurrent GC which would be really difficult to make efficient in Rust
The key here is efficient.. there's always a way to emulate anything in Rust, but if the delta with how you can do it in C/C++ is too big, it won't be attractive to language implementors
Like, representing an integer as a
Rc<RefCell<Rc<RefCell<Box<Any>>>>>
doesn't sound that great to me 🙂
Meanwhile, in one of my languages, an int just overlaps with pointers in a type unsafe union, which is an extremely common way to implement programming languages in C/C++: https://github.com/aardappel/lobster/blob/a57a300626bba29cdfd16912e25071da04405284/dev/src/lobster/vmdata.h#L393-L414
Note that this is a statically typed language, and the compiler knows the types of these values everywhere in memory mostly statically, but I have no way to express that in the target language.
In Rust, an
enum
carries its type tag always, which when you account for alignment, would double the memory usage of this language implementation, which is unacceptable. Note that in the link above I have a way to turn on type tags when I am debugging an error in the language implementation, but are off by default
If I was writing another dynamically typed language where max performance wasn't a goal, implementing it with Rust enums would be wonderful. But dynamically typed languages are very easy to get robust in C/C++ too. And sadly I am currently not into dynamic typing 🙂
Did you see http://aardappel.github.io/lobster/memory_management.html btw? I would love to hear what a Rust expert such as yourself thinks of this, good or bad 🙂
w
All fair points. A big question is--I’m fairly confident that basically any memory management strategy you could implement in C/C++ (concurrent/generational GC, etc.) you can with enough work and unsafe code implement in Rust, and usually come out with a nominally safe top-level API at the end of the day. I agree it’s not obvious that once you’ve implemented all the necessary machinery where you’ll be on the spectrum between
SmartPointer<UnderstandableType>
and
OpaqueBlob
, although my hypothesis is that it’s far enough to the left to drive progress.
Part of this dream is that then you wouldn’t need a
union { AllOfMyTypes }
, at least for statically typed languages.
One way of looking at it: a statically typed, garbage collected language implemented in Rust is not a huge runtime or virtual machine. It’s just a staged metaprogram that inserts
Gc
or
BumpGc
(or whatever) types, constructors, and dereferences at all the appropriate places.
That said, having not tried this beyond an inefficient toy language, it would not be wholly surprising if that’s not efficiently achievable today due to limitations I can’t foresee.
And I haven’t read the Lobster page but it seems like a good read, I’ll check it out! Thanks for the healthy discussion @Wouter.
w
Yup, I am pretty sure we'll see a great increase of language implemented in Rust (very suitable) or even compiling to Rust.
And yes, this is a topic I'm pretty passionate about 🙂
s
Would you implement Lobster in Rust? Or in Lobster itself? 😄
w
@shalabh The VM is going to stay in C++ for the foreseeable future, because of reasons mentioned above (mainly speed).. but the compiler itself could easily move to another language, which would make it nicer to work on. Rust and Lobster itself would be the primary contenders 🙂 It's a lot of work rewriting that much C++ though, so I thought of doing it incrementally.. first the parser etc.