Home > Articles > Programming

The Benefits of Learning Multiple Programming Languages

David Chisnall discusses the importance of learning more than one programming language. He explains that it doesn't matter whether you actually use the language that taught you the concepts; that experience gives you a much wider set of tools to apply to whatever language you use.
Like this article? We recommend

I've recently heard several people remark that the differences between programming languages are "just syntax." In a sense, this is true. The Church-Turing thesis tells us that any programming language that can implement the Lambda calculus or a Turing Machine simulator can implement any algorithm.

To understand why this is meaningless, one needs only look at the esoteric language Malbodge: Although some derivatives are Turing-complete, it took two years for anyone to write a working program in the language.

For a less esoteric example, you can look in the programmers' manual for the STANTEC ZEBRA, a machine released in 1958. It included a restricted version of its instruction set that was easier to program, with a caveat that it could be used only for programs that had fewer than 150 instructions. The manual helpfully informed readers that this wasn't a serious limitation because no one could write a working program so complex.

This is obviously not the case for most modern programming languages. In fact, writing a program that compiles to fewer than 150 instructions is something of a challenge. Different programming languages teach very different ways of thinking about problems. Some programmers learn one language and then write in any other language as if they were using their first language. These are the sorts of people who are likely to tell you that different languages are "just syntax."

The Level of Languages

It's traditional to refer to a programming language as being on a spectrum from a high-level language to a low-level language. I still believe that this is important because without a grounding in computer architecture it's very easy to forget that some constructs in a high-level language are easy to generate efficient code for-and others are not.

Today, however, the idea of a single low-level language doesn't make as much sense as it did even five years ago. A modern mobile phone has somewhere between one and eight ARM CPU cores. It has a GPU, with a very different execution and memory model, which executes somewhere up to 256 threads using a very different parallelism model in which groups of threads proceed in lockstep. It typically has a DSP that can do stream processing very quickly. And it may have some other specialized processors.


Don't Miss These Related Articles Also by David Chisnall

Learn more about David Chisnall


There is no single low-level language. A high-level language is one that is close to how a human would express the problem (albeit often for a somewhat peculiar definition of human, which is not representative outside of most university mathematics departments), whereas a low-level language is one that is close to how a machine operates.

I've argued before that everyone should learn at least one low-level programming language so that they will think about efficiency when writing code in a high-level language that has an abstract machine model that cleanly maps individually to all of these, let alone to the entire system.

This means that it's worth learning C, but it's also worth learning some related languages, such as OpenCL C or GLSL. Increasingly, general-purpose compilers are aiming to target GPUs, so being able to structure loops or map operations in a way that is amenable to this kind of autoparallelism can result in huge performance (and power usage) improvements.

At the opposite end of the spectrum, high-level languages are also very different. The definition of a high-level language has always been somewhat fluid. When I was learning to program, a high-level language meant any language that was not an assembly language, and the book from which I learned C spent a lot of the first chapter explaining that a high-level language like C could be as fast to execute as assembly but had advantages in terms of portability and maintainability. Now people would look at you very strangely if you described C as a high-level language.

So what is a high-level language today? Modern object-oriented or functional languages such as Java or Haskell are a long way away from how the computer works, although it's debatable whether they are close to how humans work. Going past them, there are domain-specific languages.

Perhaps the most well-known is the Structured Query Language (SQL), which (as its name would suggest) is designed for composing queries on structured data and would be a wholly inappropriate language for general-purpose programming.

Domain-specific languages are everywhere. Programs like awk provide domain-specific languages for record-oriented text processing. PostScript is a domain-specific language for rendering vector graphics, and although PostScript itself is increasingly rare, a number of its derivatives survive. PDF uses the core of PostScript (without the flow control) as the base for its rendering model, and the OS X drawing APIs (and Cairo on other UNIX-like platforms) provide APIs that have direct mappings to the PostScript drawing state.

The canvas tag in a modern web browser has an API that was proposed by Apple and is effectively a lightweight JavaScript binding to Apple's CoreGraphics, which in turn implements the PostScript drawing model.

Again, although PostScript would make a terrible choice as a general-purpose programming language, that hasn't stopped people from trying. Sun's NeWS system used PostScript for rendering and allowed entire view objects to be written in PostScript. This made it much more responsive for remote display than X11, because when you clicked on a button it would draw the pressed state immediately while asynchronously sending the button-pressed event to the rest of the program.

