To do something like OO in Emacs, define variables that are buffer-local, and then use the buffer as the object.
Maybe you shouldn't consider it for a user mode or some such (though I don't see why, there are enough modes that do use it) but I made clear in my article that I was asking people to consider EmacsLisp as a real language in which you could write programs that are not just Emacs programs, scripts for example, which I specifically alluded to.
Web programming is also possible of course, with Elnode - http://elnode.org/
Emacs Lisp's flaws are forgivable when writing Emacs extensions because it integrates so well with Emacs. But without the Emacs integration, it's not that great.
But of course, it's not suited to every application.
Scheme is still a bit stuck in the multiple-implementations-none-of-which-fully-implement-exactly-what-you-want type stage.
EmacsLisp is like Ruby, but better. One implementation (basically all the others are gone) and lots of people hacking on it and making it better.
The ways it differs from Ruby are that it's a proper Lisp (macros and homoiconicity) and that all the development and debugging tools are built in. Edebug is a fantastic tool for example.
This is how OO is done in Common Lisp (CLOS is the standard here) and Scheme (no standard object system, but every so often someone writes one for themselves).
$$ Reading Let Over Lambda is what done it to me.
(defmethod some-user-greeting ((user some-userc) &optional daytime)
means that the argument 'user' to the method MUST be an object of class 'some-userc'.
EmacsLisp's CLOS doesn't have as much type checking as CL's but it is there.
This is what CL people say, certainly; what you think of this statement (true? useful? a bad definition of 'object'?) depends entirely on what you think an 'object' is.
If you're a Smalltalker (or a Java programmer, or a C++ programmer, or a user of any language that got its object system from Smalltalk), then an object is something that can respond to messages. CLOS doesn't work like this: There are no messages, and expressions don't contain objects privileged to be the recipient of the message being used; therefore, a Smalltalker might well say that while CLOS has inheritance and polymorphism, it doesn't have objects as such.
(And, off in the corner, some C programmers are insisting that an int is a perfectly good object.)
I also find it useful to keep a short file of features I want to learn and features (1 or 2) I'm currently learning (trying to use as much as possible even if it slows me down a bit so that they'll stick in my mind).
One thing I'd really like to do is to make a massive index of emacs-lisp code on github. That would be a fantastic resource.
(defun kill-whitespace ()
"Kill the whitespace between two non-whitespace characters"
(re-search-backward "[^ \t\r\n]" nil t)
(re-search-forward "[ \t\r\n]+" nil t)
(replace-match "" nil nil))))))
Of course, a lot of the time buffers are really powerful tools to replace strings. I just don't think your original assertion of "almost never" is right. Buffers are handy but I use them to replace strings less than 50% of the time.
I agree stuff like this is ugly, but use of annoying naming conventions in order to get an extremely practical implementation language (particularly a Lisp) is a trade off I'm happy to make.