class InsertRear implements MutSeqVisitor {
/* given the embedded Object elt and a host with elements s[0], ... s[n],
host.execute(this) destructively updates host so that host =
s[0],..., s[n],elt */
/* field */
private Object elt;
/* constructor */
InsertRear(Object e) { elt = e; }
Object forEmpty(MutSeq host) {
host.insert(elt);
return null; /* dummy return value; this operation has return type void!
}
Object forCons(MutSeq host) {
((MutSeq) host.rest()).execute(this);
return null; /* dummy return value; the return ``type'' is void!
}
}
class MutAppend implements MutSeqVisitor {
/* given the embedded MutSeq tail with elements t[0], ..., t[n] and a host
with elements s[0], ... s[n], host.execute(this) destructively
updates host so that host = s[0],..., s[n],tail[0],...tail[m] */
/* field */
private MutSeq tail;
/* constructor */
MutAppend(Object t) { tail = t; }
Object forEmpty(MutSeq host) {
host.set(tail);
return host; /* dummy return value; this operation has return type void!
}
Object forCons(MutSeq host) {
return ((MutSeq) host.rest()).execute(this);
}
}
The primary disadvantage of quasi-functional lists is that sharing list tails between two list objects can produce unexpected results when list objects are mutated. Mutating a shared list tail changes all of the list objects that share that tail! In the programming literature, the sharing of mutable data objects is often called ``aliasing''.