I am a little confused by what you mean when you say "functions as modules", this makes me think of the Standard ML module system and functors in particular. A function being a function which takes a module as an argument and returns a new module. Is this what you are refering too? If not then I am totally confused by your use of the word "module". Please expand.

This is one part where I think it is essential to take a step back and forget everything you know about any programming languages you have learned.

The problem here is that both module and function are highly overloaded concepts. Sometimes modules are building blocks as in other engineering disciplines, sometimes they are an abstraction mechanism, sometimes they are a particular way in your programming language to encapsulate functionality, ... Similarly functions could be procedures, methods, subroutines, lambda expressions, or mathematical functions (which could be mappings or relations), or what have you. Let's forget all about that, too.

Actually, let's give a new name for the concept.

Let gob have the following meaning: Any particular functionally sensible piece of program text that has a well-defined interface through which it can be used and with which it can be connected to other gobs.

Given this meaning, a computer program is a gob: it accepts some input and produces some output. (If you want, the input and output can be partially or completely the global state of the machine.) A computer program can be connected to other gobs through its input and output.

A class in object-oriented programming is a gob: the well-defined interface is the public methods, and these are used when connecting the class to other classes (gobs).

A module in, say, Perl, is a gob: whether it is object-oriented, functional, or a collection of procedures, it has some interface through which it can be used. The interface can again be used to connect it to other gobs.

A function/routine/subroutine/procedure is a gob: the interface to a function is the parameters it accepts (the input) and the return values (the output). (If you want, it may also partially affect the (global) state of the machine, i.e. work through side-effects.) The interface can, again, be used to connect this gob to other gobs.

This is what I mean. At a very high level, all current programming paradigms let you create gobs and pass gobs as parameters to other gobs. How gobs are implemented in your particular programming language is not relevant; the concept is! Gob is the quintessential Lego block of programming, if you want.

Suppose you have that small statistical analysis framework. One gob abstracts the control: it takes in data in some form, processes the data chunk by chunk by giving it to another gob (supplied by user), which returns a value, and the value is given to a third gob (supplied by user) along with the ID number of the data chunk. The user provides such a pair of gobs that they work well together (the latter understands the output format of the former), and the framework is completely agnostic to what kind of data these two gobs pass around; it just connects the gobs together and provides them with small pieces of data.

How you might implement this could be with three classes: one for control, another for data analysis, and a third for data collection or plotting.

Or you could implement the control as a function that takes two closures as parameters.

Or you could implement the control as a function that takes two objects as parameters.

Yes, all this theory is very nice, clean and organized, but it doesn't help me at all when I need to get a job done.

This is one part where I think it is essential to take a step back and forget everything you know about any programming languages you have learned.

Again, I disagree. First of all, you are talking about concepts very heavily tied to programming languages (in fact, all your expansions on the "gob" definition come back to programming languages). But really what you call a "gob" is nothing new or fantastical, but simply the product of "moduler decomposition". Modular decomposition is not specific to computer science of course, or even engineering. Many artistic disciplines use the technique, like music and painting.

And lastly, you have not really given a useful alternative to OO. You say you don't like it, but you have not shown a superior tool. Sure, we all hate zealots, but that is no reason to abandon OO and the 30+ years of research and usage in which it has grown and developed as a paradigm. But hey, if you want to go back to the 70s/early 80s and program in CLU or Pascal, be my guest.

It helps me think. The root node title says I dislike, and the author was vrk, not stvn (you can compare that with your favourite programming language, if you like). I only argued why object-oriented programming fails to warm my heart, and to my knowledge there was no direct promise of enlightenment after reading my ramblings.

I don't claim to have discovered anything new here. I used the word gob since you were confused with my use of module; but apparently modular decomposition is okay, so I'll use that.

I find it very helpful to keep in mind that despite the programming language, you are always dealing with the same basic things, which boil down to separation of concerns and modular decomposition. If I were stuck with only one or two particular techniques in modular decomposition, and the programming language I used lacked those, I would be stuck. Clearly you are more clever than I am and this doesn't concern you, but for us less advanced in the audience, I'll explain.

