Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do functional programming languages require garbage collection?

According to Wikipedia, the translation from lambda calculus to combinatory logic is trivial. Concatenative programming languages can rely solely on a stack for memory allocation.

What's stopping GHC from translating Haskell into a concatenative programming language, such as combinatory logic, and then simply using stack allocation for everything?

Is it feasible to do this translation and thus eliminate garbage collection for languages such as Haskell and OCaml? Are there downsides to doing this?

like image 417
grasevski Avatar asked Sep 11 '16 20:09

grasevski


People also ask

Why do functional languages require garbage collection?

The fundamental challenge garbage collection addresses is freeing memory that is not, or is not known to be, used in a stack-like fashion. It is most especially useful when there is no clear place in the source code that can be pinpointed as the end of the object's lifetime.

Why is garbage collection important for code optimization?

The garbage collector provides the following benefits: Frees developers from having to manually release memory. Allocates objects on the managed heap efficiently. Reclaims objects that are no longer being used, clears their memory, and keeps the memory available for future allocations.

Do all languages have garbage collection?

Garbage collection is the process in which programs try to free up memory space that is no longer used by objects. Garbage collection is implemented differently for every language. Most high-level programming languages have some sort of garbage collection built in.

Is garbage collection Necessary?

It is not strictly necessary. Given enough time and effort you can always translate a program that depends on garbage collection to one that doesn't.


2 Answers

Suppose I have a function that generates a linked list of some size. The size is the function parameter.

The question is: where do I have to allocate memory for the list? I can't allocate it on the function's stack, since it's invalid after the function is out. And I can't allocate it on the caller's stack, since I don't know how many memory I need to allocate before the function call. So I need to allocate it on the heap.

I think there may be RAII with manual heap management usable, But I can't see how to eliminate heap allocation at all.


Edit

I can't fit all my thoughts in the comment, so I write them here.

There is no magic about stack-based allocation languages. You still need to know when your data is relevant and remove them when they're not.

Imagine you have a separate stack, and your function has control to push and pop data in it. First, there is no automatic memory management anymore, i.e. the function terminates but the data is not deallocated automatically. Second, if you function allocates some memory, needed to support e.g. the list calculation, then all that stuff will be shuffled with the list that you want to return. No chance you can free unused memory (other lists, trees or so) since you have just push and pop operations. If you have other operations, then what is the difference with the heap?

What about few stacks, not one?

You need to allocate them somewhere, manage their growth and sometimes get them back. That stacks are separate constructions that you need manage by hands. No automatic memory management.

Stack-based languages are ok, but forget about the huge amount of algorithms, that was invented with the concept "get memory from somewhere" and "put the memory back", like hash maps, red-black trees, linked lists. Of course, we can allocate all of those structs on a stack, but we can't free their parts if they don't need anymore.

What about "trivial" lambda calculus translation to Turing machine?

Of course, it is trivial, if you resources are infinite. The math theory clarifies nothing about time and memory complexity of such translated constructions. It just approves that both of that models are equivalent, and all that we can say with Turing machine we can say with lambda calculus, and vice-versa. No guarantees that it can work with real-life limitations.

like image 167
a.yekimov Avatar answered Nov 17 '22 19:11

a.yekimov


A concatenative programming language is every bit as capable of running out of memory as a functional programming language.

The fundamental challenge garbage collection addresses is freeing memory that is not, or is not known to be, used in a stack-like fashion. It is most especially useful when there is no clear place in the source code that can be pinpointed as the end of the object's lifetime.

If you simply translate a functional language into a concatenative one with only stack allocation, then you will end up overflowing the stack.

There have definitely been various efforts over the years to reduce the need for garbage collection. One interesting (but very complicated) attempt is the region inference system used in the ML Kit. Unfortunately, that's a bit much for most programmers, including myself, to understand. I believe others have worked on such systems since; I don't know the current state of the art.

The take-away is that some very heavy compiler machinery, along with careful programmer discipline and perhaps special annotations, can sometimes reduce or eliminate the need for garbage collection; no trivial transformation is going to do the trick.

like image 41
dfeuer Avatar answered Nov 17 '22 18:11

dfeuer