This post was originally written while I was at LShift / Oliver Wyman
I’ve come to the conclusion that the terms like “programming”, “coding” etc. have become horribly ambiguous which has enabled:
- organisations to offer courses on html/css editing as “coding”
- people to make claims like “nodejs is more productive than java” (which is a nonsense statement either way)
- various arguments along the lines of “is X a PROPER programming language”.
I think it’s more helpful to think in terms of “scripting” vs. “engineering”:
- Scripting is geared towards the short-term, small team or solo, quick prototyping.
- Engineering is geared towards the long-term, larger teams, maintainability(i.e. readability), refactorability and extensibility.
It’s probably impossible to agree on whether a language is “scripting” or “engineering”, but obviously I have personal opinions about some characteristics of each:
- In the long term, the time taken writing software is 90% reading what’s already there. Languages that don’t support readability (or IDE analysis support) fall towards the Scripting end. IMHO the reason nodejs has encouraged microservices is because nodejs is quickly unreadable – you don’t extend a nodejs app, you just write another service…
- Monkey-patching automatically precludes a language from Engineering (it violates the Principle of Least Surprise) – how can anyone reason about code that can extend an object’s methods at runtime?
- Static-typing moves the language towards Engineering by increasing correctness and readability. Completely pathological strict typing languages like Haskell may be a learning barrier though (along with Haskell programmers’ irresistible temptation to use punctuation as function names it seems – quick, quick, tell me what the difference is between foldl and foldl’)
- If the language has static typing then good type inference cuts down on the boilerplate. These days I wouldn’t write any Java without using lombok.
- Immutable objects are good Engineering. Likewise functional languages can aid Engineering, except that the temptation towards one-line-itis reduces readability.
- Encapsulation and clear techniques for Dependency Injection help Engineering as it supports mocking in unit tests.
- Automatic resource management aids Engineering.
So I can possibly come up with a completely unscientific and arrogantly self-opinionated table of languages: 5 is good, 0 is bad (if the square is blank then I haven’t formed an opinion):
|Readability||Least surprise||Static types||Type inference||Immutable Functional||DI Mocking||Resource Management|
|Java with lombok||4||4||4||3||2||5||31|
|Python with Coconut||5|
|Bash (just for fun)||4||38||0||0||0||0||49|
- “try” with resources
- inline Union types look interesting
- things get turned into null at the drop of a hat
- everything is in a global namespace
- annotations for run-time checking
- space handling in values
- all resources are in pipes
Scripting vs. Engineering databases
I think we can extend this to databases too. The NoSQL/schema-less fashion of databases are definitely up the scripting end:
“The problem is that in the absence of a formal schema, the “schema” is an emergent property which is reflected in the code used to manipulate the database” – comment in Why You Should Never Use MongoDB
Responses to “static typing is bad / gets in the way”
The post “Static vs. Dynamic” Is the Wrong Question for Working Programmers, in the section"static typing benefits”, makes the correct statement “Proof that certain kinds of dynamic errors are impossible” but I’d maintain the suggested “drawbacks” are incorrect:
- Increased verbosity or reduced expressiveness – not true if the language has good type inference, and type annotations improve readability immensely.
- Rejection of otherwise correct programs – how can a program be correct if it has a type error? See how an uninitialised variable cost $90,000.
- Slower programmer iteration (possibly lengthy compile/run cycles) – IDE integration and incremental builds removes this completely
- A need for the developer to learn “static typing” language feature – I’d suggest that if you really know what your program is doing then you do know about types (unless you’re programming in the Stringly style)
Reading through some python documentation blogs and this paragraph caught my eye:
If you’re coding in Haskell the compiler’s got your back. If you’re coding in Java the compiler will usually lend a helping hand. But if you’re coding in a dynamic language like Python or Ruby you’re on your own: you don’t have a compiler to catch bugs for you. – https://codewithoutrules.com/2016/10/19/pylint/
And that’s why I like types (which can be added in python)