In your favorite programming language, how do you sort a list of the strings "a", "bcd", "ef", and "ghij" in descending order of length?
One proposed solution was:
tag_negative_len(Str, NegLen-Str) :-
atom_length(Str, StrLen),
NegLen is -1*StrLen.
rem_tag(_-Val, Val).
sort_desc_len(StrLs, Sorted) :-
maplist(tag_negative_len, StrLs, TaggedLs),
keysort(TaggedLs, SortedTaggedLs),
maplist(rem_tag, SortedTaggedLs, Sorted).
I assume that the above code was written for ISO Prolog, because it doesn't make use of implementation-specific features. Example usage:
?- sort_desc_len(["a", "bcd", "ef", "ghij"], L).
L = ["ghij", "bcd", "ef", "a"].
I would have solved it in a similar way. However, the solution is extremely verbose (as compared to the one or two-liners of other programming languages), and pollutes the program with helper/auxiliary predicates. Is there a better way to solve the problem in ISO Prolog?
that is, findall/3 implements the closures by means of member/2. setof/3 would allow to merge the first findall and the keysort calls, but it would remove duplicates...
Note that atom_length/2 could not work with an ISO compliant processor. Double quoted strings are lists of codes, not atoms.
Anyway, I agree Prolog is rather verbose when it come to functional programming. I think the cause is that it has a relational data model.