crisefd

crisefd

I’m following along this online course and one of the topics they touched on was time and space complexity. They solve leetcode problems in a iterative and recursive way using Python and then calculate the complexities of the implementation.
They explained that when you code in a recursive way, it’s usually more space consuming given that when you use recursion, every function call gets added to the call stack. But by reading the book Learn Functional Programming with Elixir, in the chapter on recursion, it says this about Tail-Call Optimization:

Tail-call optimization is when the compiler reduces functions in memory without allocating more memory. It’s a common compiler feature in functional programming languages. To use it, we need to ensure that the last expression of our function is a function call. If the last expression is a new function call, then the current function’s return is the return of the new function call and it doesn’t need to keep the current function in memory

Does this mean that in most functional languages, at least when using tail-call optimization, the space complexity of an algorithm shouldn’t be that much worse than the iterative version of it in an imperative language ?

Showing Posts 1 to 2

blatyo

blatyo

Conduit Core Team

It depends on the values being recursed over and if they can be stored on the stack. Some values may be stored in the heap. So, even though there is no stack frame pointing to it, because of the frame being replaced, the value on the heap is still there until it gets garbage collected. Stuff that can be allocated on the stack are usually small values, like small strings and numbers.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

This seems orthogonal. The issue with recursion in languages like python is that regardless of where the values in the function are WRT the stack / vs heap, each recursive function call adds a stack frame. If it’s a GCed language (python) there is exactly the same issue WRT accumulating garbage. In fact arguably it’s worse, since there is a live stack frame pointing to the value, whereas in Elixir those frames are replaced and you can garbage collect the value.

The BEAM implements not only tail recursion but actually “last call elimination” where if the last thing a function call does is call a local function, the stack frame of the new function replaces the current stack frame. This allows mutual recursion where two functions recursively call each other.

Therefore:

Yes, in fact it can be identical to the iterative version.

The thing though is, even non tail recursive versions can have the same space constraints. Consider the simple function:

def multiply_by_2([]), do: []
def multiply_by_2([ n | rest]), do: [n * 2 | multiply_by_2(rest)]

This is a body recursive function, and therefore it will accumulate stack frames. The space complexity of this is O(n). The thing is, the space complexity of the iterative version is… also O(n). Now, because of immutable data, the Elixir version may generate more garbage, but honestly that depends entirely on the underlying implementation of lists / arrays in the language.

— All posts loaded —

Where Next? Top

Trending in Discussions Top

wmnnd
Hey folks, I wanted to share with you a project I’ve been working on for a while: It’s an Open Source (AGPLv3) newsletter tool. Think Ma...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New
sntran
In my third year of college, around 2010, I found Erlang. A few years later, I found Elixir. I liked the ideas at once: many small proces...
New
Ganna
Hi everyone, I have 8 years of production experience with Erlang/OTP and I’m just starting to get to know Elixir. What would you learn f...
New

Other Trending Topics Top

mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews