<p>In the context of <a href="https://en.wikipedia.org/wiki/Bootstrapping_(compilers)" rel="nofollow noreferrer">bootstrapping</a> quite a few languages are fully <a href="https://en.wikipedia.org/wiki/Self-hosting_(compilers)" rel="nofollow noreferrer">self hosted</a>.</p>
<p>Becoming self hosting is often treated as a significant milestone in the development of a programming language.
Once you have achieved this milestone you are no longer forced to develop future versions of the compiler in some other language (Typically one the languages community considers inferior).</p>
<p>What puzzles me is why these bootstrap compilers are subsequently discarded rather than being replaced.
(See also: <a href="https://langdev.stackexchange.com/q/912">What are the benefits to self-hosting compilers?</a>)</p>
<p>Reproducible builds now require a binary package for the target platform.
If you want to port to a new platform you are forced to either bootstrap again or implement a cross compiler.</p>
<p>To make porting possible I would expect to either:</p>
<ul>
<li><p>Provide just enough maintenance of the bootstrap compiler that it can be used to assist porting to another platform (Particularly if it is something ubiquitous like C)</p>
</li>
<li><p>Provide an inefficient translator / transpiler</p>
</li>
<li><p>Implement a cross-compiler</p>
</li>
</ul>
<p>The latter two approaches could be written in the new laguage or leverage an existing backend like LLVM or something else.</p>
<p>So my question is:</p>
<ul>
<li><p>Is abandoning the bootstrap issue really sensible philosophically?
Do many languages really do that? or is it more a case that they assume the original code is still in a repo somewhere and if it doesn't still compile could be made to if needed.</p>
</li>
<li><p>Which of the above mechanisms do some languages use and what are the trade offs?
Are they blessed by the language vendor/community?</p>
</li>
</ul>
<hr />
<h3>Examples</h3>
<p>I may have some things wrong as I am not an expert in these languages</p>
<h4>C</h4>
<p>Cross compilers are the dominant way to bootstrap.</p>
<h4>Haskell</h4>
<p>You can bootstrap GHC (Haskell) from C.</p>
<p>I consider this a wise choice despite the maturity of GHC.</p>
<h4>Rust</h4>
<p>For example to build a rust compiler you must first download a rust compiler.
This is okay as there are trusted binary packages for your favourite linux distributions
etc.</p>
<p>See also: <a href="https://internals.rust-lang.org/t/impediments-to-transpile-rust-to-c/8112" rel="nofollow noreferrer">Impediments to transpile Rust to C?</a>
and <a href="https://github.com/thepowersgang/mrustc" rel="nofollow noreferrer">mrustc</a>.</p>
<p>mrustc and rust2c exist but do not seem to be 'blessed' by the community.</p>
<h4>Red</h4>
<p>Years ago I asked: <a href="https://stackoverflow.com/q/48178976">Compile red and red/system compilers from source</a></p>
<p>It still appears to be the case that red and rebol require you to download a blessed implementation of red or rebol.</p>
<p>See also: <a href="https://github.com/red/red" rel="nofollow noreferrer">red</a> and <a href="https://github.com/Oldes/Rebol3" rel="nofollow noreferrer">Rebol3</a> and <a href="https://github.com/metaeducation/ren-c" rel="nofollow noreferrer">ren-c</a></p>
<hr />
<p>References (Not relevant to the question but relevant may be relevant to people landing here): <a href="https://stackoverflow.com/q/73550418">How come a bootstrapped compiler works without source language?</a> and <a href="https://stackoverflow.com/q/193560">Writing a compiler in its own language</a></p>

