Ramarren wrote:Common Lisp is not a functional language, it is a multiparadigm one. This allows it to fit to almost any problem domain without jumping through ridiculous hoops, although some rarer paradigms would require bolting on a library, which might or might not be already available.
Granted. However, certain authors still try to emphasize a more functional approach to Lisp. For example from p. xi (in the preface, A Note to Instructors) of CL:GISC
Some people prefer to teach Scheme in introductory courses because it is
so much smaller than Common Lisp. But one can easily teach the subset of
Common Lisp that is equivalent to Scheme, so language size isn’t really an
issue for beginners. A more compelling argument is that there is a certain
style of applicative programming, making heavy use of lexical closures, that
can be expressed more elegantly in Scheme syntax. But there are also areas
where Common Lisp is superior to Scheme, such as its support for user-
defined macros, ... Although this book
does emphasize a side-effect-free, applicative approach to programming with
which Scheme afficionados will feel quite at home, it does so in purely
Common Lisp style.
Moreover, in ACL, CLOS appears in only one chapter (Chapter 11), and Paul Graham gives a succinct by-the-numbers treatment of it. The tone in his presentation is telling (p.178):
In practical terms, object-oriented programming means organizing a program in terms of methods, classes, instances, and inheritance. Why would you want to organize programs this way? One of the claims of the object-oriented approach is that it makes programs easier to change...
If the program was written carefully to begin with we can make all these types of modifications without even looking at the rest of the code. [Emphasis mine]
Graham elaborates on this in an endnote (no. 178) in the appendix (p. 408)
Let's play that back one more time: we can make all these types of modifications without even looking at the rest of the code. This idea may sound alarmingly familiar to some readers. It is the recipe for spaghetti code.
The object-oriented model makes it easy to build up programs by accretion. What this often means, in practice, is that it provides a structured way to write spaghetti code. This is not necessarily bad, but it is not entirely good either.
A lot of the code in the real world is spaghetti code, and this is probably not going to change soon. For programs that would have ended up as spaghetti anyway, the object-oriented model is good: they will at least be structured spaghetti. But for programs that might otherwise have avoided this fate, object-oriented abstractions could be more dangerous than useful.
Though others might protest Graham's remarks as overly emphatic and dogmatic, I think he has a point. Even with my limited exposure to Lisp, I find it easier to test and refactor than other languages (including Smalltalk, my all-time favorite OO language). Side-effect-free functions compose more easily and naturally than objects do. Overall, I find them more formal and mathematical, and often wish that I had learned Lisp from the very start.