HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
arximboldi
immer
C++2016–2026
arximboldi / immer

immer

Postmodern immutable and persistent data structures for C++ — value semantics at scale

21Distinct people
34Mentions
3Explicit recommenders
2.9KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Postmodern immutable and persistent data structures for C++ — value semantics at scale

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

My hobby language[1] also has no reference semantics, very similar to Herd. I think this is a really interesting point in the design space. A lot of complexity goes away when…

electroly used a recommendation phrase. 3 indexed comments match. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:03:16 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year34 dated mentions

Observed mentions: 2016-11-27 16:12:55 UTC to 2026-02-15 06:31:32 UTC.

02462016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC110
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC707
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC101
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC312
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC505
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC303
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC413
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC615
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC101
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC110
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC202

What Hacker News says

34 sources
electroly·Jan 26, 2026Recommendation phrase
My hobby language[1] also has no reference semantics, very similar to Herd. I think this is a really interesting point in the design space. A lot of complexity goes away when it's only values, and there are real languages like classic APL that work this way. But there are some serious downsides. In practice I have found that it's very painful to thread state through your program. I ended up offering global variables, which provide something similar to but worse than generalized reference semantics. My language aims for simplicity so I think this may still be a good tradeoff, but it's tricky to imagine this working well in a larger user codebase. I like that having only value semantics allows us, internally, to use reference counted immutable objects to cut down on copying; we both pass-by-reference internally and present it as pass-by-val
Read the rest
ue to the programmer. No cycle detection needed because it's not possible to construct cycles. I use an immutable data structures library[2] so that modifications are reasonably efficient. I recommend trying that in Herd; it's almost always better than copy-on-write. Think about the Big-O of modifying a single element in an array, or building up a list by repeatedly appending to it. With pure COW it's hard to have a large array at all--it takes too long to do anything with it! For the programmer, missing reference semantics can be a negative. Sometimes people want circular linked lists, or to implement custom data structures. It's tough to build new data structures in a language without reference semantics. For the most part, the programmer has to simulate them with arrays. This works for APL because it's an array language, but my BASIC has less of an excuse. I was able to avoid nearly all reference counting overhead by being single threaded only. My reference counts aren't atomic so I don't pay anything but the inc/dec. For a simple language like TMBASIC this was sensible, but in a language with multithreading that has to pay for atomic refcounts, it's a tough performance pill to swallow. You may want to consider a tracing GC for Herd. [1] https://tmbasic.com [2] https://github.com/arximboldi/immer
In Show HN: A small programming language where everything is pass-by-value
I've been working on an editor (not text) in C++ and pretty early got into undo/redo. I went down the route of doIt/undoIt for commands but that quickly got old. There was both the extra work needed to implement undo separately for every operation, but also the nagging feeling that the undo operation for some operation wasn't implemented correctly. In the end, I switched to representing the entire document state using persistent data structures (using the immer library). This vastly simplified things and implementing undo/redo becomes absolutely trivial when using persistent data structures. It's probably not something that is suitable for all domains, but worth checking out. https://github.com/arximboldi/immer
In Text Editor Data Structures: Rethinking Undo
How does this compare to https://github.com/arximboldi/immer (other than the C/C++ difference)? Also, it's my understanding that, in practice, persistent data structures require a garbage collector in order to handle deallocation when used in a general-purpose way. How does your implementation handle that? Also, have you seen https://github.com/cnuernber/ham-fisted ? I think there are a few other Java-based persistent collections as well in the overall Clojure ecosystem that also improve on Hickey's original implementation, but I can't recall them now…
In Show HN: A hash array-mapped trie implementation in C
You might be interested in ewig and immer by Juan Pedro Bolivar Puente: https://github.com/arximboldi/ewig https://github.com/arximboldi/immer See the author instantly opening a ~1GB text file with async loading, paging through, copying/pasting, and undoing/redoing in their prototype “ewig” text editor about 27 minutes into their talk here: https://m.youtube.com/watch?v=sPhpelUfu8Q It’s backed by a “vector of vectors” data structure called a relaxed radix balanced tree: https://infoscience.epfl.ch/record/169879/files/RMTrees.pdf That original paper has seen lots of attention and attempts at performance improvements, such as: https://hypirion.com/musings/thesis https://github.com/hyPiRion/c-rrb
In Text Editor Data Structures
I like working in C++, after a decade of working in Java, Python, Javascript and Clojure, I find working in C++ (which I learned before these other languages) to be quite fun and pleasant, at least with relatively modern C++. I've been, on and off, working on a little toy game engine, for a few years. Its a mix of keeping up with C++ advancements, learning various concepts like physically based rendering, and just the fun of crafting a big project, with no constraints other than my time and ability, no deadlines, no expectation of releasing anything. Its cathartic and enjoyable. I really do enjoy it. Last September, I got frustrated with something I was working on in a more serious capacity. It was some server software, it responded to HTTP requests, it accessed third party services over HTTP and Websockets, it talked to a Postgres databa
Read the rest
se. Overall it was an event driven system that transformed data and generated actions that would be applied by talking to third party services. The "real" version was written in Clojure and it worked pretty well. I really like Clojure, so all good. But because I was frustrated with some things about how it ran and the resources it took up, I wondered what it would be like if I developed a little lean-and-mean version in C++. So I gave it a try as a side project for a few weeks. I used doctest[1] for testing, immer[2] for Clojure-like immutable data structures, [3] lager for Elm-like application state and logic management, Crow[4] for my HTTP server, ASIO[5] and websocketpp[6] for Websockets, cpp-httplib[7] as a HTTP client and PGFE[8] for Postgres, amongst some other little utility libraries. I also wrote it in a Literate Programming style using Entangled[9], which helped me keep everything well documented and explained. For the most part, it worked pretty well. Using immer and lager helped keep the logic safe and to the point. The application started and ran very quickly and used very little cpu or memory. However, as the complexity grew, especially when using template heavy libraries like lager, or dealing with complex things like ASIO, it became very frustrating to deal with errors. Template errors even on clang became incomprehensible and segmentation faults when something wasn't quite right became pretty hard to diagnose. I had neither of these problems working on my game engine, but both became issues on this experiment. After a few weeks, I gave up on it. I do think I could have made it work and definitely could go back and simplify some of the decisions I made to make it more manageable, but ultimately, it was more work than I had free time to dedicate to it. So my experience was that, yes, you can write high level application logic for HTTP web backends in C++. You can even use tools like immer or lager to make it feel very functional-programming in style and make the application logic really clean. Its not hard to make it run efficiently both in terms of running time and memory usage, certainly when comparing to Clojure or Python. However, I found that over all, it just wasn't as easy or productive as either of those languages and I spent more time fighting the language deficiencies, even with modern C++, than I do when using Clojure or Python. I think I would think very long and hard before seriously considering writing a web backend in C++. If I had the time, I'd love to retry the experiment but using Rust, to see how it compares. [1] https://github.com/doctest/doctest [2] https://github.com/arximboldi/immer [3] https://github.com/arximboldi/lager [4] https://github.com/CrowCpp/crow [5] https://think-async.com/Asio/ [6] https://www.zaphoyd.com/projects/websocketpp/ [7] https://github.com/yhirose/cpp-httplib [8] https://github.com/dmitigr/pgfe [9] https://entangled.github.io/
In The Lisp Curse (2017)
Hah, that's really nice! I've been working on an editor for setting up Box2D scenes for the last month or so. I know there are a bunch of them out there already, but it seemed like a fun project. No Tcl/Tk for me though. I'm writing it as a web app, but in C++ with wasm/webgl and using NanoVG[1] for drawing. I saw a comment here about undo/redo and I think it's a must have feature for something like this. I implemented something based on the command pattern first, but ended up disliking the amount of code needed just for undo. I eventually tore all that out and built my state model on the excellent immer[2] library. [1] https://github.com/inniyah/nanovg [2] https://github.com/arximboldi/immer
In Tcl/Tk Spline Editor
Cing through this, I can tell you that you can C C++: https://godbolt.org/z/sWETvsoKd (a demo for polymorphism in C90) Not only can you do OOP in C, you can also do FP, implement your own iterators and the like. (Function) pointers are your friend: https://news.ycombinator.com/item?id=28378627#28406874 And remember: FP = pure functions (no side effects) + immutable values Currying in C is essentially taking the address of a function pointer and not calling it. You can do lazy evaluation as well. The Cky is the limit! Yes, C++ is comfy, but you cannot really do FP with its STL. As STL containers require mutability by default. std::transform(v.begin(), v.end(), w.begin(), [](auto const& x){ /* ... */}); Transforming the contents of v requires a buffer(!) w. (The rescue: https://github.com/arximboldi/immer) In Python, this would be something
Read the rest
akin to: map(lambda x: x, t); # t being a tuple type here This will return another tuple. Yeah, so these are just some pointers. I just wanted to stress that C can enable your creativity once you get the essence of it.
In Ask HN: What language to learn after Python?

Showing the 15 most recent of 34 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.