"You should not have a favorite weapon. To become over-familiar with one weapon is as much a fault as not knowing it sufficiently well."
- Miyamoto Musashi
Recently, I completed the Programming Languages Part A, Part B, and Part C MOOCs, which provided me with a valuable perspective on programming languages. This blog post serves as a course review and an exploration of my stance on the idea of having a favorite programming language.
Key Ideas Explored in the Courses
Throughout the course, I delved into fundamental programming language concepts with a strong emphasis on functional programming in parts A and B. Part C focuses on Object-Oriented Programming and how they both are similar and different.
- Functional programming concepts, including closures, lexical scoping, recursion, currying, and type inference
Dynamic typing using Racket and covered topics such as thunking, lazy evaluation, streams, and memoization
The distinction between compiled and interpreted languages, emphasizes that this categorization pertains to language implementation, not the language specification.
(Developed an interpreter as part of the course assignments)
Static checking, correctness (soundness and completeness), and weak typing.
Ruby as a dynamic language and object-oriented programming (OOP) concepts within this context
Subclassing, polymorphism, double dispatch, mixins, interfaces, and abstract methods
Insights and Paradigm Shift
Completing the course led to a significant paradigm shift in my perception of programming languages. I realized that each language possesses its unique strengths and weaknesses, making them more suitable for specific problem domains. Having a favorite programming language often blinds us to the possibility of finding more elegant and efficient solutions in other languages. This notion was exemplified by the course itself, which utilized three different languages to teach appropriate concepts for each.
The ultimate goal of programming is to develop software solutions efficiently and effectively. To achieve this, it is crucial to select the right tools that align with the objective at hand. The course enabled me to transcend language-specific syntax and focus on program design, gaining a broader understanding of various concepts employed by different languages. This newfound perspective allows me to approach programming challenges agnostically, reasoning about design independently of specific languages. Additionally, I have discovered that with a strong foundation in programming concepts, learning new languages and frameworks becomes a manageable task.
Ask yourself these questions when learning a programming language:
Syntax: How do I write it?
Semantics: What is the meaning behind the syntax?
Idioms: What are typical patterns and best practices in the language?
Libraries: How to do specific things such as file access? In any language, there are things that one cannot do without library support.
Tools: What are the tools that make it easy/efficient to program in that language? Such as REPLs, debuggers, and code formatters etc. However, note that these tools are not inherently part of the language itself.
Embracing a language-agnostic approach to programming opens up a world of possibilities. By considering broader aspects of program design and leveraging concepts from various languages, developers can create efficient and elegant solutions. It is essential to remember that programming languages are tools at our disposal, and the choice of language should align with the problem.
Did you find this article valuable?
Support Rohit Mehta by becoming a sponsor. Any amount is appreciated!