I’ve tried looking on google but can’t get the answer I want to this. Is there a book or article or a video where various commonalities of different popular high level languages like Python, Java, C++ etc. are contrasted with each other ?
By commonalities I mean:
If you learned something in one language is it true for the other ?
The overarching ideas and approach to programming
I would like to find as many similarities as possible because I think that would make my life easier.
There are, of course, syntactic similarities between programming languages. E.g. most languages in the Lisp family use (some variation of) S-expressions. Many languages borrow B’s convention of delimiting blocks with curly braces. (Although other languages borrow Algol’s convention of using keywords.) Objective-C borrows Smalltalk’s syntax for message sending and blocks. Java borrows heavily from C, Pascal, and to a lesser extent C++. C♯ borrows heavily from C++ and to a lesser extent Java. The syntax of almost all modern functional languages can be traced back to SASL. Haskell’s offside rule comes from ISWIM. And so on and so forth.
But those syntactic similarities are boring. Syntax is probably the least interesting part of a programming language. If you don’t like it, you can pretty easily write a simple preprocessor … or just get used to it. For example, Vala and Genie are essentially the same language, but with very different syntaxes (Vala’s is heavily based on C♯, Genie’s is heavily based on Python, yet the languages are so similar that they actually use the same compiler, just with different parsers.) OTOH, Cobra’s syntax is heavily based on Python’s, but the two languages couldn’t be more different.
The interesting parts are the semantics and the type system.
Programming language semantics usually support one or more Programming Paradigms. Peter van Roy has made a nice poster with the 34 most important Programming Paradigms:
- active object programming / object-capability programming
- ADT functional programming
- ADT imperative programming
- concurrent constraint programming
- concurrent object-oriented programming / shared-state concurrent programming
- constraint (logic) programming
- continuation programming
- descriptive declarative programming
- deterministic logic programming
- event-loop programming
- first-oder functional programming
- functional programming
- functional reactive programming (FRP) / weak synchronous programming
- imperative programming
- imperative search programming
- lazy concurrent constraint programming
- lazy dataflow programming / lazy declarative concurrent programming
- lazy functional programming
- monotonic dataflow programming / declarative concurrent programming
- multi-agent dataflow programming
- multi-agent programming / message-passing concurrent programming
- nonmonotonic dataflow programming / concurrent logic programming
- relational & logic programming
- sequential object-oriented programming / stateful functional programming
- software-transactional memory (STM)
- strong synchronous programming
Paradigms, in turn, are composed of Programming Concepts. E.g. sequential object-oriented programming is composed of record, closure, cell, and procedure. If you add thread, you get concurrent OO programming. The most important concepts are:
- by-need synchronization
- cell (state)
- instantaneous computation
- local cell (private state)
- name (unforgeable constant)
- nondeterministic choice
- port (channel)
- single assignment
- synchronization on partial termination
- unification (equality)
Equally important as the language semantics is its Type System. Unfortunately, I don’t know of any similarly informative visualization of the different aspects of type systems. I am also not intimately familiar with Type Theory, unfortunately. (If you want to understand type systems, you should read Benjamin Pierce’s Types and Programming Languages.)
Some of the important aspects are:
- dynamic vs. static typing, also gradual typing, optional typing, soft typing
- latent vs. manifest typing
- implicit vs. explicit typing
- structural vs. nominal vs. duck typing
- strong vs. weak typing
- parametric polymorphism (also higher-rank and higher-kinded), ad-hoc polymorphism, inclusion polymorphism, bounded polymorphism, subtype polymorphism
- at the intersection of subtyping and parametric polymorphism: covariance, contravariance, invariance
- System F, System Fω, System F<:, System Fω<:, and its various extensions, variants, subsets, and derivatives, including Damas-Hindley-Milner, but also type systems that move away from System F (e.g. the Dependent Object Type Calculus underlying Scala’s Type System)
- the Barendregt Lambda Cube
- various forms of Type Inference, including Algorithm W, Flow-based, unification-based, etc.
- Dependent Typing, Linear Types, Ownership Types, Effect Types, World Types
And probably many other things I forgot.
Of course, there are really only two overarching ideas in programming, and all the different design choices in different languages represent different views on how to achieve these two things: