One of the key decisions we programmers need to make when embarking on a project is to choose a language, or set of languages, to use to implement the system. This decision affects not only the implementation of the system, but also the design. For example, should we use an object-oriented language or a procedural language? What language we choose has a profound impact on the project and the life cycle of the program that is part of the project. Many times, we go for it without thinking too much based on some very fickle factors. Choose a language: This is the language I usually use to implement this type of system; this language I understand best; this is my favorite language and I enjoy programming in this language; etc.
Since this decision will lead to profound and long-term consequences, should we be more pragmatic when making this choice? Many times, we will be blindly biased by the language we choose. And, sometimes the reasons why we don't like choosing that language may be the very reasons why we choose that language.
If we can open up and be honest about our biases, we can alleviate some of the pain of trying to fit a square peg into a round hole when decorating. While there is no secret to choosing the perfect language for your project, there are some principles that can help us make a better, more appropriate language choice.
No Language Is Perfect
This is a given to anyone, even a newbie, and many of us are willing to admit, “Of course, this language It’s not a perfect language,” but at the same time, many of us would still say, “This language is the best programming language.” The key to saying a language is the best language for a project is the context of the project, that is, the best language only exists within a certain scope. This is our first principle:
There is no perfect language: every language has its advantages and disadvantages.
For example, many developers who typically use runtime languages such as Java or Python claim that C or C++ is breathless due to concerns about low-level details such as memory management, or Concern about strict granularity of compile-time type checking while stifling the responsibilities that are delegated to developers. This is true as long as the project we are developing does not focus on seemingly trivial tasks such as memory management or the number of copy-assignments that occur in a single loop.
In contrast, if we are working on a project, or part of a project, it is natural to have biased needs for how efficient the code should be and how critical and safe the program is, and these seemingly tedious details may be exactly what we are working on. The level of granularity to look for. In this new context, the runtime nature of Java or Python seems too uncaring or too absent-minded. Instead, we want to be able to strictly control how many move-assignments and copy-assignments are executed when memory is allocated and freed, and catch as many errors as possible at compile time, rather than letting errors leak into the runtime (behaving as runtime abnormal).
While in theory "no language is perfect" sounds obvious, our behavior as developers often departs from this concept: we say we know our favorite languages are imperfect , but we continue to use this language for the projects we develop, regardless of whether it is suitable. Furthermore, when another developer questions our choice of language, we vigorously defend our choice rather than see the truth in his or her rebuttal. Remember: every language has its pros and cons. Understand the strengths and weaknesses of the languages you master and then make your choice based on your situation.
The reason you don’t like a language may be the reason you should use it
It may seem counterintuitive, but sometimes, the reason we don’t like a language may be the reason you should use it. Some language reasons. Still with the above example, in my experience as a C++ developer, many times it takes too long to complete a project because there are so many different concepts to keep track of (memory management and object lifetime, the three principles of C++ programming, etc.) A simple function can become cumbersome. After a few weeks of developing in C++, using Python, Java or another "higher" language can feel like a godsend: but is it really so?
Sometimes, maybe The reasons we dislike a language are the very reasons we use it. If I were developing a driver or some safety-critical, real-time system, the reasons stated above for being cumbersome might just be the greatest advantage of this language. For example, C++ provides a mechanism for expressing logic that is executed when an object is copied, which is invaluable when efficiency and rigor are in order.
This may all look good and great, so it's hard to pinpoint a context in which a language you don't like might be more helpful. So, how do we know which languages you don’t like are helpful? This leads to our second principle:
Be honest with yourself: know why you don’t like a language, don’t Dogmatize your own hatred.
For example, in the C++ example above, the reason why I don’t like to program in C++ for a long time is because this language requires rigorous thinking, otherwise it is easy to make mistakes, just like being trapped in a jungle. (Too much focus on the trees rather than the forest as a whole). This rigor prevents developers from questioning things like, "Am I creating objects on the stack or on the heap, or partially on the stack and partially on the heap?" or "To make this class extensible, it should be through templates." Parameters or inheritance?" and other decisions. In other languages, developers can accomplish these tasks by simply creating an object each and using object-oriented inheritance, and then move on to the next feature because the language (or, more accurately, the compiler or interpreter) takes care of these tasks. detail.
But if I'm honest with myself, I will admit that the reason I don't like these features of C++ is because it puts the onus on me to express these details. In other languages, not only am I not responsible for these details, but I also don't have the responsibility to express them: they are abstracted away from the developer. In a context where these details are essential, the reasons I don't like C++ are exactly the reasons I should use this language.
Does this mean we should frown and use features that make us angry about the language? No need to. Maybe you can look at it another way: instead of seeing these features as drawbacks, maybe we should embrace them as necessities to get the job done. Instead of saying, “What a tragedy,” we should say, “Thank God I can do this in this language.” Remember: in some contexts, these capabilities will be a gift, and In other cases, they are a liability. Be honest with yourself about why you don't like a feature of a language.
The more familiar you are with other languages, the better
For this point, this is the third principle we want to say:
If the only tool you have is a hammer, then You see every problem looks like a nail.
This rule does not apply to software engineering, but it sharply illustrates many software development situations. Many times, we choose a language, or a language-supported tool (such as Java's JMS, Python's ASYNCIO, Rails' Ruby, etc.) because we know they exist. If the only language we are familiar with is Java, then we will adapt all the problems we encounter to the context of Java. For example, "I need to create a routing framework for a communications application. How do I do this in Java?" This limits the tools available to us and artificially limits our ability to choose the right tool for the job.
The solution to this problem is to expand your horizons and understand the capabilities and intricacies of other languages. As Andrew Hunt and David Thomas suggest in "The Pragmatic Programmer", a good practice is to learn a new language every year. It's not as easy as it sounds, and learning a language will mean different things to different people. Another derivative problem is that we often only use this one language for ongoing projects, making learning another language useless. For example, if I am an Android developer and basically only use Java every day, then learning C# may seem like an untimely waste of time.
Don’t be fooled by illusions. The advantage of learning another language is that we can see a problem from a different perspective and use the tools that are best suited to the problem. In order to do this, we have to learn the caveats associated with other languages and the way developers use those languages to solve problems. For example, if a developer wants to perform metaprogramming in C++, then he or she can use Template Metaprogramming (TMP) in C++, but he or she can also use reflection in Java. Understanding how other languages solve similar problems reduces the risk of us deeming it useless.
As another example, if we need to be able to change the runtime characteristics of a class, a C++ developer who is deeply familiar with the intricacies of C++ may try to make up a compile-time language that extends the boundaries of this class. s solution. And another C++ developer, because he also has a certain understanding of Java, can say, "I like C++, but Java's runtime reflection is better suited to solve this problem."
Because of this There are so many programming languages for developers to choose from that it is important to prioritize which languages to learn. You might as well start with the most popular languages today (please refer to "most popular languages on Github", "Language Trends on Github", "The 9 most popular computer languages", "according to the Facebook for programmers", etc.).
Language is a means rather than an end
This is the fourth and final principle. It may sound the most philosophical, but it can also be said to be the most important:
Programming languages are a means, not an end.
Unless you are the author of a language standard or a compiler, you should treat programming languages as a means rather than an end. The goal is to complete the project: the ultimate goal is to complete the project, and Not using a specific language. This doesn’t mean that every developer doesn’t have the right to demand what he or she likes or dislikes about the language (in fact, if we’re honest with ourselves, these likes and dislikes can work in our favor; see the second principle above) , but we shouldn't fool ourselves into making decisions like, "This is a great opportunity for me to use this feature of the language," unless the features of the language truly fit the needs of the project.
It’s important to remember that language is just a way of expressing how to solve the problem at hand: make sure you choose the language that best expresses the problem domain you are solving.
Other places to consider
The following are some additional considerations when we choose a language:
Consider how the language interacts with other languages. For example, if you decide that Python is the best language for most projects, but there is a well-defined component in your project that requires an extremely high level of granularity or efficiency (which would be better suited to C or C++), that doesn't mean You cannot use Python on this project. Instead, consider using Python, writing a specific component in C or C++, and then using the Python C API to interface to this component. Note that to formulate such a solution we need to know that Python has a C API; therefore, it is helpful to know these features of the most popular languages.
Middleware can allow the use of multiple languages. For example, if you have two applications that must communicate, such as a mobile device and a server application, this does not mean that they must use the same language (of course they can be the same if you decide that is the best decision ). If the mobile device is an Android phone, and the server application is perfectly suited as a Python application, then using a message broker such as RabbitMQ allows you to communicate using both languages at the same time: the Android application can use Java RabbitMQ API, while server applications can use Python RabbitMQ API.
Embrace the quirks of other languages. If you are a Java developer, then you will use packages to separate logical units of source code; if you are a Python developer, then you will use Python's package structure to do the same thing; if you are a C++ developer personnel, then you would use a namespace or prefix the class name (i.e. "DZone_MyClassName"). Understand the special features of the language you're speaking and embrace them: in Rome, do as the Romans do. Otherwise it would be like speaking German with an Italian accent because you prefer the Italian pronunciation of words, which would sound nondescript. Of course, it is also possible that a feature of a language has existed for a long time, but in this case, there must be a reason: make sure you understand the reason.