C. A. R. Hoare in 1973

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com

I am surprised at how little has changed since 1973:

I would like in this paper to present a philosophy of the design and evaluation of programming languages which I have adopted and developed over a number of years, namely that the primary purpose of a programming language is to help the programmer in the practice of his art. I do not wish to deny that there are many other desirable properties of a programming language, — for example, machine independence, stability of specification, use of familiar notations, a large and useful library, existing popularity, or sponsorship by a rich and powerful organization. These aspects are often dominant in the choice of a programming language by its users, but I wish to argue that they ought not to be. I shall therefore express myself strongly. I fear that each reader will find some of my points wildly controversial; I expect he will find other points that are obvious and even boring; I hope that he will find a few points which are new and worth pursuing.

My approach is first to isolate the most difficult aspects of the programmer’s task, and state in general terms how a programming language design can assist in meeting these difficulties. I discuss a number of goals which have been followed in the past by language designers, and which I regard as comparatively irrelevant or even illusory. I then turn to particular aspects of familiar high level programming languages, and explain why they are in some respects much better than machine code programming, and in certain cases worse. Finally, I draw a distinction between language feature design and the design of complete languages.

But our approach here has changed:

Program debugging can often be the most tiresome, expensive, and unpredictable phase of program development , particularly at the stage
of assembling subprograms written by many programmers over a long period.

Combining subprograms remains a major point of pain, but there have been 2 developments:

1.) don’t integrate, but instead write separate apps that merely exchange data with each other. Nowadays it is common to setup a suite of apps using a microservices and something like Redis as a central bus, or making RESTful calls, with JSON as the format for data exchange.

2.) Use a high level language, such as Clojure, with high levels of metaprogramming, such as macros, to ease the task of composing many sub programs.

Source