It is a cold night in a quaint town – the snow is falling from the heavens, resting on a jet-black road that is covered in ice. A passive observer cannot help but notice clouds of vapor floating through the street, enveloping the heads of two brothers who are excitedly making up for lost time; it is impossible to overlook their excitement. A shriek is heard in the distance and a frail-women sprints across the glossy surface toward the young men. She hugs them, uttering the words “I love you. Welcome home.”

The previous paragraph has nothing and everything to do with this piece. It depicts the story of two brothers catching up over lost time and a mother communicating her affinity for them both with the simple words “I love you.” Unfortunately, this story has reached its end before it even began, for the focus of this piece is not on the brothers or their excited mother. Rather, it is about language. Specifically, it is about the mechanics of communication, and how certain human (or programming) languages are more conducive for the expression, understanding, and execution of certain ideas than others.

A Tool for Comprehension

Language, at its simplest, is a way to encode information and transmit it from one entity to one another. The outset of the piece was meant to communicate a story to readers in the hope that it would engage them, sparking their interest in this piece. In addition to sparking interest, the literary sleight of hand used at the outset reveals the first pillar of what effective language enables: the characterization of phenomena. This thought is fundamental to the rest of this piece – languages with strong explanatory power facilitate understanding and expression. Having a strong command of language in its many forms enables you to illuminate complexities, enhance execution, create stories, define developments, or simply digest ideas because it empowers the art of explanation.

To illustrate how certain languages can increase understanding, I offer you a story. Weeks ago, I was working to fix a bug in some code with a coworker. The issue? A function was returning a value that was one less than the expected result (i.e. returning 99 instead of the correct result of 100). These types of bugs can be referred to as fencepost errors, and this phrase is an allusion to the following problem: how many poles does it take to cover one-hundred yards if each pole is placed ten yards apart? Hint: ten poles is not the correct answer. My coworker – who had never heard of the term fencepost error – proceeded to share his amusement with the English language upon learning the phrase. Indeed, “fencepost error” is extremely information-dense. It communicates that the problem at hand is of the “one-off” variety and pushes one to analyze areas of code where counting operations could be an issue. Thus, the information provided to us by the English language served to facilitate our understanding of the problem at hand.

The fencepost error story provides us with a simple example of how languages can facilitate understanding. But what if certain languages were superior to others for developing an understanding of certain topics? If the author were a more capable writer, he would express his pieces in different languages, communicating his thoughts with different context and nuance than is allowed by English alone. [1] Consequently, it may be the case that some ideas can be expressed more effectively by leveraging other languages, and that is precisely what research corroborates.

Stanislas Dehaene – a cognitive neuroscientist – has spent ample time studying the links among the brain, languages, and numeracy (among other topics). To borrow from Jim Holt’s coverage of Dehaene’s findings:

“Interestingly, the very symbols with which we write down the counting numbers bear the trace of [a sequence]. The first three Roman numerals, I, II, and III, were formed by using the symbol for one as many times as necessary; the symbol four, IV, is not so transparent… [Indeed], English is cumbersome. There are special words for the numbers from 11 to 19 and for the decades 20 to 90. This makes counting a challenge for English-speaking children… Chinese by contrast is simplicity itself; its number syntax perfectly mirrors the base-ten form of Arabic numerals… Consequently, the average Chinese four-year-old can count up to forty, whereas American children of the same age struggle to get to fifteen… Because Chinese numbers are so brief, they take less than a quarter of a second to say, on average, compared with a third of a second for English.”

If one naively extrapolates these results, they may expect Chinese speakers to have greater mathematical aptitude than their English-speaking counterparts. But arithmetic is only part of the story of mathematics, which just so happens to be a language itself.

The Language of Logic

For those who pursued, or will pursue, an education in higher levels mathematics, what becomes readily apparent is the transition that occurs from using numbers and algorithms to leveraging abstract reasoning and formal logic to prove, or disprove, a certain statement.

Mathematical proofs are filled with plots and subplots whereby each logical step takes the reader closer toward a resolution that crescendos at the moment when the logic underlying the proof becomes so absolute that it must be taken as truth within the system defining it. If proofs are the language of math, then reading them is essential to the development of mathematical intuition – one must first be able to read and write in a language before they can reason in it. But the language of math proves challenging for many because one is often never exposed to its logical framework until college. Consequently, many students are only taught to leverage the tools generated by math’s insights, failing to be exposed to the logical foundation that makes these relationships true.

For instance, recall in one of my previous pieces two students discussing how 1+1 could be 3 and not 2. If I wanted to convince them that this cannot be the case, I could show proof. [2] Indeed, to disprove this statement, I assert that:

These symbols are a language and serve to provide us with a map from a verbal language – in this case English – to a mathematical one. The statement above reads as:

