Categories

# Scala Saturday – Code That Looks Like Math

Something that Scala and most other modern languages allow these days is variable names that contain what you might think of as non-traditional characters from the Unicode character set, e.g., Greek symbols such as π and τ. If you’re a C programmer, you have to settle for spelling out the name of the character:

```const double PI = 3.141592654;
double delta = x1 - x2;
```

But that’s OK, right? What’s the difference, really? The value π is one thing: it’s a universally recognized constant. But even with the example `delta` above, don’t you want to name it something more descriptive, like `marginOfError` anyway?

Well, yes, many times instead of using the characters verbatim from your physics textbook …

```val f = m * a
```

… you spell it out so that the code is clearer:

```val force = mass * acceleration
```

Likewise, even though Scala allows you to write the following:

```val Ï‰ = 2 * math.Pi * f
```

… it’s probably better practice to write …

```val angularVelocity = 2 * math.Pi * frequency
```

What’s the point of this post then? Sure, you can use “special” characters in variable names, but so far, I’ve discouraged you from doing it!

Nevertheless there are times when it is appropriate. If you are coding up an algorithm that consists of a series of well-known equations in a certain field of study, and the more your code looks like those equations, the easier it is to check it against the literature.

Consider the following—a series of values and equations for converting latitude and longitude to universal polar stereographic (UPS) coordinates, a way of representing coordinates at the earth’s poles:

UPS coordinates consist of a hemisphere—either northern or southern—and two distance components, easting and northing, both in meters:

```object Hemisphere extends Enumeration {
type Hemisphere = Value

val Northern = Value('N')
val Southern = Value('S')

def fromLatitude(lat: Double): Hemisphere =
if (lat < 0) Southern else Northern
}

case class UniversalPolarStereographic(
northing: Double,
easting: Double,
hemisphere: Hemisphere)
```

Now compare the code below to the equations from the literature above:

```def latLonToUps(
lat: Double,
lon: Double): UniversalPolarStereographic = {

val hemisphere = Hemisphere.fromLatitude(lat)

val Ï† = lat.abs
val Î» = lon

val Ï€ = math.Pi

val FN = 2000000.0
val FE = 2000000.0

val a = 6378137.0
val f = 1 / 298.257223563

val e_2 = f * (2 - f)
val e = math.sqrt(e_2)
val eOver2 = e / 2
val Câ‚’ = ((2 * a) / math.sqrt(1 - e_2)) *
math.pow((1 - e) / (1 + e), eOver2)
val kâ‚’ = 0.994
val Ï€Over4 = Ï€ / 4

val esinÏ† = e * math.sin(Ï†)
val Ï†Over2 = Ï† / 2

val tanZOver2 =
math.pow((1 + esinÏ†) / (1 - esinÏ†), eOver2) *
math.tan(Ï€Over4 - Ï†Over2)
val R = kâ‚’ * Câ‚’ * tanZOver2
val RcosÎ» = R * math.cos(Î»)
val RsinÎ» = R * math.sin(Î»)

val N = hemisphere match {
case Hemisphere.Northern => FN - RcosÎ»
case Hemisphere.Southern => FN + RcosÎ»
}
val E = FE + RsinÎ»

UniversalPolarStereographic(N, E, hemisphere)
}
```

It’s not perfect: you still cannot set numerators above denominators, for instance. But isn’t that easier to compare to the literature than if we had to write out `RsinLambda` or `eSinPhi`?

(Note: UPS coordinates are only valid for latitudes near the poles. For simplicity, the code above does not check to make sure that the input latitude falls within those bounds. I mean, it’s complex enough as it is for the sake of exemplifying the point of this post.)

(Note: I’m aware that some of the characters in the code don’t show up correctly on all browsers, e.g., the subscript “O” and perhaps the φ. I’m working to correct that. Nevertheless you should be able to use such symbols in your source code.)

This site uses Akismet to reduce spam. Learn how your comment data is processed.