
What's new in purely functional data structures since Okasaki? (2010) - r4um
http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki
======
hellofunk
Perhaps the most interesting "discovery" for me in this area is that these
types of data structures are not possible in C++ as they are in other
languages, due to lack of GC or tail recursion[0], either of which could make
them a reality.

The other discovery is that some languages, like Swift, are introducing lots
of surface-level functional idioms that resemble their counterparts in truly
functional languages, but without the persistent structures. Since Swift is
implemented in C++, no doubt that's why it's not a reality in that new
language either.

If someone could cleverly invent an implementation of Okasaki that worked in a
language like C++ (and some smart people have really tried), I think it would
be a major game changer to the language's possibilities. This handicap is a
rare example of something that is simply not so possible in C++.

[0]
[https://github.com/BartoszMilewski/Okasaki/issues/1](https://github.com/BartoszMilewski/Okasaki/issues/1)

~~~
tines
> due to lack of GC or tail recursion

(1) I'm pretty sure that everything that can be done by a GC can be done by
`shared_ptr` and `weak_ptr`. If not, then you can use Boehm GC if you don't do
anything weird with pointers.

(2) If you mean "tail recursion optimization", it's a compiler thing, not a
language thing in this case, and GCC and MSVC in fact support it, and I'm sure
Clang does too. So since "either one" is sufficient, as you say, it looks like
you can go implement Okasaki's stuff in C++ now!

~~~
davexunit
Tail calls are not simply an optimization, they are semantic.

edit: Not understanding the downvotes here. In Scheme, for example, tail calls
are part of the semantics of the language. We know that when we place a
recursive call in tail position that we're really describing a linear process.
If such a thing is just an optional optimization, programmers can't rely on it
in the same way.

~~~
sonyandy
Luckily, you can do the rewrite manually. I recently implemented an array
mapped trie that shared structure when copied. `find`, `erase`, and `at` were
all rewritten to use loops after first implementing them recursively (and
profiling indicated it to be a problem).

~~~
masklinn
If you follow the link, the issue isn't iteration, iteration is easy. The
issue is the recursive destruction of the tree when the root is destroyed and
no subtree is shared.

> The list implementation is simple/nice but it imposes a limit on number of
> stored elements because of "additional effect" of recursive destruction.

~~~
sonyandy
How would you perform destruction of a tree with more than one child tail
recursively? I mean this as an honest question - my current implementation of
array_mapped_trie performs this operation via non-tail recursive calls.

EDIT: I also don't see how destruction of a list is any harder than iteration
of a list, as far as writing it tail recursively. You would need to make sure
your node destructors are trivial, but you probably need to do this anyway if
you intend to support using a custom Allocator (would instead have template
<typename Allocator> destroy(node*, Allocator&); that calls Allocator::destroy
on the contained value and Allocator::deallocate on the node). The
implementation would then look something along the lines of:

decltype(head) next; for (auto ptr = head; ptr; ptr = next) { next =
ptr->next; if (ptr->unique()) { destroy(ptr, allocator); } }

(unique() is a method on node - intrusive ref count.)

------
davexunit
I implemented Okasaki's persistent queue in Scheme recently using SRFI-41
streams and it was a lot of fun. Now, I need to grok things like finger trees
so I can understand persistent vectors and hash tables.

~~~
tibbe
Look at hash array mapped tries, which is what most functional languages use
to implement hashmaps.

------
kazagistar
Whats new since "What's new in purely functional data structures since
Okasaki?"? Its been 5+ years now...

------
peteretep
I learned functional programming from Ralf Hinze, great to see his
contributions, even if he did teach me to say 'mooo-nad'.

