<p>I am new to language development. I am aware of Rust's ownership model that builds programs in a way that does not need garbage collection.</p>
<p>So if I am to build a new programming language using safe Rust exclusively, will it be that the programming language will not need for me to implement garbage collection?</p>
<p>Here is the context;</p>
<p>I want to create an interpreted language. I have decided to either use <a href="https://nim-lang.org/" rel="nofollow noreferrer">Nim</a> or Rust.</p>
<p>I love Nim's syntax and find it fun to work with. I also hear interesting things concerning Rust, especially regarding its safety features.</p>
<p>So my questions are;</p>
<ol>
<li><p>Does using Rust eliminate the need to implement garbage collection in a language? If not, what other benefits do you think one can get by using Rust for working on an interpreted language?</p>
</li>
<li><p>If I am to use Nim, what exactly will I be losing (or gaining) over rust?</p>
</li>
</ol>

<language-design><rust><garbage-collection><memory-safety>
Does using Rust eliminate the need to implement garbage collection in a language?
CC BY-SA 4.0
2023-09-27T18:00:02.420Z
If you use Rust to implement a different language, then the fact that Rust - the host language - does not use a GC, does not imply anything about whether the language you are implementing will have a GC or not. That's a language design decision for you, the language designer, to make.
kaya3
CC BY-SA 4.0
2023-09-27T18:08:27.650Z
The top question here about GC is answerable, but the two labelled “my questions” are different and very broad currently. Which part of this are you looking for an answer to here? You can ask separate questions for different topics, although the broad ones would need to be dialed in a bit more for people to be able to give you good answers.
Michael Homer
CC BY-SA 4.0
2023-09-27T18:09:02.603Z
Welcome to PLDI! One thing worth noting is that the things you hear about Rust regarding safety are typically relative to lower level languages like C/C++. Nim is likely to be similar in how safe it is (I don't know much about it tho).
rydwolf
CC BY-SA 4.0
2023-09-27T18:17:43.610Z
Nim has a GC (you can choose from multiple GCs, actually, or no GC if you want), so if you make an interpreter in Nim and don't do any unsafe stuff, you shouldn't need to implement garbage collection yourself. I'm not sure why you mentioned Nim and Rust specifically, because any language that has either a GC or borrow checking like Rust can be used to implement an interpreter without requiring another GC, as long as you don't do something unsafe that the GC or borrow checker don't know about/can't handle.
user
CC BY-SA 4.0
2023-09-27T19:01:32.933Z
You should think about whether your language implementation is as an interpreter or with a compiler — you didn't say, and it can make a difference.
Erik Eidt
CC BY-SA 4.0
2023-09-27T19:06:35.673Z
Rust has memory safety but for complex data structures (like an AST) that means using reference counting (which is not guaranteed to not leak), unsafe code (which gives up the safety), or other non-trivial approaches (e.g. https://rdambrosio016.github.io/rust/2020/09/18/pure-ast-based-linting-sucks.html)
Erik Eidt
<p>No, while rust's safety model will prevent many types of memory errors like use-after-free, it does not prevent memory leaks. From the Rust book:</p>
<blockquote>
<p>Rust’s memory safety guarantees make it difficult, but not impossible, to accidentally create memory that is never cleaned up (known as a memory leak). Preventing memory leaks entirely is not one of Rust’s guarantees in the same way that disallowing data races at compile time is, meaning memory leaks are memory safe in Rust. We can see that Rust allows memory leaks by using Rc and RefCell: it’s possible to create references where items refer to each other in a cycle. This creates memory leaks because the reference count of each item in the cycle will never reach 0, and the values will never be dropped.</p>
</blockquote>
<p>You can trivially create a memory leak by creating a cycle with an <code>Arc&lt;T&gt;</code>/<code>Rc&lt;T&gt;</code>. Also functions like <a href="https://doc.rust-lang.org/std/mem/fn.forget.html" rel="nofollow noreferrer"><code>std::mem::forget</code></a> are considered safe even though they may leak memory.</p>
<p>A language implemented only in safe rust will inherit rust's safety guarantees, but may still leak memory as that isn't one of the guarantees. If you want memory usage to stay within limits you need some system to detect leaked objects and free them (eg. a Mark and Sweep Garbage Collector)</p>
<p>You don't <em>need</em> a garbage collector though, if you are willing to accept leaks can happen and are not much of a problem. PHP for example uses only reference counting to free objects which means it will leak memory in much the same situations as rust would. If you are a language intended to be used for short scripts it may not be a huge problem.</p>
<p>Further reading:</p>
<ul>
<li><a href="https://stackoverflow.com/q/56107324/6333444">Why does Rust consider it safe to leak memory?</a></li>
<li><a href="https://stackoverflow.com/a/74824895/6333444">Why is it considered safe to <code>mem::forget</code> Boxes?</a></li>
</ul>

CC BY-SA 4.0
2023-09-28T07:43:43.110Z
2024-11-29T18:55:23.780Z
2024-11-29T18:55:23.780Z
mousetail 'he-him'
CC BY-SA 4.0
2023-10-28T13:38:53.270Z
PHP does not leak memory with circular references; it keeps a list of freed references, and periodically runs a specific garbage collection algorithm to detect if any lead to closed cycles. This has been enabled by default since PHP 5.3, released in 2009. See https://www.php.net/manual/en/features.gc.collecting-cycles.php
IMSoP
<p>Rust does not provide garbage collection out of the box. But when you write a new language in Rust, the new language may require garbage collection. You can not write a Scheme interpreter without implementing a garbage collector. Whether you need a garbage collector depends on the language you want to implement. Rust does not require one, but other languages require one. And if the new language requires garbage collection, Rust's borrow semantics will not help. You have to write a garbage collector in Rust in the same way people wrote garbage collectors in C.</p>

CC BY-SA 4.0
2023-11-08T20:06:15.790Z
2023-11-08T20:06:15.790Z
ceving
<blockquote>
<p>Does using Rust eliminate the need to implement garbage collection in a language?</p>
</blockquote>
<p>No. The language in which a language is implemented has almost nothing to do with the properties of the implemented language. Rust was originally written in OCaml, for example, but OCaml is garbage collected and Rust is not.</p>
<blockquote>
<p>If I am to use Nim, what exactly will I be losing (or gaining) over Rust?</p>
</blockquote>
<p>As you noted, Nim is garbage collected (reference counted) and does not use an ownership system for anything other than eliding reference counts. There are some data structures that are difficult to represent in an ownership system like Rust, notably graphs. If you use a graph to represent any part of your language - and you likely will - it's probable that you will run into difficulties with the borrow checker, especially starting off, or have to fall back on using <code>Rc</code> and <code>Arc</code> to form a reference-counted structure. (a possible alternative is to instead <a href="https://manishearth.github.io/blog/2021/03/15/arenas-in-rust/" rel="nofollow noreferrer">represent graphs as <code>Vecs</code></a>)</p>
<p>Rust is descended from the ML family of languages, however, and inherited many of their features that make them nice for building languages (ML: literally &quot;Meta Language&quot;). The combination of Rust's <code>struct</code> and <code>enum</code> types allow for the modelling of many data structures useful for implementing a language, while its <code>match</code> statement allows for structurally decomposing them. These are <em>heavily</em> inspired by ML's <code>data</code>/<code>type</code>/<code>datatype</code> and <code>match</code>/<code>case/of</code> constructs.</p>
<p>Rust's <code>struct</code> is directly equivalent to Nim's <code>object</code>. Rust's <code>enum</code> has no direct equivalent. Instead, Nim has &quot;object variants&quot;: structs that have a tag that can be matched upon to access different fields. This means that fields can be shared across variants, unlike Rust's <code>enum</code>, but the tag must be explicitly defined separately. This is generally a little harder to work with. Nim also does not have structural pattern matching: its <code>case/of</code> statement can only match upon ordinal types and strings (though, there are libraries that extend it to work structurally).</p>
<p>There's not a right or wrong choice, of course, and there are many examples of languages implemented in both, but hopefully that provided some exposition as to what language features make a language suitable for implementing other languages in.</p>

CC BY-SA 4.0
2023-10-26T12:53:34.450Z
2024-06-22T19:18:15.780Z
2024-06-22T19:18:15.780Z
apropos
CC BY-SA 4.0
2023-10-27T12:45:19.720Z
"there are many examples of languages implemented in both" have people have written a lot of compilers in Nim? Actually while I'm less surprised about Rust for all the reasons you name I'd love for you to link some of the Rust examples as well.
Jared Smith
CC BY-SA 4.0
2023-10-28T11:02:45.057Z
Yes! Here are a couple: https://github.com/arturo-lang/arturo, https://github.com/h3rald/min, https://github.com/calebwin/pipelines. Plus the Nim compiler itself and community libraries of a certain complexity, ex. the LLVM backend.

As for Rust, there's a neatly collected (and long) list at https://github.com/alilleybrinker/langs-in-rust.
apropos
CC BY-SA 4.0
2024-03-10T10:50:34.277Z
Trees actually follow Rust's ownership model very nicely, because each node has exactly one owner. I think you're thinking of graphs. If you had any particular examples in mind I would be very interested to hear them.
Charlie Lidbury
<blockquote>
<p>Does using Rust eliminate the need to implement garbage collection in a language?</p>
</blockquote>
<p>No. Rust’s memory management relies on semantic properties of the language that are carefully guaranteed. Unless your language is implemented as an embedded domain-specific language within Rust (that is, it is “just” a Rust library, perhaps with some fancy macros to provide sugar), you cannot easily inherit these guarantees from the host language, so you will still have to worry about your language’s memory management in the usual way.</p>
<p>If your language is interpreted, and you wish to remain within the safe subset of Rust, you <em>will</em> somehow have to prove to the borrow checker that values of your language have well-defined lifetimes. Depending on the semantics of your language, this may be tricky to do. On the other hand, if your language is compiled, Rust’s memory management has little impact on the memory and lifetime semantics of your language, as you are free to produce whatever code you’d like.</p>
<p>If your language is intended to support fully automatic memory management without explicit lifetimes, then an interpreter is likely to be easier to implement in a garbage collected language, as it <em>is</em> possible to reuse the garbage collector of the host language in that case. However, again, if your language is compiled, the memory management of the host language is essentially irrelevant.</p>
<blockquote>
<p>If not what other benefits do u think one can get by using Rust for working on an interpreted language. […] If I am to use Nim what exactly will I be missing out (or benefiting) on if I choose to use Nim or Rust to implement a language.</p>
</blockquote>
<p>These questions are not on-topic on this site, as they are extremely broad and in some cases essentially come down to opinion. Also, more broadly, it’s best to only ask one question per question on Stack Exchange sites. See our <a href="https://langdev.stackexchange.com/help/on-topic">Help Center</a> for what types of questions you can ask here.</p>

CC BY-SA 4.0
2023-09-27T18:13:53.640Z
2023-09-27T18:13:53.640Z
Alexis King
CC BY-SA 4.0
2023-09-28T07:06:30.840Z
In short (and assuming that my own understanding is correct), simple data types like integers will be deallocated once the the semantics determine they will no longer be used, while more complex types like strings are garbage collected. It is this semantic analysis, as distinct from a simple consideration of scope etc., which distinguishes Rust from its ALGOL-based predecessors.
Mark Morgan Lloyd
CC BY-SA 4.0
2023-09-28T08:48:45.770Z
@MarkMorganLloyd describing rust as Garbage Collected is a bit iffy. Most common understandings of garbage collection are about scanning collectors, which rust does not have. Rusts analysis falls under the same bucket as Objective C++ ARC, and RAII. Semantic lifetime analysis which is different enough to be regarded as seperate.
user1937198
CC BY-SA 4.0
2023-09-28T08:51:29.930Z
@user1937198 I agree, but I was trying to to stray too far from OP's phrasing. Also I think it's fair- in the general case- to assume that implementations can use different classes of storage one of which might be heap for strings etc.
Mark Morgan Lloyd
CC BY-SA 4.0
2023-09-28T08:56:46.787Z
@MarkMorganLloyd An interpreter might. Rust as it currently stands? Only one heap in the standard library. Any alternative allocation store would be a custom library. Whether the rust language recognizes the existence of heap at all is a bit iffy, boxes etc are part of alloc, not core, and running Rust with just core is a standard supported configuration, unlike say C where the standard specifies malloc will exist because the standard only specifies the full stdlib.
user1937198
# Does using Rust eliminate the need to implement garbage collection in a language?
Posted by: username_0 on 2023-09-27
I am new to language development. I am aware of Rust's ownership model that builds programs in a way that does not need garbage collection.

So if I am to build a new programming language using safe Rust exclusively, will it be that the programming language will not need for me to implement garbage collection?

Here is the context;

I want to create an interpreted language. I have decided to either use [Nim](https://nim-lang.org/) or Rust.

I love Nim's syntax and find it fun to work with. I also hear interesting things concerning Rust, especially regarding its safety features.

So my questions are;

1. Does using Rust eliminate the need to implement garbage collection in a language? If not, what other benefits do you think one can get by using Rust for working on an interpreted language?
2. If I am to use Nim, what exactly will I be losing (or gaining) over rust?
**Tags:** language-design rust garbage-collection memory-safety
> **Comments:**
> **username_1**: If you use Rust to implement a different language, then the fact that Rust - the host language - does not use a GC, does not imply anything about whether the language you are implementing will have a GC or not. That's a language design decision for you, the language designer, to make.  
> **username_2**: The top question here about GC is answerable, but the two labelled “my questions” are different and very broad currently. Which part of this are you looking for an answer to here? You can ask separate questions for different topics, although the broad ones would need to be dialed in a bit more for people to be able to give you good answers.  
> **username_3**: Welcome to PLDI! One thing worth noting is that the things you hear about Rust regarding safety are typically relative to lower level languages like C/C++. Nim is likely to be similar in how safe it is (I don't know much about it tho).  
> **username_4**: Nim has a GC (you can choose from multiple GCs, actually, or no GC if you want), so if you make an interpreter in Nim and don't do any unsafe stuff, you shouldn't need to implement garbage collection yourself. I'm not sure why you mentioned Nim and Rust specifically, because any language that has either a GC or borrow checking like Rust can be used to implement an interpreter without requiring another GC, as long as you don't do something unsafe that the GC or borrow checker don't know about/can't handle.  
> **username_5**: You should think about whether your language implementation is as an interpreter or with a compiler — you didn't say, and it can make a difference.  
> **username_5**: Rust has memory safety but for complex data structures (like an AST) that means using reference counting (which is not guaranteed to not leak), unsafe code (which gives up the safety), or other non-trivial approaches (e.g. https://rdambrosio016.github.io/rust/2020/09/18/pure-ast-based-linting-sucks.html)  
---
## 4 answers
### Answer by username_12 on 2023-09-27. Score: 29 | Accepted answer
> Does using Rust eliminate the need to implement garbage collection in a language?

No. Rust’s memory management relies on semantic properties of the language that are carefully guaranteed. Unless your language is implemented as an embedded domain-specific language within Rust (that is, it is “just” a Rust library, perhaps with some fancy macros to provide sugar), you cannot easily inherit these guarantees from the host language, so you will still have to worry about your language’s memory management in the usual way.

If your language is interpreted, and you wish to remain within the safe subset of Rust, you *will* somehow have to prove to the borrow checker that values of your language have well-defined lifetimes. Depending on the semantics of your language, this may be tricky to do. On the other hand, if your language is compiled, Rust’s memory management has little impact on the memory and lifetime semantics of your language, as you are free to produce whatever code you’d like.

If your language is intended to support fully automatic memory management without explicit lifetimes, then an interpreter is likely to be easier to implement in a garbage collected language, as it *is* possible to reuse the garbage collector of the host language in that case. However, again, if your language is compiled, the memory management of the host language is essentially irrelevant.

> If not what other benefits do u think one can get by using Rust for working on an interpreted language. […] If I am to use Nim what exactly will I be missing out (or benefiting) on if I choose to use Nim or Rust to implement a language.

These questions are not on-topic on this site, as they are extremely broad and in some cases essentially come down to opinion. Also, more broadly, it’s best to only ask one question per question on Stack Exchange sites. See our [Help Center](https://langdev.stackexchange.com/help/on-topic) for what types of questions you can ask here.
> **Comments:**
> **username_13** (2023-09-28): In short (and assuming that my own understanding is correct), simple data types like integers will be deallocated once the the semantics determine they will no longer be used, while more complex types like strings are garbage collected. It is this semantic analysis, as distinct from a simple consideration of scope etc., which distinguishes Rust from its ALGOL-based predecessors.  
> **username_14** (2023-09-28): @MarkMorganLloyd describing rust as Garbage Collected is a bit iffy. Most common understandings of garbage collection are about scanning collectors, which rust does not have. Rusts analysis falls under the same bucket as Objective C++ ARC, and RAII. Semantic lifetime analysis which is different enough to be regarded as seperate.  
> **username_13** (2023-09-28): @user1937198 I agree, but I was trying to to stray too far from OP's phrasing. Also I think it's fair- in the general case- to assume that implementations can use different classes of storage one of which might be heap for strings etc.  
> **username_14** (2023-09-28): @MarkMorganLloyd An interpreter might. Rust as it currently stands? Only one heap in the standard library. Any alternative allocation store would be a custom library. Whether the rust language recognizes the existence of heap at all is a bit iffy, boxes etc are part of alloc, not core, and running Rust with just core is a standard supported configuration, unlike say C where the standard specifies malloc will exist because the standard only specifies the full stdlib.  
---
### Answer by username_6 on 2023-09-28. Score: 6
No, while rust's safety model will prevent many types of memory errors like use-after-free, it does not prevent memory leaks. From the Rust book:

> Rust’s memory safety guarantees make it difficult, but not impossible, to accidentally create memory that is never cleaned up (known as a memory leak). Preventing memory leaks entirely is not one of Rust’s guarantees in the same way that disallowing data races at compile time is, meaning memory leaks are memory safe in Rust. We can see that Rust allows memory leaks by using Rc and RefCell: it’s possible to create references where items refer to each other in a cycle. This creates memory leaks because the reference count of each item in the cycle will never reach 0, and the values will never be dropped.

You can trivially create a memory leak by creating a cycle with an `Arc`/`Rc`. Also functions like [`std::mem::forget`](https://doc.rust-lang.org/std/mem/fn.forget.html) are considered safe even though they may leak memory.

A language implemented only in safe rust will inherit rust's safety guarantees, but may still leak memory as that isn't one of the guarantees. If you want memory usage to stay within limits you need some system to detect leaked objects and free them (eg. a Mark and Sweep Garbage Collector)

You don't *need* a garbage collector though, if you are willing to accept leaks can happen and are not much of a problem. PHP for example uses only reference counting to free objects which means it will leak memory in much the same situations as rust would. If you are a language intended to be used for short scripts it may not be a huge problem.

Further reading:

* [Why does Rust consider it safe to leak memory?](https://stackoverflow.com/q/56107324/6333444)
* [Why is it considered safe to `mem::forget` Boxes?](https://stackoverflow.com/a/74824895/6333444)
> **Comments:**
> **username_7** (2023-10-28): PHP does not leak memory with circular references; it keeps a list of freed references, and periodically runs a specific garbage collection algorithm to detect if any lead to closed cycles. This has been enabled by default since PHP 5.3, released in 2009. See https://www.php.net/manual/en/features.gc.collecting-cycles.php  
---
### Answer by username_8 on 2023-11-08. Score: 1
Rust does not provide garbage collection out of the box. But when you write a new language in Rust, the new language may require garbage collection. You can not write a Scheme interpreter without implementing a garbage collector. Whether you need a garbage collector depends on the language you want to implement. Rust does not require one, but other languages require one. And if the new language requires garbage collection, Rust's borrow semantics will not help. You have to write a garbage collector in Rust in the same way people wrote garbage collectors in C.
---
### Answer by username_9 on 2023-10-26. Score: 1
> Does using Rust eliminate the need to implement garbage collection in a language?

No. The language in which a language is implemented has almost nothing to do with the properties of the implemented language. Rust was originally written in OCaml, for example, but OCaml is garbage collected and Rust is not.

> If I am to use Nim, what exactly will I be losing (or gaining) over Rust?

As you noted, Nim is garbage collected (reference counted) and does not use an ownership system for anything other than eliding reference counts. There are some data structures that are difficult to represent in an ownership system like Rust, notably graphs. If you use a graph to represent any part of your language - and you likely will - it's probable that you will run into difficulties with the borrow checker, especially starting off, or have to fall back on using `Rc` and `Arc` to form a reference-counted structure. (a possible alternative is to instead [represent graphs as `Vecs`](https://manishearth.github.io/blog/2021/03/15/arenas-in-rust/))

Rust is descended from the ML family of languages, however, and inherited many of their features that make them nice for building languages (ML: literally "Meta Language"). The combination of Rust's `struct` and `enum` types allow for the modelling of many data structures useful for implementing a language, while its `match` statement allows for structurally decomposing them. These are *heavily* inspired by ML's `data`/`type`/`datatype` and `match`/`case/of` constructs.

Rust's `struct` is directly equivalent to Nim's `object`. Rust's `enum` has no direct equivalent. Instead, Nim has "object variants": structs that have a tag that can be matched upon to access different fields. This means that fields can be shared across variants, unlike Rust's `enum`, but the tag must be explicitly defined separately. This is generally a little harder to work with. Nim also does not have structural pattern matching: its `case/of` statement can only match upon ordinal types and strings (though, there are libraries that extend it to work structurally).

There's not a right or wrong choice, of course, and there are many examples of languages implemented in both, but hopefully that provided some exposition as to what language features make a language suitable for implementing other languages in.
> **Comments:**
> **username_10** (2023-10-27): "there are many examples of languages implemented in both" have people have written a lot of compilers in Nim? Actually while I'm less surprised about Rust for all the reasons you name I'd love for you to link some of the Rust examples as well.  
> **username_9** (2023-10-28): Yes! Here are a couple: https://github.com/arturo-lang/arturo, https://github.com/h3rald/min, https://github.com/calebwin/pipelines. Plus the Nim compiler itself and community libraries of a certain complexity, ex. the LLVM backend.

As for Rust, there's a neatly collected (and long) list at https://github.com/alilleybrinker/langs-in-rust.  
> **username_11** (2024-03-10): Trees actually follow Rust's ownership model very nicely, because each node has exactly one owner. I think you're thinking of graphs. If you had any particular examples in mind I would be very interested to hear them.  
---
