In general, language design requires a balance between first-class vs. second-class objects. First-class objects are important because they let you write the program you want. Second-class objects are also important because they let you write programs that can be reasoned about.
For instance, Haskell's type language (without compiler-specific extensions) has no beta reduction, because only type constructors can appear not fully applied in type expressions anyway. This reduces its “raw expressive power” (w.r.t. System F-ω, whose type level is the simply typed lambda calculus), but it makes inference decidable, which helps machines help humans. It also helps humans in a more direct fashion: Haskellers often infer a lot about their programs just from their type signatures, that is, without having to compute at all. It's no wonder that Haskellers love reasoning with types - it's literally less work than reasoning with values.
So I agree with you that “first-class everything” isn't a good approach to take. A language with first-class everything is a semantic minefield: Nothing is guaranteed, sometimes not even the runtime system's stability. (I'm looking at you, Lisp!)
---
But, on the specific topic of first-class functions, you'll pry them from my cold dead hands. Solving large problems by composing solutions to smaller, more tractable problems, is a style that's greatly facilitated by first-class functions, and I'm not ready to give it up.
You misunderstand (as most do): I never said function composition was a bad idea; I do it all the time.
My only claim is that you don't need a Turing-complete language to compose functions. As an thought-exercise, consider replacing all uses of first-class function compositions in any given OCaml program with top-level module compositions. You lose nothing: no-one (who designs maintainable software) uses the full expressive power of a Turing-complete language to manipulate first-class functions.
(Of course there are more user-friendly ways to implement second-class functions, which make using them less a burden, but no extant language has such a system.)
When did I say “function composition”? What I said is “composing solutions to smaller, more tractable problems”. If you divide a problem `FooBarQux` into a sequence of subproblems, `Foo`, `Bar` and `Qux`, sure, these solutions must be combined using the function composition operator. But there are other ways to decompose problems. For instance, splitting a problem into a DAG of subproblems with overlapping dependencies gives rise to dynamic programming.
And, no, an ML-like module system wouldn't make up for the lack of first-class functions. Standard ML doesn't allow any module recursion whatsoever, and, while OCaml allows it, it's quite unwieldy to use in practice. It would be literally impossible to define a function like `fix`, which requires the ability to call its function argument (let's call it `f`), supplying an expression containing `fix` itself as argument.
For instance, Haskell's type language (without compiler-specific extensions) has no beta reduction, because only type constructors can appear not fully applied in type expressions anyway. This reduces its “raw expressive power” (w.r.t. System F-ω, whose type level is the simply typed lambda calculus), but it makes inference decidable, which helps machines help humans. It also helps humans in a more direct fashion: Haskellers often infer a lot about their programs just from their type signatures, that is, without having to compute at all. It's no wonder that Haskellers love reasoning with types - it's literally less work than reasoning with values.
So I agree with you that “first-class everything” isn't a good approach to take. A language with first-class everything is a semantic minefield: Nothing is guaranteed, sometimes not even the runtime system's stability. (I'm looking at you, Lisp!)
---
But, on the specific topic of first-class functions, you'll pry them from my cold dead hands. Solving large problems by composing solutions to smaller, more tractable problems, is a style that's greatly facilitated by first-class functions, and I'm not ready to give it up.