next up previous
Next: Further Work Up: Experiences with higher order Previous: Member

Other predicates

Before implementing our transformation tools we recognised several programming patterns and implemented the corresponding higher order predicates. A version of map which also has an accumulator pair of arguments, map_acc, has been of use and could be implemented in functional languages as well. A variation of map0 which calls a predicate for each consecutive pair of elements in a list, map0_consec, can be used to check sortedness, for example. This could be adapted to functional programming by applying functions which return booleans. We have also used a combination of map and filter which relies on the ability of a predicate to either return a result or fail: split(P,Xs,Ys,Zs) applies P/2 to each member of Xs and returns the list of results of successful calls to P and the list of elements for which P failed.

We have also found it useful to extend our tools to implement transformations which are special cases of other higher order predicates. Instead of using a complicated instance of a very general higher order predicate, we can use a relatively simple predicate. This is appropriate if the instance of the higher order predicate is common. We have already seen an example of this: map is an instance of foldr, at least in the case of algebraic types. It is somewhat special instance since it is particularly useful and can be coded in a tail-recursive way due to the nature of unification. We have implemented another instance of map/foldr which preserves the shape of the data structure without relating the elements: same_shape. It is a generalisation of same_length for lists. We have also implemented an instance of foldl which converts any data structure into a list using an accumulator, list_from, which generalises a reverse post-order traversal. The transformed code contains calls to append where the first argument is the list of variables which don't occur in recursive calls. The append calls are optimised away by the DCG expansion in NU-Prolog. Program 20 shows the result of transforming rtree_any/1.

list_from_rtree_any(rt(A, B)) -->
    append([A]),
    list_from_list_rtree_any(B).

list_from_list_rtree_any([]) -->
    append([]).
list_from_list_rtree_any([A|B]) -->
    append([]),
    list_from_rtree_any(A),
    list_from_list_rtree_any(B).
Program 20: List-from transformation for rtree_any/1


next up previous
Next: Further Work Up: Experiences with higher order Previous: Member
Lee Naish
2000-07-26