For any integer x, x is odd if and only if x + 1 is even.

When I read the mathematical statement above, I convert the symbols into the English language. Indeed, there is some internal conversion that occurs in my brain’s CPU, and this conversion occurs each time I am presented with a new concept.

The difficulty of higher-level mathematics, then, resides in the fact that there is often no map between math and verbal language. Since there are no characterizations to be found in verbal languages for certain mathematical concepts, they tend to stay in the domain of math. Therefore, it is clear that math is a language predicated upon reasoning and logic. Its constructs having little to do with numeracy since numerical issues are rarely abstract – one is 1 in English. In essence, the map that exists between verbal language and mathematics only exists up to a point. Once you reach that point, verbal language cannot possibly explain what is happening – mathematics exists to create knowledge in a domain where verbal language falls short!

So mathematics exists precisely to create a framework for developing abstract concepts, providing users with the ability to reason logically and explain phenomena with irrefutable precision. Consequently, the best mathematicians are literary masters of the language of logic (a la Shakespeare), inventing new methods (theorems), creating new prose (developing a new method of proof), and generating new stories (advancing the field of mathematics).

While math is the language of logic and the abstract, that does not mean verbal language cannot serve to facilitate our understanding up to a point. Au contraire – I believe verbal languages that promote creativity, those that are very flexible with odd quirks, structure, conventions, and rules, better prepare individuals to leap into abstract fields like mathematics. [3] [4] Additionally, I assert that those with a fantastic command of one or multiple languages are better equipped to create maps between the abstractions that occur in domains like mathematics and the tangible realm of verbal language. If you can talk about it, think about it, read about it, and write about it in a verbal language, things become a heck of a lot easier.

Yet, creating this map becomes difficult to create as concepts become more abstract. Consider the mathematical concept of a symmetry group, which Wikipedia defines as:

The group of all transformations under which [the geometric] object is invariant, endowed with the group operation of composition. Such a transformation is an invertible mapping of the ambient space which takes the object to itself, and which preserves all the relevant structure of the object.

If you are thinking what I am thinking, it must be along the lines of holy ___ (this is left as an exercise to the reader). So here is another wonderful explanation by Jim Holt, with some personal additions, to make this abstract concept more concrete at the expense of some rigor:

“An important kind of group is a symmetry group. Suppose you have a square card sitting in the middle of a room. Intuitively, this piece of furniture is symmetrical in certain ways… if you rotate the table about its center by about 90 degrees its appearance will be unchanged… Groups are thus a way of measuring the symmetry of an object: a circular table, with its infinite symmetry group, is more symmetrical than a square table, whose symmetry group contains just four actions (90, 180, 270, and 360 degree rotations).”

Thus, we have established a link between the language of mathematics and the English language through analogy. Since it becomes increasingly challenging to define abstract concepts, users of verbal languages must create inventive ways to make abstract concepts more tangible. Thus, the only way to map challenging abstract ideas to a verbal language is to enhance your ability to characterize these ideas in the language of your choice. There will be times when mapping the language of math to another language is not possible, but I am certain that possessing a strong command of language helps one’s progression in more abstract domains. The more tools you have available for characterizing concepts, and the more maps you create, the more concrete abstract concepts become. Over time, your understanding of these abstract ideas will improve, and you may reach a point when you no longer need to rely on verbal language to internalize these concepts. Indeed, you can reside in the language of logic (math), leveraging its power to uncover patterns in the playful manner it was designed for. [5]

Unfortunately, few are currently familiar with the language of math because it is not presented in a playful manner. Instead, students are forced to memorize formulae, rarely discovering these formulae themselves. To illustrate the playful discovery process that occurs in the language of logic, consider a proposed path for discovering a triangle’s area formula from Paul Lockhart’s A Mathematician’s Lament:

For example, if I’m in the mood to think about shapes— and I often am— I might imagine a triangle inside a rectangular box.

If I chop the rectangle into two pieces like this, I can see that each piece is cut diagonally in half by the sides of the triangle.  So there is just as much space inside the triangle as outside. That means that the triangle must take up exactly half the box! This is what a piece of mathematics looks and feels like.  That little narrative is an example of the mathematician’s art: asking simple and elegant questions about our imaginary creations, and crafting satisfying and beautiful explanations. There is really nothing else quite like this realm of pure idea; it’s fascinating, it’s fun, and it’s free!

This is the language of logic: a harmless question is asked, a diagram is drawn, and a simple yet convincing observation is made that leads us to the following conclusion:

If we truly want to motivate individuals to study math, we must spark their curiosity about its playful nature. If the motivation is there, they will be sucked into learning the rest of the language – this is equivalent to the sleight of hand I used at the outset of this piece. Additionally, individuals accustomed to the language of math develop unique reasoning skills as languages with strong explanatory power facilitate understanding and expression, and different languages are more conducive for certain forms of thinking and expression.
QED.

