against list flattening
"Richard A. O'Keefe" <[email protected]>
| Newsgroups | gmane.comp.ai.prolog.swi |
|---|---|
| Message-ID | <[email protected]> |
As I have mentioned, probably often enough to be annoying, I've been developing a somewhat unusual Smalltalk system, compiling Smalltalk to C. Currently I'm comparing its class library's with Ruby's to see if I'm missing anything useful. So far I've found a handful of operations that looked worth stealXXXXXcopying, although they generally needed refactoring and in one case I'm so worried about the risks it introduces that I'll probably pull it out again. And then I came across a.flatten() a.flatten(depth) a.flatten!() a.flatten!() where a is an Array. And that just blew up in my face. My system has no fewer than 62 concrete "indexed sequence" classes, excluding example files, which introduce several of their own. And that's not counting Deques and sorted sets... Just what set of classes should be covered by .flatten()? How should user-defined classes be plugged in? What possible sense does it make for .flatten() to flatten an array of arrays to an array but not an array of strings to a string? (In Smalltalk, _none_.) And what should a user do who wanted *some* arrays to be flattened but other arrays to be treated as atomic data? I just couldn't assign any coherent *meaning* to the flatten operation. Oh, I could *implement* it, but I couldn't make it mean anything *except* the implementation level; I could not say "this is what it does to a coherent data structure". Now it is just the same in Prolog. Pairs and nils are *one* way to represent a sequence in Prolog, but there are plenty of others (like unrolled lists, like lazy concatenation, like applicative random-access stacks -- library(ranstk), ..). If you are in the habit of using flatten, then which of the many possible implementations of the sequence idea you use is no longer just an implementation detail; if your data structure is included in someone else's list, the choice affects _their_ result. And worse, there are some lists you want treated as atomic and others you do not. This is not an argument against flattening (clearly labelled) *trees*. That's a useful and unproblematic operation. It is an argument against flattening "lists". The clincher, of course, is L = [a,B,c], flatten(L, R), B = [2,3] => R = [a.[2,3],c] which is not flat.