For example, recently I've had to program in PHP. PHP 4 and 5 have classes and objects (less refined in the former than in the latter), and they support a rudimentary callback mechanism by giving function names as parameters (through "variable variables"; in Perl: reference to a scalar). They also have eval, but I try to keep away from that beast. So, my options in modular decomposition are limited: I can make some procedures or I can make some objects, and that's about it.

If I only knew, say, (pure) functional programming through Scheme, I would be in trouble: no support for the particular mechanisms of modular decomposition that I know. Oh! But what I do when I pass closures around is roughly the same as passing objects! Problem solved: I'll explicitly define classes and then instantiate objects.

Programming in Scheme would be equally confusing if you only knew object-oriented programming. Oh, what am I saying, of course not: it's the same modular decomposition process again, only with different concepts. In multiparadigmatic languages I even have a choice, when decomposing the problem into gobsmodules parts, which particular mechanism to use based on the structure of the problem.

I'm not saying that by knowing what modular decomposition is you would miraculously know any programming paradigm there is. (You'll no doubt read it that way.) The point of all this waste of time is to say that I don't like the particular mechanism of modular decomposition offered by (pure) object-oriented programming, regardless of how the particular implementation of object-oriented programming works (and by implementation, I don't mean how the programming language is implemented, but it seems to be useless to make distinctions).

And lastly, you have not really given a useful alternative to OO.

Right, I suppose I should have written four or five of these meditations to enforce equality between paradigms.

But since you asked nicely, I recommend pure functional programming with monads to encapsulate the particular cases where you need explicit state and sequential execution. Haskell is one where this happens. You can read more propaganda from their wiki.

Relax man, don't take this all so personally, we are just talking 'bout Perl here.

The point of all this waste of time is to say that I don't like the particular mechanism of modular decomposition offered by (pure) object-oriented programming, regardless of how the particular implementation of object-oriented programming works

My point is that many different languages provide different approaches to OO, and therefore provide a different form of "OO-style modular decomposition". I find it hard to believe that you have programmed enough (non-trivial) applications in all these different languages to really make such a sweaping statement about OO programming in general. I know that I have not done so, but I am willing to leave open the possibility that what I don't like about $language{X} might be "fixed" by some feature of $language{Y}. Or that through some creative technique I might be able to implement said feature in $language{X} often times by (ab)using the language in ways it was never intended to be (ab)used.

For instance, when I have programmed in Java, I have really really missed closures, which I use heavily in my Perl OO programming. In the end I just created an interface and wrote small inline classes to mimic them. It was clunky, but worked.

When I programmed in Javascript, I really missed some kind of namespacing mechanism, thankfully someone came up with a cool namespace hack using functions and exploiting the prototype based OO system.

I learned to hate Perl's clunky OO system over the years, but I loved where Perl 6 was going. So I wrote Moose, which bootstraps an entire new OO system into Perl's existing one.

In all these three examples, $language{X} was missing a particular "gob", but with a little creative hacking that "gob" (or something fairly close to it) was added to $language{X}.

Right, I suppose I should have written four or five of these meditations to enforce equality between paradigms.

Hopefully you don't hate all programming paradigms, cause if so, I think you picked the wrong career/major.

But since you asked nicely, I recommend pure functional programming with monads to encapsulate the particular cases where you need explicit state and sequential execution. Haskell is one where this happens. You can read more propaganda from their wiki.

Yeah, Haskell is nice, but IMO monads tend to be an overly complex abstraction of what are usually very simple tasks/requirements. The exception being the Maybe monad, which I always thought made Haskell code more readable.

It is interesting that you say monads, because while there are many "Monads in $my_favorite_language" blog posts out there, there are few practical uses of the technique outside of Haskell. Part of this is due (IMO of course) to the fact that really effective use of monads relys not only on a strong type system, but also on polymorphism (i.e. overloading of >>= operator) such as is provided by Haskell's type classes. Simply taking a look at any monad implementation in OCaml will illustrate this, since OCaml does not have this level of polymophism (you can hack around it somewhat using Functors, but it gets really ugly). So really your solution to OO is heavily tied to a particular programming language and other features in that language that truely make it a useful technique. Just as writing small inline classes to mimic closures in Java sucked, I would not want to have to use some other ackward technique in $language{X} to have monads.

My whole point is that you can't be implementation agnostic when discussing the merits of a particular paradigm, especially in a multi-paradigm language like Perl. As many people around here are fond of saying ...