Which Language is It?
Thomas J. Kennedy
Sometimes you will come across an unfamiliar code snippet. Sometimes the snippet is a familiar language (e.g., C++, Java, or Python). Sometimes it is a less familiar language (e.g., Rust).
1 Intuition
Intuition is a powerful tool, but it will often mislead you. Let us start this discussion by ignoring all intuition (i.e.,gut feelings). This primarily includes ignoring:
- Variable naming - specifically underscore (the_book_title) vs camel case (theBookTitle).
- Placement of brackets (i.e., same line vs next line).
- Pre-increment vs post-increment
++i
vsi++
. - Presence or absence of
public
,private
, orprotected
. - Use of a variable to store container size vs using
.size()
,.length
or.length()
. - Use of
String
vsstring
- type aliases (e.g.,using String = std::string
) and template parameters can obfuscate code.
2 Example 1
Example 1: A Point Match Function// Function header/signature omitted { for (int i = 0; i < numLocations; i++) { if (locations[i] == p) { return i; } if (locations[i].x == p.x && locations[i].y == p.y && locations[i].z == p.z) { return i; } } return -1; }
First, we need to figure out what this function does and is indended to do. This is a nuanced distinction (on the verge of a distinction without a difference). However, we know from experience (with our own mistakes) that what we want the code to do and what the code actually does are sometimes different.
2.1 The C++ View
Let us first examine this as C++ code:
-
The first condition
locations[i] == p
checks for equivalence by callingPoint::operator==
. -
The second condition
locations[i].x == p.x && locations[i].y == p.y && locations[i].z == p.z
explicitly checks each attribute.
This is (syntactically) valid C++ code–albeit redundant. If this were written in proper (i.e., idiomatic) C++, it would be:
Example 2: Idiomatic C++ Point Math Function// Function header/signature omitted { for (int i = 0; i < numLocations; i++) { if (locations[i] == p) { return i; } } return -1; }
If we wanted to take it a step further… we could use std::find
.
Example 3: C++ Point Match Function - with std::find// Function header/signature omitted { auto it = std::find(begin(locations), end(locations), p); if (it == end(locations)) { return -1; } return (it - begin(locations)); }
I do not think we need to be that obnoxious…
2.2 The Java View
Let us now examine this as Java code:
-
The first condition checks if the memory addresses match–every object variable in java is a reference–analogous to a C++ pointer.
-
The second condition–as in C++–explicitly checks each attribute.
This is valid Java code. This is code most likely extracted from a Java program. It is clear that the person who wrote this code violated the Java class checklist (i.e., did not provide an equals
method).
Assuming the equals
issue were addressed, we would end up with:
Example 4: Idiomatic Java Point Math Function// Function header/signature omitted { for (int i = 0; i < numLocations; i++) { if (locations[i] == p){ return i; } else if (locations[i].equals(p)) { return i; } } return -1; }
2.3 A Little Python
With a few quick changes, we can turn this into Python code…
Example 5: Python - A Quick Conversion""" Function header/signature omitted """ for i in range(0, len(locations)): if hash(locations[i]) == hash(p): return i elif locations[i] == p: return i return -1
We can make it more idiomatic… using enumerate
!
Example 6: Python - A Quick Conversion""" Function header/signature omitted """ for idx, a_point in enumerate(locations): if hash(a_point) == hash(p): return idx elif a_point == p: return idx return -1
3 Example 2
Example 7: Array Append & ResizeEncyclopedia newEdition = catalog[oldEditionIndex]; newEdition.edition = 3; catalog[catalogSize] = newEdition; catalogSize++;
3.1 The C++ View
Let us first examine this as C++ code:
-
I define a new Encyclopedia,
newEdition
. This results a deep copy through application of the assignment operator. -
I take the new book and change the edition number to 3.
-
I add
newEdition
to the end of thecatalog
array.
This is an instance of resizing an array.
3.2 The Java View
Let us next examine this as Java code:
-
I define a new book reference,
newEdition
-
I take the new book reference and change the edition number to 3.
-
I add this new book reference to the end ot the
catalog
array.
This code results in two references in the array–that both reference the same book. This code is extracted from a C++ program.
If I wanted this code snippet to be useful in Java, I would add a call clone
:
Example 8: Adding the Java clone MethodEncyclopedia newEdition = catalog[oldEditionIndex].clone(); newEdition.edition = 5; catalog[catalogSize] = newEdition; catalogSize++;
3.3 A Little Python
With a few quick changes, we can turn this into Python code…
Example 9: Python - A Quick Conversionnew_edition = copy.deepcopy(catalog[oldEditionIndex]) new_edition.edition = 5 catalog[catalog_size] = new_edition catalog_size +=1
Let us use a Python list instead of a faked array.
Example 10: Python - A More Complete Conversionnew_edition = copy.deepcopy(catalog[oldEditionIndex]) new_edition.edition = 5 catalog.append(new_edition)