I am in the camp that says keep the abstraction level somewhere in the middle, not too low (painful) and not too high (you will lose a lot of people). There is a happy Buddhist middle there somewhere.<p>Almost any code meant to be used by other people (i.e not throw-away scripts, but even some of those!), even code written by almighty Lispers, will need to be tweaked by another person at some point - they call that "maintenance" but since that term comes with baggage, I say tweaking.<p>Great Lisp (and by extension any very-high-level-abstraction) tends to emphasize the elegant proof aspect of it, or the poetry aspect of it, depending on whether you come from the math or the art bent of mind, which, of course, need not be mutually exclusive. "Painters and Hackers" captures this.<p>But refining code this way can leave out later day tweakers in a state of dread. This is why really great math profs don't just recite the super-elegant proof but actually "motivate" it, with examples, with analogies and so on, none of which will be found in the proof itself.<p>A medium-level abstraction language will tend to leave in the analogies and examples, in a sense, so the tweaker will find some guide-posts. At the very least, he can turn a little knob here and there, and there is a bit of continuity in his experimentation. With dense, super-abstract code, a single token can hold the hold galaxy but will take arbitrarily long to figure out.<p>Sorry for the long, rambling comment, but my personal experience (I have shipped a lot of stuff) is Buddha is right. We must avoid extremes and go for the middle.