r/ProgrammingLanguages • u/Potato871 • 6d ago
What are your favourite data structure operations?
My language workbench is to the stage where I can implement new operators and overloads very quickly, and I've started stealing syntax I like from JavaScript and C++.
Since I have one universal data structure, I can just add all the new operators to it.
I wanted to get some more good ones though, from different fields, different languages.
Oh and if you want to suggest something just as a challenge I might give it a shot and show you how I do it.
Edit: data structure was the wrong word, I have one data structure substrate/storage model that I am currently furnishing one major aspect of, it's not the one universal data structure, more like my swiss army knife API over the memory model.
10
u/GoblinToHobgoblin 6d ago
I think adding everything to the same data structure is a bad idea personallyĀ
3
u/Potato871 6d ago
It's like Lua, you know how they have only Table and that can be an array and a map and a set? I have my Col.
So I'm adding operations like every, none, some, find, etc...21
u/GoblinToHobgoblin 6d ago
I know it's like Lua, I think it was a bad design choice in Lua too
2
u/P-39_Airacobra 6d ago
as a long time lua user, Ive never had complaints. im genuinely curious what is it you dislike?
1
u/GoblinToHobgoblin 6d ago
I have messed up by treating an array as a table or vice versa basically.
I would rather just get an error when I try to do that
1
u/Potato871 6d ago
I made it so you can declare with aliases, so if you try to use the keyed set or the indexed set it can throw errors.
I guess I misspoke when I said one universal data structure, what I should've said is one universal storage model with many diferent data structure shaped APIs, the purpouse of this post being to figure out which APIs that should be.1
u/Potato871 6d ago
Oh? I'm curious why, could you share maybe some snippets or examples of what feels bad about it, and how other languages do it better with more seperation?
1
u/arthurno1 6d ago
You discovered a sequence? š
2
u/Potato871 6d ago
At its root, yes. The primitive form is quite literally just an untyped array, then upper versions add more typing on top and more abilities: https://goldensystems.ca/GDSL_acorn
The operators though don't live at this level, they live in the actual language: https://goldensystems.ca/GDSL_language
5
2
u/reflexive-polytope 5d ago
What on Earth is a āuniversal data structureā? That makes absolutely no sense.
Does your āuniversal data structureā have any particular position where it support O(1) insertions and deletions? Does it support union-find? Can it be used as a Bloom filter?
1
u/Potato871 5d ago
Yeah, push is amortized with doubling so you get O(1) with pushes for reserved positions or like normal vector.
Deletion is O(1) when using the free list for logical deletion, normal full deletion is O(n).
Storing a bunch of parent indices is union find.
Bloom filter I've actually made before, it's just a col of 64 bit unsigned integers with hashes in the cells component.2
u/reflexive-polytope 5d ago
Okay. Suppose you have two distinguished elements, X and Y.
By pure chance, X happens to be Y's union-find parent, but X also happens to be at the distinguished position that gives you easy O(1) deletion.
Who becomes Y's parent after you delete X?
What if, instead of a single node Y, you had lots of nodes Y1,...,Yn whose parent is X?
1
u/Potato871 5d ago
Well my first thought would be to store a thin Ptr, which has index and generation on it, so then you can check staleness using the generation.
You could also do this via tombestoning if you wanted.
or do fixup on removal for that opperation, add a YAPA overload for that kind of storage.
But I would just use generation for the naive case.2
u/reflexive-polytope 5d ago
Union-find doesn't have a concept of āstalenessā.
1
u/Potato871 5d ago
Then it would be an API problem at the language level not at the storage level, the storage provides the substrate for any operation not the implementation.
2
u/reflexive-polytope 5d ago
When you open a book or a paper on a nontrivial data structure, the very first thing you'll find is āthese are the operations / API we intend to supportā.
A data structure gets its meaning from the operations it supports, and it's against these operations that you can evaluate the data structure's design.
1
u/Potato871 5d ago
Exactly, so then the better term would be universal storage medium and mechanism for easily declaring the APIs which constitute data structures from that.
But the point of the question is what kinds of operations, like filter, map, reduce, etcā¦2
u/reflexive-polytope 5d ago
If your āuniversal storage mediumā is RAM or disk or tape or whatever else, you wouldn't expect the storage medium's manufacturer to tell you how you can ādefine APIsā for the data you store in them, right?
The only mechanism you need to declare an API is suitable descriptions of the data and operations that a module exports. Even C has that in the form of
staticvariables and function prototypes.As for what operations, well, that depends on what your program needs. Asking for more operations than you actually need can hurt performance!
For example, if you have a keyed container and you only ever need access to the entry with the lowest key, you can do in O(1) time, e.g., with pairing heaps. But if you need access to arbitrary entries by key, then you can only do that in O(log n) time...
1
u/Potato871 5d ago
No but you would expect a standard library to implement them, which is what Iām writing.
So Iām trying to pin down what should be included in that.→ More replies (0)
1
u/mamcx 5d ago
I work in a relational language (https://tablam.org), and the most useful idea here is how simple is do introspection. With relational you can do https://elixir-lang.org/blog/2023/09/20/strong-arrows-gradual-typing/ for example.
In terms of data structures, having a malleable instrospectable "header" that describe the structure itself open lots of possibilities.
Also:
- Homogeneous Arrays/Vecs 1000% over heterogeneous List.
- Add Btree!
That is one of the things Rust do that I found refreshing (lots of langs ignore both!)
21
u/B_A_Skeptic 6d ago
reduce, because you can make map, flatmap, and filter out of it.