Appending two list differences means just a unification of first diff's end pointer with the second one's head. With regular lists it requires retracing of the whole list structure of the first list. Thus repeated concatenation on the right is linear with the list difference technique, and quadratic with plain lists.
When all the intended concatenations are done, to return the whole structure as a plain list to a caller we just unify the "end pointer" logvar with [].
In C terms, list difference is a portion of singly-linked list where we maintain two variables: its head pointer but also its tail pointer:
// typedef struct { int payload; node* next } node;
typedef struct { node** head; node** tail } list_diff;
Now each concatenation is just an assignment of the end pointer:
void diff_concat( list_diff* a, list_diff* b)
{
*(a -> tail) -> next = *(b -> head);
a -> tail = b -> tail;
}
And finalization is
void diff_finalize( list_diff* a)
{
*(a -> tail) = NULL; // or some sentinel value, whatever
}
In Prolog we could represent it as a binary term like -/2, e.g. -(A,B) or A-B.
But (as in C also) there's no actual need to build an actual structure in memory just for holding the two pointers; we can just maintain two logvars individually. Or let DCGs do it for us.
The above was the motivational introduction to list difference technique, "what are they good for?". It also makes clear that the representation of empty difference is
list_diff* d;
*(d -> head) = *(d -> tail);
Or in Prolog, a pair of logvars unified with each other: L-L, var(L). To see why, see what happens when empty diff is appended with some other diff on its right (it is always on the right that we append things, thus growing the lists in the top-down manner). My C may be off here, the idea being that by setting the tail the appending to an empty diff will also update its head.
The empty list is represented by any pair of the form L-L.In your question you have it asT1-T2, so are you asking about two different list that are not the same and using them to represent the empty list? Note the emphasis on represent. - Guy Coderconc_d([a,b|T]-T, [d,e|T1]-T1, L).However, the result would beL = [a,b,c,d|T1]-T1, but as a programmer I would need[a,b,c,d], plain and simple. I have a feeling I am missing the point, but I don't see the practical benefit or fail to see how to use difference lists in practice. - Bram Vanroyphrase/2does for you automatically when using DCGs. But this goes for any data structure with holes, not just difference lists—I may need holes (like the end of the list) while computing something but I don't usually want to reason over them in general. - Daniel Lyons