[plt-scheme] self-referential data structures

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Thu Mar 5 22:08:57 EST 2009

On Mar 5, 2009, at 5:10 PM, aditya shukla wrote:

> Here in chapter 9 the problem of adding all numbers of a list of  
> numbers is explained.The method explained to tackle the problem is  
> based on the data definition of list of numbers .And this has been  
> the approach of the book that is a problem is solved according to  
> the data definition of a data structure.Suppose I switch from  
> scheme to any other programming language say c++ ,so should the  
> same approach should be followed ?

I have taught this exact same data structure, and the exact same  
approach to solving the problem, in Java and C++.  It's more  
complicated in Java, and even more complicated in C++, but it can be  
done.  In fact, I assigned my beginning Java students to do that  
exact problem yesterday.

In partial answer to your previous question, no, self-referential  
data types are not limited to functional programming, and in fact  
people have been building lists and trees in C, Pascal, Ada, C++,  
etc. for decades.  Some of the problems they encounter can be  
eliminated by making the data structures "immutable", i.e. creating a  
little safe island of functional programming within the terrifying  
ocean of mutation and imperativity. :-)  In Java and C++, for  
example, you can largely achieve this by providing getters, but no  
setters, for your class fields.

However, there are more complicated self-referential data types that  
are difficult to do without mutation.  For example, consider
(define biglist (list 10 9 8 7 6 5 4 3 2 1 0))
(define partlist (rest (rest (rest (rest biglist)))))
 From "partlist", you can easily get the 5th element of the original  
list, or move forward to the the 6th element and so on... but there's  
no way to "move backward" through the original list to see the 3rd  
element of the original list, because "partlist" doesn't contain that  
information.  For some applications it's very useful to be able to  
move both backward and forward through a large list, and the usual  
data structure to do that is called a "doubly linked list".  Since  
the 5th element of a list has to "know" about both the 4th and 6th  
elements, both of which have to "know" about the 5th, the usual way  
to build a doubly linked list is to create the 6th element, then  
create the 5th element referring to it, then MUTATE the 6th element  
so that it knows about the 5th element in turn, then create the 4th  
element referring to the 5th element, then MUTATE the 5th element so   
it knows about the 4th element, and so  on.  This is difficult to do  
without mutation.

However, if you basically like functional programming but need a  
doubly-linked list for one part of your program, you can wrap up the  
mutating doubly-linked list in a "front end" that looks functional,  
even though there's actually some mutation going on behind the scenes.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.