NeXT also used a variant of PostScript (Display PostScript) for rendering, but developers usually just generated PostScript commands from another language.

Thinking in Abstractions

With such a plethora of high-level and domain-specific languages, it's usually fairly easy to find one that is close to the expression of the problem. Unfortunately, in the real world there are other constraints that often mean that you can't use the language that makes the implementation easier.

These constraints can be related to performance or deployment. For example, a language like Python or Ruby may be quick to write in, but might not run the resulting code quickly enough. If you have the resources of a company like Facebook, you can write your own compiler to make your existing code faster, but that's not usually an option.

Alternatively, your language of choice may not support your target platform. For example, trying to ship a Java application for Microsoft or Apple's mobile platforms is not usually possible.

That doesn't make it a waste of time, however. It's often a good idea to prototype in another language. This has several advantages. If the language that you're prototyping in is not usable for deployment, it prevents the prototype (which may have some poor design decisions and be unmaintainable code) from being pressed into service by management. It also means that you are free to make any experimental choices you want, knowing that you won't have to live with them if they don't work.

More importantly, creating a prototype allows you to structure your thoughts about what the design should look like. For more-experienced programmers, actually creating the prototype is not always an essential part of this process.

Having identified a language in which the problem can be expressed naturally, I often spend some time considering how I would implement the program in that language and then how the constructs that I would use would map to the language that I am using. The end result is code that solves the problem and is easy to restructure when I revisit it a few years later.

It's possible to write C, or even assembly, in a style that mimics an object-oriented language, with fine-grained encapsulation and independent parts accessible only via well-defined interfaces. It's much harder to do this if you've never used a language where these ideas are exposed syntactically and enforced by the language model.

Models of Parallelism

One of the most obvious differences between languages on modern hardware is how they expose parallelism. This is increasingly important, for two reasons. For the purely performance minded, single-threaded execution speeds have not become much faster for quite a while. In the '90s, you could expect your single-threaded program to roughly double in speed if you replaced your year-old computer with a new one. Now, you'd be lucky to get a 20% speedup (unless it's I/O bound and you replace a hard disk with an SSD). Very little code these days is actually CPU-bound, so this isn't a huge problem, but increasingly power consumption matters.

All other things being equal, a single CPU core running at 1GHz will consume more power than two running at 500MHz. If you have perfectly written parallel code without any contention, it will run at about the same speed on both. If it's running on a mobile device, this translates to longer battery life. More importantly, it gives the operating system more opportunity to adapt. A four-threaded program with work distributed evenly among the threads can be scheduled on one, two, or four cores, depending on which makes more sense for the current device conditions.

I've already mentioned GPUs. They have a very different programming model from more traditional SMP systems because there is a significant performance penalty if the threads diverge (or, indeed, need to communicate). On the CPU side, there are a lot of models that are worth learning.

Go and Erlang both provide primitives built into the language for communication. Somewhat confusingly, Erlang uses the syntax from Hoare's Communicating Sequential Processes (CSP) formalism but provides actor-model concurrency, whereas Go provides CSP semantics but its own syntax.

Both the actor model and CSP are shared-nothing models (although Go's implementation relaxes this). The cardinal rule for writing scalable and maintainable parallel code is that no object should be both aliased between threads and mutable. This is enforced by Erlang, which provides a single mutable object per process (the process dictionary) and makes everything else immutable.

Some Π-calculus extensions to Haskell do the same. In Go, you must enforce this yourself, although the language does make it quite easy and provides design patterns such as "share memory by communicating" that make it easy.

In C, you have a shared-everything model of parallelism and no explicit mechanisms for sending messages between thread (or, until recently, of creating threads without extensions such as POSIX or Win32). All that you have is some fundamental building blocks for creating and synchronizing threads. You can build Erlang-style message passing or Go-style channels on top of them.

Learning either of these languages and writing some code in it gives you the mental building blocks to use the same ideas elsewhere. This applies to a great many other aspects of a language. It doesn't matter whether you actually use the language that taught you the concepts; that experience gives you a much wider set of tools to apply to whatever language you happen to find yourself using.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020