In the world of physics, there are many different models that can be used, though typically each of them has different applicability to different contexts. At the small scale, quantum physics is a very useful model, Newtonian physics will yield evidently incorrect predictions so is less valuable. Where a Newtonian model gives sufficiently accurate results, it’s a lot easier to work with than quantum or relativistic mechanics.
All of these models are used to describe the same universe – the same underlying collection of observations that can systematically be categorised, modelled and predicted.
Physical science (or experimental philosophy) does not work in the same way as computational philosophy. There are physical realisations of computational systems, typically manifested as electronic systems or pencil-and-paper simulations. But the software, the abstract configurations of ideas that run on those systems, exist in entirely separate space and are merely (though the fact that this is possible is immensely powerful) translated into the electronic or paper medium.
Of course one model for the software system is to abstract the electronic: to consider the movement of electrons as the presence of voltages at terminals; to group terminals as registers or busses; to further abstract this range of voltages as 0 and that range as 1. And indeed that model frequently is useful.
Frequently, that model is not useful. And the great thing is that we get to select from a panoply of other models, at some small or large remove from the physical model. We can use these models separately, or simultaneously. You can think of a software system as a network of messages passed between independent objects, as a flow of data through transformers, as a sequence of state changes, as a graph of single-argument functions, as something else, or as a combination of these things. Each is useful, each is powerful, all are applicable.
Sometimes, I can use these models to make decisions about representing the logical structure of these systems, transforming a concept into a representation that’s valid in the model. If I have a statement in a mathematical formulation of my problem, “for any a
drawn from the set of Articles
there exists a p
drawn from the set of People
such that p
is the principal author of a
” then I can build a function, or a method, or a query, or a predicate, or a procedure, or a subroutine, or a spreadsheet cell, or a process, that given an article will yield exactly one person who is the principal author of that article.
Sometimes, I use the models to avoid the conceptual or logical layers at all and express my problem as if it is a software solution. Object-oriented analysis and design, data flow modelling, and other techniques can be used to represent a logical model, or they can be used to bash the problem straight into a physical model without having thought about the problem in the abstract. “Shut up and code” is an extreme example of this approach, in which the physical model is realised without any attempt to tie it to a logical or conceptual design. I’ll know correct when I see it.
I don’t see a lot of value in collecting programming languages. I can’t count the number of different programming languages I’ve used, and many of them are entirely similar. C and JavaScript both have sequences of expressions that are built into statements that are built into procedures. Both let me build aggregations of data and procedures that either let me organise sequential programs, represent objects, represent functions, or do something else.
But collecting the models, the different representations of systems conceptually that can be expressed as software, sometimes called paradigms: this is very interesting. This is what lets me think about representing problems in different ways, and come up with efficient (conceptually or physically) solutions.
More paradigms, please.
That’s why I think we need to focus on software architecture, architectural styles.
Nice to see the approach of thinking of the problem and how to resolve it, before hitting the keyboard. :)
Source or it didn’t happen.
I worked in much the same way using COBOL.
Great article. Do you think “shut and code” is a good approach to programming?
Very well written take on the world of programming.
I have noticed this, too: that it’s more interesting, and more useful, to learn radically different languages, than it is to learn similar ones.
Thus, C++, Java, Modula-2, Pascal, Perl, Python, PHP, Go, etc: all variations of the same theme, albeit some have better syntax (and less busywork) than others.
Forth, Lisp, J, Smalltalk, Haskell, Erlang, Prolog, SQL, or even Assembler? This is the stuff that bends minds! I don’t always fall in love with such languages, but I always appreciate them!
I liked the statement “Shut up code”. I am a programmer needed to hear that. Thank you verymuch.
I agree entirely…. the programming paradigm class I took for my CS degree was by far one of my most interesting classes due to the way in which it taught me to think about programming as an abstract discipline. It allowed me to think about software from a higher level where it no longer matters which “model” as you described I am using to construct a solution for a problem.
Over the summer I did research about web development and the different approaches of different “frameworks” to solving the same problems. What I found was that there was an underlying set of paradigms that were partially to fully implemented by the different frameworks. Learning these frameworks opened up a new way to attain knowledge in the field due to my newly found ability to cluster methods from different frameworks based on their respective paradigm.
Paradigms. Paradigms. Paradigms.
excuse the rant…
enjoyed your article
Feels a little silly to say that there is no value in “collecting languages”. I have also used more then I could count at this point but each language fits a specific niche even if it wasn’t built for it. And while many languages do share some ideas and syntax; there can be infinite different interpretations of these ideas. Object oriented programming is one paradigm where many languages have implemented the same ideas but in different ways. That is to say that the model for oop in java is different from how it is in JavaScript or c# or dart or kotlin etc. The same goes for the functional paradigm, scheme and clojure have vastly different implementations of the same ideas despite them being lisps.
There is nothing wrong with being language agnostic (I am so myself), but its also wrong to just completely discount a potential way of doing things that might ultimately be more productive.
Great position! I think I agree. Lambda Calculi, Turing Machines, Register Machines, State Machines, Network Graphs… The more the merrier! I would say some languages have built into them a strong aesthetic and practical leaning towards one or other paradigm. E.g. functional languages which can be fundamentally different from procedural ones. But this really boils down to the underlying model these languages are expressing.
One nit. You have your quantifiers the wrong way in this: ‘there exists a p drawn from the set of People such that for any a drawn from the set of Articles, p is the principal author of a’. This says there is a person who is the principal author of everything! You want ‘for any a drawn from the set of Articles, there exists a p drawn from the set of People such that p is the principal author of a.’
I assure you it doesn’t feel silly to say that. I said it.
as many people in the past have said, there are denotational semantics..and there are operational semantics
Great article. I can agree entirely with you since I have got the same conclusion – to applicate certain models to solve a problem as software solution – from a psychology point of view (for example, the Cognition model and its software implementation in the field of Machine Learning).
Thanks for the correction, I’ve updated my post.
I agree that programming languages ‘naturally’ support a paradigm over others, and that this is largely a matter of aesthetics. Smalltalk has closures as first-class data types but tends to be used for OOP rather than functional programming (and what is an object other than a function that maps messages to method invocations?)