# Fluent: Algorithmic Chaining Library for Slice Manipulation

**URL:** <https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978>\
**Category:** Showcase\
**Created:** [April 16, 2024, 4:04pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978 "2024-04-16T16:04:54Z")\
**Posts on this page:** 12\
**Page:** 2

<div class="post-metadata">

**Author:** ![ram535](https://ziggit.dev/user_avatar/ziggit.dev/ram535/32/1885_2.png) [@ram535](https://ziggit.dev/u/ram535)\
**Post date:** [April 22, 2024, 1:24pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/22 "2024-04-22T13:24:14Z")

</div>

@AndrewCodeDev what are your thoughts on this cpp library [GitHub - tcbrindle/flux: A C++20 library for sequence-orientated programming](https://github.com/tcbrindle/flux).

> About Flux provides a broadly equivalent feature set to C++20 Ranges, but uses a slightly different iteration model based around _cursors_ rather than _iterators_ . Flux cursors are a generalisation of array _indices_ , whereas STL iterators are a generalisation of array _pointers_ .

Here is talk about it [https://www.youtube.com/watch?v=nDyjCMnTu7o](https://www.youtube.com/watch?v=nDyjCMnTu7o)

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [April 22, 2024, 1:45pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/23 "2024-04-22T13:45:00Z")

</div>

Ah, I remember std::tuple… good ol’ std::tuple…

From back here, it looks like a fairly modern C++ code base. They’re implementing some sensible defaults - max returns optional instead of throwing. They’re also taking an interesting stance by being index based instead of iterator based.

What you’d like me to specifically comment on? I’ve never been a fan of the C++ build system but that’s not really the fault of the library authors. Looks like they’re getting good AVX instructions generated as well. Looks like a fairly solid library.

---

<div class="post-metadata">

**Author:** ![ram535](https://ziggit.dev/user_avatar/ziggit.dev/ram535/32/1885_2.png) [@ram535](https://ziggit.dev/u/ram535)\
**Post date:** [April 22, 2024, 2:05pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/24 "2024-04-22T14:05:01Z")

</div>

I was wondering of your thoughts on that part. Is it any relevant ideas that could be applied on your library?

> [@AndrewCodeDev](#):
>
> They’re also taking an interesting stance by being index based instead of iterator based.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [April 22, 2024, 2:22pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/25 "2024-04-22T14:22:36Z")

</div>

Well, first, thanks for the question. I’ve gone back and fourth on the benefits of both ideas and I have a few thoughts I can share here.

First, Zig and C++ are entirely different animals. I write C++ professionally in my day job and the transition to Zig was… well… interesting. If I was writing this in C++, I’d be more tempted to go down that road for a variety of reasons.

An extremely important thing to consider here is the presence of two major components to the C++ ecosystem - destructors and hidden allocations. These definitely influence the mental model around lifetimes and stability.

I’m not a fan of destructors. IMO, it’s like someone took a garbage collector and split it into a thousand little autonomous pieces, lol. I don’t like to complain, but they just aren’t my style.

And `operator new` creates a lot of issues surrounding the stability of pointers. In Zig, it’s _hard to ignore the fact that you’re allocating_. Also, lifetimes are thought about more in terms of allocators and general memory management strategies more so than “when does this vector self-destruct?” I find that gives me much more confidence because I’m thinking about the lifetime of my memory, not my objects.

That said, I’m not really stubborn about things here. I just changed the iterator backend to user pointers instead of `index/slice` combinations because I was able to save a usize and remove a bunch of math ops in the process - I feel like the program is actually much safer now because reasoning about how they move is much simpler. One thing I’ll say about Zig is that we have a heavy reliance on unsigned integers and that can create some pretty odd patterns for indexing if you’re trying to approach zero (especially with variable strides) and I wanted to resolve that in a different way.

So I’m not against indices, but I don’t see a point at this juncture to switch entirely to their model until I see some really hard evidence. I’m not convinced that if something makes sense in C++ then we should do it too. It’s also worth mentioning that a good chunk of our library uses indices instead of iterators already.

Still, I’m open to the idea and my mind can always be changed with evidence.

---

<div class="post-metadata">

**Author:** ![jaime](https://ziggit.dev/user_avatar/ziggit.dev/jaime/32/1842_2.png) [@jaime](https://ziggit.dev/u/jaime)\
**Post date:** [April 22, 2024, 3:14pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/26 "2024-04-22T15:14:44Z")

</div>

Oh thanks @pierrelgol and @AndrewCodeDev for this piece of work. So many interesting stuff to dive in since I started learning Zig…looking great!

---

<div class="post-metadata">

**Author:** ![pierrelgol](https://ziggit.dev/user_avatar/ziggit.dev/pierrelgol/32/10233_2.png) [@pierrelgol](https://ziggit.dev/u/pierrelgol)\
**Post date:** [April 22, 2024, 8:34pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/27 "2024-04-22T20:34:57Z")

</div>

Thanks for the kind words, It’s been very interesting for me too, as I’m very new to programming as a whole, having the chance to work with @AndrewCodeDev what a true blessing, especially because he was able to explain a lot of the comptime stuff that was still a bit fragile for me. If you are new to Zig, I think that Fluent would be a very interesting read, simply for the fact that it uses comptime in very useful ways and honestly it shows a good variety of where and how to use comptime, which to be honest is one of the best part of Zig as a whole.

---

<div class="post-metadata">

**Author:** ![jaime](https://ziggit.dev/user_avatar/ziggit.dev/jaime/32/1842_2.png) [@jaime](https://ziggit.dev/u/jaime)\
**Post date:** [April 22, 2024, 8:48pm UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/28 "2024-04-22T20:48:06Z")

</div>

Actually I started with the comptime topic last week. I’ll take your advice and check Fluent also as part of my comptime learning chapter :). Comptime seems to be one of the star features in Zig, so it will be good to see it under different contexts. Thanks for your work!

---

<div class="post-metadata">

**Author:** ![korke](https://ziggit.dev/user_avatar/ziggit.dev/korke/32/1547_2.png) [@korke](https://ziggit.dev/u/korke)\
**Post date:** [September 6, 2024, 3:13am UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/29 "2024-09-06T03:13:10Z")

</div>

Umm how do I only iterate over the captured gourps? say my pattern is `foo-(\\d+)(\\.so|\\.a).*` (\ escaped) for this `libfoo-18.so.18.1` i would only like to iterate over `18` and `.so`

also could we use it in build.zig, since it’s a standalone single file project as far i know you can expose it for build scripts by exposing using `pub usingnamespace @import("fluent.zig")` in the package’s `build.zig`.

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [September 6, 2024, 3:30am UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/30 "2024-09-06T03:30:50Z")

</div>

Using `Fluent.match`, an expression is: `\\d{2}|\\.so`

source: `ibfoo-18.so.18.1`

`18`  
`.so`  
`18`

You can test your strings here (make sure you select the pcre in the upper right hand corner): [https://regexr.com/](https://regexr.com/)

On that website, they only require one escape (zig doesn’t have a concept like “raw strings” so it’s just `\d{2}|\.so`.

---

<div class="post-metadata">

**Author:** ![korke](https://ziggit.dev/user_avatar/ziggit.dev/korke/32/1547_2.png) [@korke](https://ziggit.dev/u/korke)\
**Post date:** [September 6, 2024, 3:53am UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/31 "2024-09-06T03:53:09Z")

</div>

Kind of confused was using [https://regex101.com/](https://regex101.com/) (selected PCRE not PCRE2 from the left side) where `foo-(\d+)(\.so|\.a).*` pattern showed result like this:  
 ![image](https://ziggit.dev/uploads/default/original/2X/1/1133633d5ec29c3d5b9e1e42293fbab58a504751.png)  
thought it’s same for fluent but it’s different like [https://regexr.com/](https://regexr.com/), so regex also don’t have  
“stable abi” like c++? xD guess I don’t know much bout regex after all…

---

<div class="post-metadata">

**Author:** ![korke](https://ziggit.dev/user_avatar/ziggit.dev/korke/32/1547_2.png) [@korke](https://ziggit.dev/u/korke)\
**Post date:** [September 6, 2024, 5:04am UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/32 "2024-09-06T05:04:23Z")

</div>

this pattern `(\d+)|(\.so|\.a|\.dylib|\.tbd)` seems to match `la` for some reason, using branch `zig-0.14-version`  
zig usage:

```zig
    var matches = fluent.match("(\\d+)|(\\.so|\\.a|\\.dylib|\\.tbd)", "foolaso-18.so.18.0");
    while (matches.next()) |match| {
        std.log.info("match {s}", .{match});
    }

```

```zig
info: match la

info: match 18

info: match .so

info: match 18

info: match 0

```

[https://regexr.com/](https://regexr.com/) shows these matches  
 ![image](https://ziggit.dev/uploads/default/original/2X/0/01ab869051555bdf328fb0819e48d3665c09f675.png)

---

<div class="post-metadata">

**Author:** ![AndrewCodeDev](https://ziggit.dev/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@AndrewCodeDev](https://ziggit.dev/u/AndrewCodeDev)\
**Post date:** [September 6, 2024, 6:51am UTC](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978/33 "2024-09-06T06:51:38Z")

</div>

> [@korke](#):
>
> ` var matches = fluent.match("(\\d+)|(\\.so|\\.a|\\.dylib|\\.tbd)", "foolaso-18.so.18.0");`

Thanks for the bug report - I just pushed a change to fix it (it looks like I was missing one check for an escape after I refactored out some of the redundant regex cells).

[Previous page](https://ziggit.dev/t/fluent-algorithmic-chaining-library-for-slice-manipulation/3978.md?page=1)