Hello, world!

This piece would not be complete without a discussion of languages that have formed recently in the scope of human history. These languages support the website you are reading this piece on, the smartphones we use every day, and underpin an increasingly large portion of the global economic landscape, especially as our virtual migration accelerates. I am, of course, referring to programming languages, and they have – and will continue to – change the world as we know it.
It is a fait accompli.

Programming languages are unique for a multitude of reasons, but a characteristic that immediately separates them from the languages previously discussed is that they provide humans with a method to communicate with machines. While there is undoubtedly a human component to writing good code – it should be understood by other developers working in a library – code is simply a way for humans to provide explicit instructions to a computing system. There are times when these instructions cannot be understood by a computer’s compiler before a program is run, resulting in a compile-time error. And then there are other times when a program compiles and begins to execute, but somewhere along the way, an unexpected result occurs causing a runtime error.

To avoid compile-time and runtime errors, engineers must become familiar with the syntax of a programming language in addition to certain programming concepts. Once basic syntax is understood, a human can begin writing code that compiles and runs without error, with a novice programmer’s first piece of compile code typically taking the form of “Hello, world!” There is an incredible number of programming languages in existence today, but this piece will focus on two, namely Python and C++, for these are the languages the author is most familiar with.

Python is a high-level language that reads like pseudocode, or code that is meant to be read by other humans. It almost feels like writing English and is convenient for novice programmers to learn because of its syntax. However, for engineers looking to optimize machine resources, gain more control over memory allocation, or enhance performance with respect to speed, Python can be a poor choice as these lower-level considerations are hidden from its users to enhance its readability.

Conversely, C++ offers developers tremendous control over a library’s lower level details. The language is syntactically challenging, but it enables engineers to implement concepts that are not supported by Python. Effective C++ development involves higher levels of abstraction as a result – its ability to provide engineers with more control over a computer’s resources demands an understanding of programming concepts that are generally more challenging than those found in Python.

To show a simple example of the syntactic differences across these two languages, consider the code snippets below – these functions achieve roughly the same goal but are accomplished in entirely different ways. The C++ code example below is taken from Eli Bendersky’s fantastic blog, and I have created my own Python analog:

First, let us dissect the Python function. Python’s adder function takes advantage of iteration; “for arg in args” behaves the way it sounds. Indeed, for each argument in the provided arguments, the function adds the argument to the result. When all the arguments have been visited, the result is returned. Notice how adder can take any amount of strings or numbers (meaning integers and floats) – that is the magic of using *args in the function signature! Thus, our familiarity with Python’s syntax enables us to take advantage of an operation that a novice would have no notion of – we are able to communicate to a machine in a much more succinct fashion and simultaneously create a function that is flexible. In a departure from verbal and mathematical language, having a strong understanding of language facilitates expression. However, note that there is an issue with this function: in the event that an argument type other than numbers or strings is passed into adder, or if the arguments are a mixture of numbers and strings, the Python adder function will encounter a runtime error.

Suppose I did not like the notion that the Python function was not all-encompassing – indeed, we know it will error in the two cases mentioned above, and perhaps under other cases. Then we can resort to the C++ analog, which leverages the concepts of function and template parameter packs. I will let the talented Eli Berndesky explain first and provide more exposition after (feel free to skip this blurb, it may be more technical than some readers care for):

adder will accept any number of arguments, and will compile properly as long as it can apply the + operator to them. This checking is done by the compiler, at compile time.

typename… Args is called a template parameter pack, and Args… args is called a function parameter pack (Args is, of course, a completely arbitrary name and could be anything else). Variadic templates are written just the way you’d write recursive code – you need a base case (the adder(T v) declaration above) and a general case which “recurses”. The recursion itself happens in the call adder(args…). Note how the general adder is defined – the first argument is peeled off the template parameter pack into type T (and accordingly, argument first). So with each call, the parameter pack gets shorter by one parameter. Eventually, the base case is encountered.”

Unlike our Python function, the C++ adder leverages recursion. Every argument passed into adder is mapped down to the base version of the adder function (the first adder(T v) you see in the C++ code above), and eventually, we arrive at our solution. Additionally, notice the template<Typename T> that rests above the adder call – since C++ is more explicit than Python, this is a method for creating generic C++ return types. template<Typename T> means adder can return any type as long as the plus operator (+) is defined for those arguments. In the event the arguments do not have a plus operator, we will encounter a compile-time error. Thus, the C++ function differs from its Python analog because it leverages recursion and will fail to compile if the arguments do not have a plus operator.

Consequently, the C++ function should be used if we want to design a function that can error at compile time instead of runtime and want to ensure that it works for every argument type that has a defined plus operator. However, it took an intimate understanding of C++ syntax, and an understanding of concepts like parameter packs and recursion, to generate the C++ version of the adder function. Preferences for erroring at compile time and runtime differ based on an engineer’s goals, but if one decides to create functions that error at compile-time, you can be extremely confident your code will work in the event it compiles. Once again, different languages are more conducive to certain forms of thinking and expression.

Programming languages, therefore, rest at the intersection of verbal languages and the language of math. Languages like C++ require a thorough understanding of syntax and knowledge of certain concepts to write effectively, whereas novices in Python can still write functional code by leveraging their understanding of verbal language and basic reasoning skills. Familiarity with Python’s intricacies goes a long way, but the marginal returns of increasing one’s familiarity with the capabilities of C++ are larger than those to be gained from Python (in this author’s humble opinion). In any event, developing one’s ability to think logically, express ideas in a reasonable fashion, and think creatively, are all conducive to becoming a more effective, writer, mathematician, developer, and critical thinker.

The Trifecta

Astute readers may have caught on to something in the last discussion. I was able to describe the Python and C++ code verbally in the succeeding paragraphs, creating yet another map – a map between verbal and programming languages. My hope is that readers who have never read a line of Python or C++ feel comfortable with the code that was provided. If that is the case, our ability to characterize concepts in verbal language has once again made the abstract feel more concrete! Additionally, some extremely astute readers may have noticed the map that was created between the language of math and programming languages – indeed the concept of recursion that appeared in C++ has its roots in mathematics! [6] Thus, we have developed the following Trifecta – three forms of language each serving to reinforce comprehension in one another:

Creating this image, which depicts the intersection of verbal, mathematical, and programming languages, manifested many thoughts I have had swimming through my head for some time now. When I write, I find that my pieces have a logical progression to them; I believe this structure exists due to my mathematics background. In effect, my education in mathematics impacts my prose as I strive to thread ideas together in a logical fashion, while my vocabulary serves to enhance my ability to characterize difficult mathematical concepts. Additionally, my familiarity with English helps me digest concepts I have not seen in programming languages, while my background in mathematics supports my pursuit to write code that is logically consistent, concise, and elegant.

It is not always obvious how you can refine a skill set. Aptitude can be hidden in areas one fails to appreciate. A mathematician may scoff at literature, a writer may belittle code due to its lack of creativity, and a programmer may question mathematics due to its lack of practicality. But failing to appreciate what different languages have to offer means sacrificing your ability to make meaningful progress in these seemingly unrelated areas. Advancement in one language means a step in the other – the transmission of knowledge that occurs among verbal, mathematical, and programming languages is undeniable. Given this knowledge, the question then becomes: what insights are waiting to be uncovered?


[1] There are approximately 6,500 known human languages today, many of them dwindling away. In fact, the website I obtained this information from is named after a language spoken by eight people. We are sadly witnessing the extinction of communication methods. This convergence toward popular forms of communication affects the versatility of human expression – certain ideas may literally be lost in translation.

[2] If you are not entirely convinced that 1+1 cannot be 3, please see the proof below:

[3] Perhaps the author does speak multiple languages.

[4] Lewis Carroll would be the champion of this claim.

[5] For the curious reader, I highly recommend reading Paul Lockhart’s A Mathematician’s Lament which is an essay referenced in this piece. Mathematics is a field of discovery and should promote a feeling of wonder. Instead, high school students are often offered formulas without context, destroying the most captivating part of mathematical thinking: independent thought and discovery.

[6] http://www.people.cs.uchicago.edu/~soare/History/compute.pdf

4 comments

  1. Drew Mouacdie

    Great piece. As someone who wrote his first macro in VBA last night, you have more than piqued my interest in the possibilities of expanding the creative process into realms unbeknownst to me, namely C++ and Python (I read the first command Def adder and thought of a venomous Australian snake). Thank you for your efforts in explaining these languages, attempting to corral their meanings for the lesser quantitative mind as well as explaining language logically. That first paragraph read like an instructional manual with the literary tact of a novel.

    • admin

      Drew, thanks for taking the time to read it! Truly hope it was helpful — if you want to get into displacing VBA with Python (I am sure this is down the line on your journey), check out the following: https://www.python-excel.org. PyXLL is definitely the friendliest of the bunch, but it is not free, unfortunately.

  2. Felipe

    Bravo, great piece. A little side note:

    “`
    def adder(first, *args):
    for arg in args:
    first += arg
    return first
    “`

    • admin

      Felipe, thanks for the feedback. It is fantastic when I learn from those who read my pieces… Even more elegant!

Comments are closed.