<bootstrapping>
Why do many language implementations not provide an option to bootstrap from another language?
CC BY-SA 4.0
2023-06-25T23:36:45.850Z
As a counterexample, I'm fairly sure Zig maintains its bootstrap compiler.
Bbrk24
CC BY-SA 4.0
2023-06-26T00:04:43.577Z
"Reproducible builds now require a binary package *for the target platform*." Now there is an alternative: a wasm+wasi module (still a binary, but cross-platform). Apparently Zig has [already gone that route](https://github.com/ziglang/zig/pull/13560).
Bubbler
<h1>Maintenance</h1>
<p>Maintaining two compilers and ensuring that they are both compliant is a tall order, especially for languages like Rust which are in constant evolution.</p>
<p>An option is to maintain a compiler that only compiles a subset of the language and then use only that subset in the final compiler, but that's still a hard task and you'd be limiting the code quality of your final compiler.</p>

CC BY-SA 4.0
2023-06-25T21:39:36.547Z
2023-06-25T21:39:36.547Z
kouta-kun
<p>There is an alternative to bootstrapping with a mature fully-functional compiler or compiling with another language - <em>growing</em> a language.</p>
<p>This way you only need an external compiler, interpreter or whatever to start the tiny core of the language. The rest of the functionality can be added in the build process incrementally, eventually constructing the fully functional compiler that can be used to re-compile the underlying layers.</p>
<p>This approach works with languages that have sufficiently powerful metaprogramming capabilities, at least at the bootstrap stage (they can be reduced later if you don't trust your users with so much power). I experimented with using only a tiny subset of Forth, manually bootstrapped from machine code, to build a small Lisp core that was later grown into a full optimising Lisp compiler. In order to bootstrap this you don't need anything besides an implementation of that tiny Forth, yet the language itself does not have much in common with Forth.</p>

CC BY-SA 4.0
2023-06-25T22:28:47.737Z
2023-06-25T22:28:47.737Z
SK-logic
<p><strong>Disclaimer</strong>: This answer is completely speculation and opinion because I am not a programmer that works on any of those languages.</p>
<p>I think the answer is <strong>convenience</strong>.</p>
<p>Think about it: to have the kind of bootstrap process you want, as a user, the developers need to do extra work.</p>
<p>They need to either:</p>
<ul>
<li><strong>Accept an ever-growing bootstrap process.</strong> This is easiest for them, since they have already done the process to get the current version of the compiler, but since most users don't run Gentoo, they know users won't accept this.</li>
<li><strong>Maintain two separate compilers.</strong> Would you want to do 2x the work? And yes, it's at least 2x because even if the bootstrap compiler is smaller, it's in a language that the developers are less expert in. This applies to cross compilers too, by the way.</li>
<li><strong>Maintain a translator.</strong> This is less work, but it has downsides. If it's in the language of the compiler, how do you bootstrap the translator? If it's not, you again have the problem that the developers are not as good with that language. Plus, such a translator would probably be different enough from a compiler that it could be <em>more</em> work than a bootstrap compiler.</li>
</ul>
<p>Philosophically, whether or not a bootstrap process is needed depends on the situation.</p>
<p>Perhaps the language is <em>not</em> bootstrapped; then no bootstrap is necessary because the compiler can still be built from source.</p>
<p>If the language is bootstrapped, do you <em>really</em> care about the &quot;Trusting Trust&quot; problem? I mean, do you <em>really?</em></p>
<p>Unless you need a Software Bill of Materials, or don't have a trusted distro, nor do you have a irresistible inner drive to watch your machine suffer under heavy compilation (no, I don't have a problem; why do you ask?), you can probably get away with downloading a binary, so just do it.</p>
<p>Even better, if someone <em>else</em> made another compiler, you can use <a href="https://dwheeler.com/trusting-trust/" rel="nofollow noreferrer">Diverse Double-Compiling</a> <em>without</em> a full bootstrap.</p>
<p>On the other hand, if a language's users need those things, they'll make it known, and if they <em>really</em> need them, they'll pay for them. Payment will make the barriers to two compilers go away, I'm sure.</p>
<p>Personally, I'm with you. I don't understand why people don't do it.</p>
<p>My language will have an officially supported C99 backend, and maybe C89. Before release, I'll use that backend to generate a C99 version and check that C code into the repo. Then the bootstrap would just be to build the C99 version, use that to build the regular version, and build again to check. Done.</p>
<p>On top of that, this system will always let me implement the compiler in the latest version of the language, unlike the example in one of the other answers.</p>
<p>But again, I have to implement and support a &quot;translator&quot;; I just think it's worth it because my language would then be available wherever there's a C99 compiler without needing to write specific backends <em>while also</em> taking advantage of optimization work done on C compilers.</p>
<p>Seems like a worthy tradeoff to me.</p>

CC BY-SA 4.0
2023-06-25T22:06:29.810Z
2023-06-25T22:06:29.810Z
Gavin D. Howard
<h3>Because you already bootstrapped yourself from the chicken-egg paradox</h3>
<blockquote>
<p>If you want to port to a new platform you are forced to either bootstrap again or implement a cross compiler.</p>
</blockquote>
<p>On the new platform, you will need:</p>
<ol>
<li>A source front-end for your language;</li>
<li>A binary back-end.</li>
</ol>
<p>Assuming a native compiled language, (2) is inevitable, and you already have (1), so there is no need to bootstrap (1) on the new machine: you will write all pieces of a cross-compiler anyway.</p>
<p>On a language that produces bytecode, (2) is a bigger piece of code that you already have in a portable language, or the bytecode can be &quot;desugared enough&quot;, so a initial cross compiler is easy to code, that in turn <em>already runs your complete language,</em> while you recode or adapt the VM in parallel.</p>
<p>After the initial automatic &quot;simple-and-slow&quot; back-end is substituted by a better back end, it is abandoned.</p>

CC BY-SA 4.0
2023-06-29T16:36:42.753Z
2023-06-29T20:29:38.557Z
2023-06-29T20:29:38.557Z
André L F S Bacci
<p>Because the bootstrap compiler goes out-of-date quickly.</p>
<p>Let's say your language is named Florp. You develop the Florp v0.1 compiler in a language called Glarp, which is similar enough to Florp that you can translate your code from Glarp to Florp. At this point, the language is self-hosted because it's written in itself.</p>
<p>In Florp v0.2 you introduce some great new features: static garbling, runtime charp information, and exception frambling. Since the compiler is now written in Florp, these new features are implemented in Florp v0.1. At this point you have two compilers you might use to compile the Florp v0.2 compiler: the original bootstrap compiler written in Glarp, and the self-hosting one written in Florp v0.1. It doesn't matter which one you use, they are functionally identical.</p>
<p>Then in Florp v0.3 you introduce even more exciting features: zero-cost abstrusion, discriminated intersection types, and an ownership model based on IOU notes. These new features are implemented in Florp v0.2 ─ the new features from v0.2 were very helpful for implementing v0.3! But at this point there is only one compiler you can use to build Florp v0.3, and that's the Florp v0.2 compiler that you built last week.</p>
<p>At this point the language is <em>only</em> self-hosted; there is no bootstrap compiler implemented in a different language that can compile Florp v0.3, because the only source code for it is written in Florp v0.2. In theory, you could translate the Florp v0.3 codebase back to Glarp, but why would you? That would take considerable effort now that Florp is quite a different language to Glarp, and even if you do, it will be out-of-date again as soon as Florp v0.4 comes out a week later.</p>
<p>All of that said, it is still feasible for a third-party user to build Florp v0.3 from source without having to download a binary of the compiler. You just have to download the original Florp v0.1 source code and compile it with your Glarp compiler, then download the Florp v0.2 source code and compile it with Florp v0.1, then download the Florp v0.3 source code and compile it with Florp v0.2. There's just little reason for anyone to do it, and the number of steps required increases each time a new language feature is used in the compiler's codebase.</p>
<hr />
<blockquote>
<p>To make porting possible I would expect to either:</p>
<ul>
<li>provide just enough maintenance of the bootstrap compiler that it can be used to assist porting to another platform (particularly if it is something ubiquitous like C)</li>
<li>provide an inefficient translator / transpiler</li>
<li>implement a cross compiler</li>
</ul>
</blockquote>
<p>A cross-compiler is the sensible option. It's a useful feature not just for building the compiler itself, but also so that every project written by any user of your language can be built for all supported platforms. Anyway, if you're using an existing backend like <a href="https://en.wikipedia.org/wiki/LLVM" rel="noreferrer">LLVM</a> then compiling to different target platforms is practically free.</p>

CC BY-SA 4.0
2023-06-25T21:38:13.223Z
2023-06-25T21:44:32.053Z
2023-06-25T21:44:32.053Z
kaya3
CC BY-SA 4.0
2023-06-26T02:42:02.437Z
+1 just for the features of Florp
Seggan
# Why do many language implementations not provide an option to bootstrap from another language?
Posted by: username_0 on 2023-06-25
In the context of [bootstrapping](https://en.wikipedia.org/wiki/Bootstrapping_(compilers)) quite a few languages are fully [self hosted](https://en.wikipedia.org/wiki/Self-hosting_(compilers)).

Becoming self hosting is often treated as a significant milestone in the development of a programming language.
Once you have achieved this milestone you are no longer forced to develop future versions of the compiler in some other language (Typically one the languages community considers inferior).

What puzzles me is why these bootstrap compilers are subsequently discarded rather than being replaced.
(See also: [What are the benefits to self-hosting compilers?](https://langdev.stackexchange.com/q/912))

Reproducible builds now require a binary package for the target platform.
If you want to port to a new platform you are forced to either bootstrap again or implement a cross compiler.

To make porting possible I would expect to either:

* Provide just enough maintenance of the bootstrap compiler that it can be used to assist porting to another platform (Particularly if it is something ubiquitous like C)
* Provide an inefficient translator / transpiler
* Implement a cross-compiler

The latter two approaches could be written in the new laguage or leverage an existing backend like LLVM or something else.

So my question is:

* Is abandoning the bootstrap issue really sensible philosophically?
  Do many languages really do that? or is it more a case that they assume the original code is still in a repo somewhere and if it doesn't still compile could be made to if needed.
* Which of the above mechanisms do some languages use and what are the trade offs?
  Are they blessed by the language vendor/community?

---

### Examples

I may have some things wrong as I am not an expert in these languages

#### C

Cross compilers are the dominant way to bootstrap.

#### Haskell

You can bootstrap GHC (Haskell) from C.

I consider this a wise choice despite the maturity of GHC.

#### Rust

For example to build a rust compiler you must first download a rust compiler.
This is okay as there are trusted binary packages for your favourite linux distributions
etc.

See also: [Impediments to transpile Rust to C?](https://internals.rust-lang.org/t/impediments-to-transpile-rust-to-c/8112)
and [mrustc](https://github.com/thepowersgang/mrustc).

mrustc and rust2c exist but do not seem to be 'blessed' by the community.

#### Red

Years ago I asked: [Compile red and red/system compilers from source](https://stackoverflow.com/q/48178976)

It still appears to be the case that red and rebol require you to download a blessed implementation of red or rebol.

See also: [red](https://github.com/red/red) and [Rebol3](https://github.com/Oldes/Rebol3) and [ren-c](https://github.com/metaeducation/ren-c)

---

References (Not relevant to the question but relevant may be relevant to people landing here): [How come a bootstrapped compiler works without source language?](https://stackoverflow.com/q/73550418) and [Writing a compiler in its own language](https://stackoverflow.com/q/193560)
**Tags:** bootstrapping
> **Comments:**
> **username_1**: As a counterexample, I'm fairly sure Zig maintains its bootstrap compiler.  
> **username_2**: "Reproducible builds now require a binary package *for the target platform*." Now there is an alternative: a wasm+wasi module (still a binary, but cross-platform). Apparently Zig has [already gone that route](https://github.com/ziglang/zig/pull/13560).  
---
## 5 answers
### Answer by username_7 on 2023-06-25. Score: 22 | Accepted answer
Because the bootstrap compiler goes out-of-date quickly.

Let's say your language is named Florp. You develop the Florp v0.1 compiler in a language called Glarp, which is similar enough to Florp that you can translate your code from Glarp to Florp. At this point, the language is self-hosted because it's written in itself.

In Florp v0.2 you introduce some great new features: static garbling, runtime charp information, and exception frambling. Since the compiler is now written in Florp, these new features are implemented in Florp v0.1. At this point you have two compilers you might use to compile the Florp v0.2 compiler: the original bootstrap compiler written in Glarp, and the self-hosting one written in Florp v0.1. It doesn't matter which one you use, they are functionally identical.

Then in Florp v0.3 you introduce even more exciting features: zero-cost abstrusion, discriminated intersection types, and an ownership model based on IOU notes. These new features are implemented in Florp v0.2 ─ the new features from v0.2 were very helpful for implementing v0.3! But at this point there is only one compiler you can use to build Florp v0.3, and that's the Florp v0.2 compiler that you built last week.

At this point the language is *only* self-hosted; there is no bootstrap compiler implemented in a different language that can compile Florp v0.3, because the only source code for it is written in Florp v0.2. In theory, you could translate the Florp v0.3 codebase back to Glarp, but why would you? That would take considerable effort now that Florp is quite a different language to Glarp, and even if you do, it will be out-of-date again as soon as Florp v0.4 comes out a week later.

All of that said, it is still feasible for a third-party user to build Florp v0.3 from source without having to download a binary of the compiler. You just have to download the original Florp v0.1 source code and compile it with your Glarp compiler, then download the Florp v0.2 source code and compile it with Florp v0.1, then download the Florp v0.3 source code and compile it with Florp v0.2. There's just little reason for anyone to do it, and the number of steps required increases each time a new language feature is used in the compiler's codebase.

---

> To make porting possible I would expect to either:
>
> * provide just enough maintenance of the bootstrap compiler that it can be used to assist porting to another platform (particularly if it is something ubiquitous like C)
> * provide an inefficient translator / transpiler
> * implement a cross compiler

A cross-compiler is the sensible option. It's a useful feature not just for building the compiler itself, but also so that every project written by any user of your language can be built for all supported platforms. Anyway, if you're using an existing backend like [LLVM](https://en.wikipedia.org/wiki/LLVM) then compiling to different target platforms is practically free.
> **Comments:**
> **username_8** (2023-06-26): +1 just for the features of Florp  
---
### Answer by username_4 on 2023-06-25. Score: 7
There is an alternative to bootstrapping with a mature fully-functional compiler or compiling with another language - *growing* a language.

This way you only need an external compiler, interpreter or whatever to start the tiny core of the language. The rest of the functionality can be added in the build process incrementally, eventually constructing the fully functional compiler that can be used to re-compile the underlying layers.

This approach works with languages that have sufficiently powerful metaprogramming capabilities, at least at the bootstrap stage (they can be reduced later if you don't trust your users with so much power). I experimented with using only a tiny subset of Forth, manually bootstrapped from machine code, to build a small Lisp core that was later grown into a full optimising Lisp compiler. In order to bootstrap this you don't need anything besides an implementation of that tiny Forth, yet the language itself does not have much in common with Forth.
---
### Answer by username_3 on 2023-06-25. Score: 6
# Maintenance

Maintaining two compilers and ensuring that they are both compliant is a tall order, especially for languages like Rust which are in constant evolution.

An option is to maintain a compiler that only compiles a subset of the language and then use only that subset in the final compiler, but that's still a hard task and you'd be limiting the code quality of your final compiler.
---
### Answer by username_5 on 2023-06-25. Score: 2
**Disclaimer**: This answer is completely speculation and opinion because I am not a programmer that works on any of those languages.

I think the answer is **convenience**.

Think about it: to have the kind of bootstrap process you want, as a user, the developers need to do extra work.

They need to either:

* **Accept an ever-growing bootstrap process.** This is easiest for them, since they have already done the process to get the current version of the compiler, but since most users don't run Gentoo, they know users won't accept this.
* **Maintain two separate compilers.** Would you want to do 2x the work? And yes, it's at least 2x because even if the bootstrap compiler is smaller, it's in a language that the developers are less expert in. This applies to cross compilers too, by the way.
* **Maintain a translator.** This is less work, but it has downsides. If it's in the language of the compiler, how do you bootstrap the translator? If it's not, you again have the problem that the developers are not as good with that language. Plus, such a translator would probably be different enough from a compiler that it could be *more* work than a bootstrap compiler.

Philosophically, whether or not a bootstrap process is needed depends on the situation.

Perhaps the language is *not* bootstrapped; then no bootstrap is necessary because the compiler can still be built from source.

If the language is bootstrapped, do you *really* care about the "Trusting Trust" problem? I mean, do you *really?*

Unless you need a Software Bill of Materials, or don't have a trusted distro, nor do you have a irresistible inner drive to watch your machine suffer under heavy compilation (no, I don't have a problem; why do you ask?), you can probably get away with downloading a binary, so just do it.

Even better, if someone *else* made another compiler, you can use [Diverse Double-Compiling](https://dwheeler.com/trusting-trust/) *without* a full bootstrap.

On the other hand, if a language's users need those things, they'll make it known, and if they *really* need them, they'll pay for them. Payment will make the barriers to two compilers go away, I'm sure.

Personally, I'm with you. I don't understand why people don't do it.

My language will have an officially supported C99 backend, and maybe C89. Before release, I'll use that backend to generate a C99 version and check that C code into the repo. Then the bootstrap would just be to build the C99 version, use that to build the regular version, and build again to check. Done.

On top of that, this system will always let me implement the compiler in the latest version of the language, unlike the example in one of the other answers.

But again, I have to implement and support a "translator"; I just think it's worth it because my language would then be available wherever there's a C99 compiler without needing to write specific backends *while also* taking advantage of optimization work done on C compilers.

Seems like a worthy tradeoff to me.
---
### Answer by username_6 on 2023-06-29. Score: 2
### Because you already bootstrapped yourself from the chicken-egg paradox

> If you want to port to a new platform you are forced to either bootstrap again or implement a cross compiler.

On the new platform, you will need:

1. A source front-end for your language;
2. A binary back-end.

Assuming a native compiled language, (2) is inevitable, and you already have (1), so there is no need to bootstrap (1) on the new machine: you will write all pieces of a cross-compiler anyway.

On a language that produces bytecode, (2) is a bigger piece of code that you already have in a portable language, or the bytecode can be "desugared enough", so a initial cross compiler is easy to code, that in turn *already runs your complete language,* while you recode or adapt the VM in parallel.

After the initial automatic "simple-and-slow" back-end is substituted by a better back end, it is abandoned.
---
