# Plans to bring FBIP/FP2 in Haskell?

**URL:** <https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859>\
**Category:** Learn\
**Created:** [August 29, 2025, 4:27am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859 "2025-08-29T04:27:43Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Agnishom](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/agnishom/32/2108_2.png) [@Agnishom](https://discourse.haskell.org/u/Agnishom)\
**Post date:** [August 29, 2025, 4:27am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/1 "2025-08-29T04:27:43Z")

</div>

It seems that in the recent years, there have been advancements towards the in-place implementations for functional programs, as seen in Lean 4 and [Roc](https://www.roc-lang.org/fast) and [Koka](https://koka-lang.github.io/koka/doc/book.html#sec-fbip), and several academic papers.

Are there any plans to implement such strategies in Haskell (i.e, GHC)? I did a quick Google search but couldn’t find any discussion.

* * *

- Lorenzen, Anton, Daan Leijen, and Wouter Swierstra. “FP²: Fully in-Place Functional Programming.” ICFP (2023)
- Ullrich, Sebastian, and Leonardo de Moura. “Counting immutable beans: Reference counting optimized for purely functional programming.”
- Reinking, Alex, et al. “Perceus: Garbage free reference counting with reuse.” PLDI (2021)

---

<div class="post-metadata">

**Author:** ![sgraf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sgraf/32/392_2.png) [@sgraf](https://discourse.haskell.org/u/sgraf)\
**Post date:** [August 29, 2025, 9:47am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/2 "2025-08-29T09:47:22Z")

</div>

Dynamic reuse relies on reference counting as garbage collection strategy. Thunks and mutable data structures introduce cycles in the heap, so you cannot use reference counting (exclusively) to collect such a heap. Therefore I don’t see how to apply these techniques to GHC Haskell.

On the other hand, transient data structures offer the same promise of in-place update. It’s just that GHC’s support for mutable data structures (e.g. record fields) is lacking, so there is an inherent overhead to transients.

I mentored a bachelor’s thesis that used a transient implementation for GHC’s InScopeSet: [https://pp.ipd.kit.edu/uploads/publikationen/ellinger22bachelorarbeit.pdf](https://pp.ipd.kit.edu/uploads/publikationen/ellinger22bachelorarbeit.pdf)

The results on p31 were mixed, but I think they’d be a win overall if more code was actually written in a way that exploited mutability more (which would’ve required large refactorings).

---

<div class="post-metadata">

**Author:** ![TeofilC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/teofilc/32/3987_2.png) [@TeofilC](https://discourse.haskell.org/u/TeofilC)\
**Post date:** [August 29, 2025, 11:15am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/3 "2025-08-29T11:15:35Z")

</div>

Another thing that would be worth exploring is to implement something like this through staged fusion (ie, (typed) Template Haskell). Like [GitHub - AndrasKovacs/staged-fusion: Staged push/pull fusion with typed Template Haskell](https://github.com/AndrasKovacs/staged-fusion) or [GitHub - phadej/staged: Staged Streams and other stuff](https://github.com/phadej/staged)

---

<div class="post-metadata">

**Author:** ![TerrorJack](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/terrorjack/32/5155_2.png) [@TerrorJack](https://discourse.haskell.org/u/TerrorJack)\
**Post date:** [August 29, 2025, 9:54pm UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/4 "2025-08-29T21:54:38Z")

</div>

in order to build and modify heap closures in place, you can exploit the compact region feature. this is deeply cursed territory and has many footguns, but my colleague @tbagrel1 did some explorations on this front and he might be motivated to provide a bit of his experience here 🙂

---

<div class="post-metadata">

**Author:** ![tbagrel1](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tbagrel1/32/4610_2.png) [@tbagrel1](https://discourse.haskell.org/u/tbagrel1)\
**Post date:** [September 1, 2025, 9:22am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/5 "2025-09-01T09:22:28Z")

</div>

Thanks @TerrorJack for mentionning me.

I indeed used Compact Regions as a way to obtain immovable memory area in which the GC won’t go looking. That way, I could do controlled mutations without fear of letting the RTS read uninitialized pointers etc. The end goal was to enable destination-passing style programming in Haskell, but I guess that the same tricks could be used to implement FiP programming too.

Here’s the major part of my work:

- [HIW 24 - A zero-copy interface to compact regions powered by destinations](https://www.youtube.com/watch?v=UIw0s-yEkfw) (video, 24min)
- [`linear-base` PR #450 - Write data to compact regions through destination “filling”](https://github.com/tweag/linear-base/pull/450) (contains the library code do to controlled mutations in a DPS way inside compact regions)
- [`ghc-proposals` PR #683 - Primitives for zero-copy compact regions](https://github.com/tweag/ghc-proposals/blob/tbagrel1/dps-compact-regions-prims/proposals/0683-zero-copy-compact.md) (lists and discusses the required changes in GHC to support DPS structure building, especially the slight additions to the compact region API)
- [Destination-passing style programming: a Haskell implementation](https://inria.hal.science/hal-04406360/) (research paper)
- [Destination Calculus: A Linear 𝜆-Calculus for Purely Functional Memory Writes](https://dl.acm.org/doi/10.1145/3720423) (research paper, more theoretical, less relevant to this thread)
- [Formalization and Implementation of Safe Destination Passing in Pure Functional Programming Settings](https://github.com/tweag/tbagrel-phd-manuscript/blob/master/submitted_pdfs/tbagrel_phd_manuscript_submitted_202506130100_fixed.pdf) (PhD manuscript, ties theory and practical aspects together, with extra details compared to the individual articles)

AFAIK, doing the same kind of mutations in the garbage-collected heap would require a very precise understanding of garbage collection/RTS in GHC, and alas, I don’t have it. I’m also afraid it would be even more brittle than what I propose in my work, as any modification of the GC implem afterwards would require to review and adapt the mutation system again.

Personnally, I used compact regions almost solely to avoid the GC. But maybe there are alternate memory allocation systems that could be even better for that purpose.

---

<div class="post-metadata">

**Author:** ![mzabani](https://avatars.discourse-cdn.com/v4/letter/m/c68b51/32.png) [@mzabani](https://discourse.haskell.org/u/mzabani)\
**Post date:** [September 2, 2025, 7:53pm UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/6 "2025-09-02T19:53:34Z")

</div>

I don’t know the GHC compiler or runtime well at all, but would it not be possible for compile time reuse analysis to produce code that replaces values in single-use constructors of same size?

For example, could a function `f :: Int → Int` be compiled to not allocate a new `I#` and instead replace the value in the supplied `I#` with the result, as long as the caller is the producer of that input and only uses it when passing it to `f`?

Of course, the compiler might have to produce two versions of `f`, one of them for cases where this cannot be applied.

---

<div class="post-metadata">

**Author:** ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)\
**Post date:** [September 3, 2025, 3:25am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/7 "2025-09-03T03:25:25Z")

</div>

So I don’t like making promises on something that isn’t public yet, but this is what I have been doing for the last 2 years during my free time. I have been building a new Haskell compiler entirely from scratch and I plan to use FBIP. I plan on releasing it and make a proper announcement when I get to the MVP (if I get there tbh).

```haskell
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Haskell 177 1302 364 10998
-------------------------------------------------------------------------------
SUM: 177 1302 364 10998
-------------------------------------------------------------------------------

```

---

<div class="post-metadata">

**Author:** ![sgraf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sgraf/32/392_2.png) [@sgraf](https://discourse.haskell.org/u/sgraf)\
**Post date:** [September 8, 2025, 9:08am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/8 "2025-09-08T09:08:20Z")

</div>

In order to allow reuse of a heap object, you need to know whether the object is dead at the point where you want to reuse it. So we are talking about a static analysis that estimates the lifetime of heap objects. (How reuse is implemented is a different matter, but as you note it is doable.)

I don’t have much experience with such analyses and am having doubts about its precision (i.e., that it justifies much reuse in the end). But one thesis I mentored on this topic is an escape analysis. That is, an analysis that infers whether some heap object does not live longer than its allocating function and hence can be allocated on the stack: [https://pp.ipd.kit.edu/uploads/publikationen/scheper22masterarbeit.pdf](https://pp.ipd.kit.edu/uploads/publikationen/scheper22masterarbeit.pdf)  
The results here need to be taken with a grain of salt: Although the portion of heap objects that can be allocated on the stack is _huge_, certainly some of the ensuing stack allocation is not _safe for space_, that is, the stack allocated objects will occupy stack space longer than they are actually alive, which may lead to an asymptotic increase in total memory usage.

However, maybe an escape analysis like this could be useful to estimate whether reuse of some heap object is possible. I’d also hope that there are more advanced attempts to reuse analysis. However, a static reuse analysis will yield far smaller benefits than a dynamic one based on reference counting.

---

<div class="post-metadata">

**Author:** ![sgraf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sgraf/32/392_2.png) [@sgraf](https://discourse.haskell.org/u/sgraf)\
**Post date:** [September 8, 2025, 9:18am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/9 "2025-09-08T09:18:03Z")

</div>

This is cool 🙂 Presumably, your implementation will not memoise thunks, at the very least for recursive thunks? Or at least I can hardly imagine that

```hs
ones = 1 : ones

```

will be represented as a “loopy list” at runtime, that is, a circular data structure.

Indeed for the non-recursive thunk case, FBIP seems possible (as long as recursive thunks are ruled out).

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [September 8, 2025, 9:29am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/10 "2025-09-08T09:29:07Z")

</div>

> [@sgraf](#):
>
> static analysis that estimates the lifetime of heap objects

I also know of this thesis, but I wasn’t involved:

> **[Higher Ranked Region Bound Inference For Region Based Memory Management In...](https://studenttheses.uu.nl/handle/20.500.12932/41246)**

---

<div class="post-metadata">

**Author:** ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)\
**Post date:** [September 8, 2025, 3:18pm UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/11 "2025-09-08T15:18:19Z")

</div>

Correct.

Though it’s okay to have global recursive thunks because they don’t have a reference count. Right now my plan is to use lambda lifting to rewrite all recursive let bindings into global let bindings.

---

<div class="post-metadata">

**Author:** ![sgraf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sgraf/32/392_2.png) [@sgraf](https://discourse.haskell.org/u/sgraf)\
**Post date:** [September 9, 2025, 10:34am UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/12 "2025-09-09T10:34:37Z")

</div>

How do you track the lifetime of global thunks if they don’t have a reference count? GHC calls these “constant applicative form” and is careful to release them once they are dead. IIRC it’s kind of a big deal (though I wasn’t around when this hadn’t been implemented yet).

---

<div class="post-metadata">

**Author:** ![superstar64](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/superstar64/32/5308_2.png) [@superstar64](https://discourse.haskell.org/u/superstar64)\
**Post date:** [September 9, 2025, 8:57pm UTC](https://discourse.haskell.org/t/plans-to-bring-fbip-fp2-in-haskell/12859/13 "2025-09-09T20:57:28Z")

</div>

You don’t. They’re global variables, they’re supposed to leak. I don’t want to have a runtime that needs to know what `main` is doing or what threads are currently running. Being able to write shared library that you can use from C is one of my goals.

I’m fully aware that will break the big O characteristics of certain Haskell programs but I’m okay with that. Haskell 2010 is dead anyway, so almost all packages will need to be ported to avoid GHC features I don’t implement either way.
