So I’m trying to implement the following;
// Destructive Abstract data type ilist
struct ilist_ADT;
typedef struct ilist_ADT *ilist;
// prototype for secret implementation
// do not rely on ilist being a pointer
ilist iempty();
// returns an empty ilist
int iempty_huh(ilist il);
// returns 1 (true) if il is empty
// returns 0 (false) if il is not empty
int ifirst(ilist il);
// returns the first element in il
// il must not be empty
ilist icons_destroy(int in, ilist il);
// returns an ilist with in added as the first element of il
// references to il cease to be valid ilists
// the result must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
ilist irest_destroy(ilist il);
// modifies il to remove the first element, and returns the modified ilist
// frees the memory associated with the first element
// references to il cease to be valid ilists
// the result (if non-empty) must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
ilist icopy(ilist il);
// returns a new copy of il that continues to be a valid
// ilist with the same elements even when il is destroyed
// the result must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
int ilength(ilist il);
// computes the number of elements in il
void idelete(ilist il);
// frees the storage for ilist
// all further references to il become invalid
// NOTE: every ilist created by icons_destroy or
// irest_destroy or icopy must eventually be destroyed
// by being consumed by icons_destroy or
// irest_destroy or idelete
I am focusing on icons first, and i have a non-destructive icons such as:
ilist icons(int in, ilist il) {
ilist r = malloc(sizeof(struct ilist_ADT));
r->first = in;
r->rest = il;
r->length = 1 + ilength(il);
return r;
}
How exactly would i make this to suit the implementation? in other words how do i make it destructive?
“Destructive” means that the arguments to a function (or the receiver in an oop’s method) is allowed to be modified. A non-destructive function means that it does not modify its arguments but instead returns a modified copy. The advantage of allowing a destructive function is, that you dont have to create that copy and thus you typically need fewer mallocs (in this example, however the number is the same).
In the implementation of
iconsyou provided you can see that con’ing an entry keeps the originalilist ila valid unmodified list!: Anyone usingilist ilwill not notice that you did anything (this only works with singly-linked lists of course).A destructive implementation first allows you to modify the arguments, but it also implies that you are supposed to modify the arguments in a meaningful way: You should modify it such that someone who still has a reference to the original
ilist ilshould see your modification. You can do this like so:Now someone else who holds a ref to
ilist ilwill see the new-first element followed by the old-previously-first element.