Qqwy

Qqwy

TypeCheck Core Team

Cyclical data structures in Elixir?

Certain kinds of algorithms can be sped up (or even: are only possible) by using cyclic data structures.
Functional languages make it hard to specify cyclic data structures (such as for instance doubly-linked lists) because of their immutability.

Nevertheless, in e.g. Haskell it is possible to create cyclic data structures using a process that is known as ‘tying the knot’. This seems to only be possible because Haskell is by definition/default lazy, however.

I am wondering if it is possible (maybe with some clever (non-hygienic) macro metaprogramming?) to create a cyclic data structure in Elixir, such as a list x where one of the elements contains this list.

Are there ways to do this?

Marked As Solved

rvirding

rvirding

Creator of Erlang

There is no way to create real cyclic data structures when you only have immutable data as cyclic structures require mutability. You can only simulate them in some way.

Also Liked

sasajuric

sasajuric

Author of Elixir In Action

Zippers can be used to implement a two-way navigational list. The example in the article doesn’t support cycle, but it should be very easy to extend it by adding a clause which matches on the empty list in the second element.

The idea is to keep a tuple in the shape of {visited::[any], remaining::[any]}. So for example, in a tuple {[3, 2, 1], [4, 5, 6]} you’re currently at the element 4, while previously visited 1, 2, 3 (in that order). The next operation will move 4 to the top of the first list, so you’ll get {[4, 3, 2, 1], [5, 6]}. If after the move the second list is empty, then you just reverse the first list, and return {[], reversed_first_list}. So next({[5, 4, 3, 2, 1}, [6]) will return {[], [1, 2, 3, 4, 5, 6]}, and you’re back at the start.

You can take the similar approach to move in the opposite direction. The prev operation pops the head off the first list and pushes it at the top of the second list, unless the first list is empty, in which case you need to keep the last element of the second list, reversing all others into the first list.

Supporting insert and delete is as easy as pushing/popping to/from the top of the second list.

14
Post #3
michalmuskala

michalmuskala

Another very interesting structure are the Finger Trees, that allow for efficient implementations of deques (double ended queues), priority queues or lists with O(1) size information - http://www.staff.city.ac.uk/~ross/papers/FingerTree.html There are couple implementations in erlang in the wild.

It could be interesting to see some Elixir based implementations with all the protocols.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Also worth noting that this is very similar to the implementation of a queue in functional programming. For more information on the underpinnings of such structures I highly recommend: https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf

talentdeficit

talentdeficit

Rebar3 Core Team

i believe tying the knot is possible in haskell because lazy evaluation gives you a form of memoization for free. without that you have to memoize your cyclic data structures ‘by hand’. you can look at the erlang module digraph for an example that uses ets tables to model a graph with possible cycles via immutable data structures

however, using memoization to convert self referential data structures doesn’t let you use the algorithms that rely on self referential data structures on them. at best you can write code that looks like the imperative/cyclical algorithm but the performance is going to be - at best - the same as the pure functional algorithm. all you are really doing is rewriting one algorithm to look more like another. even haskell has to pay this performance penalty when working with self referential data structures

Where Next?

Popular in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement