The Infinite Zenith

Where insights on anime, games and life converge

Tag Archives: Software

Controversed: Moyatori’s November Workshop (Part II), Remarks on Style, and A Case Study Using Operator Precedence

“The thing I hate about an argument is that it always interrupts a discussion.” –G.K. Chesterton

We continue with Moyatori’s Controversed programme, and this time around, I am actually on time for once. This week’s prompt deals with the non-trivial matter of how I approach controversy, whether or not my style is conducive for discussing polarising topics, and how I strike a balance between being clear and reaching the depths needed to adequately cover a topic. In a curious bit of coincidence, I will be able to do a live demonstrate the approach I take for this week’s Controversed, which is exciting: a few evenings ago, order of precedence, the order in which arithmetic expressions are evaluated based on the operands, began trending on Twitter after a user submitted the expression “6 ÷ 2 (1 + 2)” and claimed that such an expression was unsolvable on account of ambiguity. In this post, I will step through a justification of the answer, approach it from a computer science perspective and explore the problem in Moyatori’s context to reflect on how my experience, and style, impacts the way I solve problems (and by extension, how I deal with controversial topics). The aim of this exercise is to give readers a sense of how I ensure my posts can cover the details that I aim to, while simultaneously remain accessible for readers from a range of backgrounds. In today’s discussion, the versatility of my style will be put to the test as I strive to explain why the approach I have taken towards solving the semi-viral expression is appropriate.

  • This post is a little long, so for Moyatori’s Controversed, I’ll answer the questions here, elevator-pitch style, for visibility:
    1. I write very nearly the same way I used for for my journal publications and thesis paper. My blogging voice varies: in paragraphs, I aim to be neutral and stick to what I see in a given work. In the figure captions, I have a little more fun and speak more casually.
    2. My bias depends on what I’m writing for. If I’m writing about anime, I’m going to be biased: my goal is to have fun, and therefore, I tend to accentuate the positives. I’ll still try to explore all sides of the arguments where possible and mention any merits they may have.
    3. My approach in 2) ensures I cover both sides, although I will spend more time presenting evidence for the side I am on. With this being said, I have changed perspectives as I do more reading before; a well-written piece can and has persuaded me to see other perspectives previously.
    4. I use visuals and lean heavily on my screenshots/figure captions to help me out. Words alone are dense and can be very dry, but captioning a picture can help people gauge my reaction to something more readily.
  • With the prompts answered for folks in a hurry, I can almost delve into an example of how I handle controversy. Before I do, I would like to extend a special thanks to Rose of Wretched and Divine and Nabe-chan of Geek Nabe for encouraging me to do something a little more exciting, and fun, for this post.

The Matter of Order

In mathematics, operator precedence (or order of operations) is a method used to determine which operands are carried out first in a given expression. Such rules exist precisely to eliminate ambiguity: broadly speaking, mathematics is a discipline that deals in quantity, structure, space and change. To ensure consistency, students are taught a set of rules to help them compute the value of an expression earlier in their education: brackets are calculated first, followed by exponents, and then multiplication or division follow, with subtraction and addition last. This is a relatively simple rule set that ensures students understand operator precedence, and in the case of carrying out order of operations, a one-line expression such as “6 ÷ 2 (1 + 2)” can be evaluated as follows:

The explanation is simple enough: we execute the sub-expression in the brackets first. The sum of 1 and 2 is 3. Subsequently, using the operator precedence, which states that multiplication and division are carried out in the order that they appear in, we evaluate the 6 ÷ 2. This results in 3, as well. The resulting expression, 3 x 3, is computed as nine. The only assumption here is that we are dealing with a one-line operation, and this is where the alleged ambiguity comes in: are we supposed to interpret the expression “6 ÷ 2 (1 + 2)” as a rational expression? Suppose that we do interpret the original statement as a rational. Then, evaluating it yields the following:

One seemingly simple expression, represented in a different manner, yields a completely different result when evaluated through. This is where the crux of the controversy lies: which of these final values are correct? Basic mathematics is, after all, deterministic: given that we hold the parameters consistent, the result should always be the same. In this case, ambiguity has seemingly created a situation where mathematics is open to interpretation. To remove this ambiguity, mathematicians define what is called a “symbol of grouping”, in which certain symbols, such as the horizontal fraction line, create distinct groups that can be solved. In the case of our expression here, assuming it is rational (a / b for any integers a, b, and b ≠ 0), the numerator and denominator can be treated as a group. The numerator is evaluated separately from the denominator, and the final value is the quotient of the numerator and denominator. The horizontal fraction line is critical: its presence clearly indicates that we have two groups of operations, and as such, the final value, 1, is correct provided that we did, in fact, have a horizontal fraction line. However, because the expression “6 ÷ 2 (1 + 2)” was displayed on one line, there is no symbol of grouping present. Mathematics is about being explicit, and there is no symbol to make it clear that “6 ÷ 2 (1 + 2)” was in fact the rational expression with a numerator of 6 and a denominator of 2 (1 + 2). As such, if it is not a rational expression, “6 ÷ 2 (1 + 2)” is a simple, one-line expression to be evaluated left-to-right, exactly as it appears.

A Swift Solution

To verify this is the case, I implemented a simple evaluator in three different languages: Python, Java and Swift. The complete code is provided below, and I invite readers to give this a whirl. The code for Python can be copied to a .py file and run with the python command in the command line (e.g. python MathSolver.py), while for Java, the code will need to be copied to a .java file, compiled using javac (e.g. javac MathSolver.java) and then run. Finally, I’m writing Swift code for Playgrounds, which provides a Python-like way to run code without requiring one open a new Xcode project. As an aside, everything I’m running has a time and space complexity of O(1): it runs in constant time, and everything is guaranteed to halt once the expressions are evaluated.

Python Example

def solve():
  result = 6 / 2 * (1+2)
  print(result)

solve()

Java Example

public class MathSolver
{
  public static void main(String[] args)
  {
    int result = solve();
    System.out.println(result);
  }

  static int solve()
  {
    int result = 6 / 2 * (1+2);
    return result;
  }
}

Swift Example

func solve()
{
  let result = 6 / 2 * (1 + 2)
  print(result)
}

solve()

In each language, the result was the same: the expression “6 ÷ 2 (1 + 2)” evaluates to 9. The reason this is happening is because the compiler (for Java and Swift) or interpreter (in Python) is reading the expression as a single-line expression and is following operator precedence to compute the final result. Compilers tend not to make decisions about more complex operators and in languages like Java, Swift or Python, simply evaluate expressions left-to-right. It is the case that different programming languages may interpret the same expression differently depending on how it was designed, and so, it is the programmer’s responsibility to write out the expressions themselves in the correct order if they intend for an expression to have a specific meaning. This is no fault of the engineers who designed the aforementioned programming languages: the goal of a high-level programming language is simply to allow the programmer a means of providing instructions to the computer in a readable manner (low-level, or assembly languages, provide much more control at the expense of readability and ease-of-use), and as such, programming languages will interpret instructions exactly as they are provided. As such, if one intended to indicate that “6 ÷ 2 (1 + 2)” was, in fact, a rational expression, it would be necessary to write the line as “6 ÷ (2 (1 + 2))”: the additional brackets eliminate any ambiguity and clearly denote that we intend to treat the “2 (1 + 2))” as a denominator. Unsurprisingly, all three of Python, Java and Swift evaluate “6 ÷ (2 (1 + 2))” to 1. Below, I provide an example of what clean code looks like if one were to write a function evaluating 6 ÷ (2 (1 + 2)) in Swift. While less concise, every line clearly indicates its functionality.

Swift Example of Good Practises in Readability

func solveRational()
{
  let numerator = 6
  let denominator = 2 * (1 + 2)
  let result = numerator / denominator
  print(result)
}

solve()

I further remark that a good programmer wouldn’t just write out the expressions on one line: readable code is critical for maintenance and extensibility. While it may require more lines and come at the expense of conciseness, readability has numerous benefits. In this example, to make it explicit, beyond any debate that I was dealing with a rational expression, I would express the rational expression with separate variables for each of the numerator and denominator, and then return the quotient. Otherwise, in the case where no other context is given, the compiler does not make any assumptions about the expression and simply evaluates it. In the example above, I’ve not passed in any parameters or done any work to allow for the evaluation of an arbitrary rational expression. That is simple enough, but outside the scope of this discussion. Computer programs are only as good as the programmers that write them, and as such, a faulty program is inevitably the responsibility of the individual who write the code: if one wished “6 ÷ 2 (1 + 2)” to evaluate to 1 in a programming language which handles similarly to Swift, Java or Python, the expectation is that they, at the very least, add the additional brackets to clearly indicate their intentions; otherwise, what the programmer has on their hands is a semantics error, in which the program produces an output contrary to what was expected because said programmer did not correctly communicate their intentions.

Handling Controversy Elegantly

I have now roughly defined how I reached my solutions, my understanding of how the alternate solution is reached and provided justification for why the alternate solution requires a massive subjective leap that renders it incorrect in the current context. Upon posting this to Twitter originally, I was met with resistance. From an explanation of why the computer is not correct, to a poorly formed proof and even ad hominem attacks, it appeared that people were insistent that their calculations were correct, often-times without adequate explanation. The best effort was an attempt to prove that “6 ÷ 2 (1 + 2) = 1”, where the individual worked their way to a solution, but had a converse error in their reasoning. A converse error occurs when, given ∀x, P(x) → Q(x), one assumes Q(a), which gives them P(a). In the attempt at a solution, the individual here supposed that since, they had Q(a) (i.e. 6 ÷ 2 (1 + 2) = 1), therefore, they had P(a) (6 ÷ 2 (1 + 2) = 6 ÷ 2 [(1 + 2)]) as well. This is an invalid mode of reasoning (one that I informally call “supposing what you want to prove is true”). I have a counter-proof using one of the more fun forms of reasoning, called a proof by contradiction. Here, let’s suppose that it is the case that 6 ÷ 2 (1 + 2) = 1, such that 6 ÷ 2 (1 + 2) = 6 ÷ [2 (1 + 2)]. Through the use of algebra to simplify both sides, we end up with the following contradiction:

Since it is clear that 1/6 is not equal to 6 (which is absurd were it to be true), we’ve established our contradiction, and therefore, the premise is false. I have shown that the two expressions are different and therefore, not equivalent. Proof by contradiction is one of the most amusing and powerful forms of reasoning there is, and this is a clean, elegant way of showing my point. The other arguments were that Apple’s engineers are wrong, that I’m living a “sad life…trying to work out this problem like an 8 year old but it’s[sic] actually much cooler than that” and I “litteraly[sic] changed the equation…[because I’m] trying to seem smart but that took pre calc can see you’re wrong”. On Twitter, I’m unable to reply to those owing to the character and formatting constraints, but here, where I have all the space I need, I’ve concretely and decisively demonstrated in not one, but two different ways that there is no ambiguity here. Certain results come from how clearly defined one makes their expressions, and there is one reality: if one does not have an eye for detail and pay attention to things, they will inevitably get results that seem correct, but are in fact erroneous. Such mistakes can be fatal in a system: individual errors may not seem like such a big deal, but in a complex system with many equations and many computations, error propagation means that the more errors there are, the worse a system will perform. I will leave it to the individuals above to decide whether or not this makes me as being equivalent to an “8 year old” who apparently had not taken pre-calculus.

The takeaway lesson here, then, isn’t that mathematics is open to interpretation because there can be ambiguity, but rather, that in mathematics, and computer science, there are specific symbols and syntax that is used to define semantics. The compiler, not being human, will not infer the user’s meaning, and as such, it is the writer’s responsibility to make clear their meaning. Consequently, the entire Twitter debate only served to illustrate one thing: that there is a non-trivial belief that mathematics can be regarded as one might a liberal art: open to debate, semantics and interpretation. The origins of this belief are outside the scope of this document, but I hold that the reason why mathematics, and science in general, can be counted upon is because it is a discipline dependent on quantitative measures. Unlike the liberal arts, where personal background, beliefs and other intangible elements come into play, there are some things that simply cannot be argued against in mathematics: these laws and theorems form an indisputable framework that can be used to solve more complex, sophisticated problems. If these fundamentals cannot be agreed upon, there would be no foundation from which to explore increasingly exciting solutions for handling challenging and relevant problems.

  • The short version of this post, pertaining to the “6 ÷ 2 (1 + 2)” problem, is as follows: the answer is 9, and I’ve offered my reasons for why this holds true. Given what I have presented above, I can conclude that 6 ÷ 2 (1 + 2) = 9 with a quod erat demonstrandum (the mathematician’s equivalent of a mic drop; more formally, it is Latin for “that which was to be demonstrated”). I personally feel that Twitter’s limited character count really prevents discussions such as these from happening, and this could be one reason why controversies seem to be happening every other day now: without enough space to establish context, things get misunderstood more often. There is one more remark I have about this post; it took a total of around an hour to forumate the ideas, and then an extra four hours put it the actual post together, including the equations and code snippets; the tricky part was formatting the post so everything looked nice for the readers. With this post in the books, I’m going to return to doing what I do best: relaxing with the anime community on Twitter and gear up for Kanon, which we’re revisiting, as well as blasting bad guys in The Division 2, which I’m sure my opponents would find more agreeable than if I were to give them a personalised demonstration of what graduate school makes of their foes.

For this week’s controversy, I have presented a discussion that roughly indicates how I’d resolve a polarising question outside of the realm of anime. In this case, I feel that I am not biased, having analysed both sides of the argument to reach the conclusion that I did. In something like computer science or mathematics, bias can be detrimental, so I always strive to ensure I understand what the other side is saying, and why they are saying it: there are circumstances where I am confident in my position, and there are others yet where the other side is correct because of a misunderstanding on my end. I do not believe in defending something incorrect, and I can be convinced to accept the other side’s statements if there is a well-reasoned and evidence-based explanation. In anime discussions, things are more subjective, and I admit that I can grow attached to my own theories. However, even here, I am not above hearing other perspectives: the point of being in an anime community is, after all, to see what others are saying. The merits of this is being able to see what different peoples’ experiences are through how they watch, and enjoy their anime. Finally, Moyatori’s discussion raises the question of how I ensure people walk away with a good idea of what I am saying, even if I do venture into the realm of the arcane and begin drawing terminology and phrases from my old textbooks. The solution for this is simple enough: I use a lot of screenshots, and I tend to be a little more casual in the accompanying figure captions. Here in the figure captions, I crack jokes, explain myself in more conversational terms and use the screenshots as a context for what I’m saying. For this post in particular, I’ve used visual examples to demonstrate my thought process (i.e. show my work). I believe that over the lifespan of this blog, is one that has allowed me to cover a variety of topics, from anime, games, films and all manners of topics in between without creating inconsistency.