Analytics Vidhya
Published in

Analytics Vidhya

Scala reminder: Gotta name an argument to use it twice

Photo by Michał Parzuchowski on Unsplash

This is going to be a short article. Scala is a very powerful programming language with a generally concise syntax. Trouble is, every so often I forget certain details of that concise syntax. Like, for example, how do you use a wildcard twice?

I learned quickly enough how to use a wildcard once. For example:

scala> LazyList.iterate(1: BigInt)(_ * 7)
res0: scala.collection.immutable.LazyList[BigInt] = LazyList(<not computed>)

The first pair of parentheses enclose 1 as a BigInt. In the second pair of parentheses, the underscore wildcard represents, on the first iteration, the initial value (1, in the example), and on later iterations the value computed by the previous iteration.

So the value represented by the wildcard is, in the example, multiplied by the integer 7. Thanks to an implicit conversion I generally take for granted, the Int is converted to a BigInt, and thanks to “operator overloading,” we can use the multiplication operator instead of multiply() or times() or whatever it might otherwise be called.

Thus the first iteration produces 7, then the second iteration gives 49, and so on and so forth.

scala> res0.take(20).toList
res1: List[BigInt] = List(1, 7, 49, 343, 2401, 16807, 117649, 823543, 5764801, 40353607, 282475249, 1977326743, 13841287201, 96889010407, 678223072849, 4747561509943, 33232930569601, 232630513987207, 1628413597910449, 11398895185373143)

Copy and paste to the OEIS search box, the very first result should be A420, the powers of 7. In fact it should be the only result.

Sometimes though, you need to use the wildcard twice.

For example, consider the method to approximate square roots that is sometimes attributed to Sir Isaac Newton. By “Newton’s method,” we approximate the square root of x by starting with an initial guess g(0), which we progressively refine by the formula g(n) = (g(n − 1) + x/g(n − 1))/2.

Here g(n − 1) seems like a perfect choice for a LazyList iteration that uses the wildcard twice in the iterated function. Except that you can’t do that in Scala. There are Scala expressions in which you can use two underscore wildcards, but this is not one of those.

scala> def newtonSqrt(x: Double, initGuess: Double): LazyList[Double] = LazyList.iterate(initGuess)((_ + x/_)/2)                                                                                             
^
error: missing parameter type for expanded function ((<x$1: error>, x$2) => x$1.$plus(x.$div(x$2)))
^
error: missing parameter type for expanded function ((<x$1: error>, <x$2: error>) => x$1.$plus(x.$div(x$2)))

So I have to give the underscore wildcard a type? That doesn’t sound right.

After some searching with Google, I came across the Scala cheat sheet by Brendan O’Connor.

(1 to 5).map(x => x * x)

Anonymous function: to use an [argument] twice, [you] have to name it.

A-ha! I have to name the “wildcard,” but I don’t have to specify its type, that’s inferred by the compiler.

scala> def newtonSqrt(x: Double, initGuess: Double): LazyList[Double] = LazyList.iterate(initGuess)(g => (g + x/g)/2)
newtonSqrt: (x: Double, initGuess: Double)LazyList[Double]

Alright, that looks like it works. But the proof is in the pudding.

scala> newtonSqrt(13.0, 4.0)
res12: LazyList[Double] = LazyList(<not computed>)
scala> res12.take(20).toList
res13: List[Double] = List(4.0, 3.625, 3.605603448275862, 3.6055512758414574, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896, 3.6055512754639896)
scala> res13(19) * res13(19)
res14: Double = 13.000000000000002

For assertEquals() in JUnit with type Double (double in Java), I generally use a delta of 0.00001. So 13.000000000000002 would be good enough with that delta.

Well, there you have it. In Scala, you can’t always use the underscore wildcard, but sometimes you can name a wildcard and use that twice.

--

--

--

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Recommended from Medium

Deploy Django project with gunicorn, PostgreSQL, and nginx

📢 @RoseonFinance was mentioned in @thecryptofomo latest video and also highlighting #Roseon Road…

How to change the name of the principal Git branch

Tackling asynchronous integration testing in Senses

Road to Go Pro — Packages & Modules

.Net Core Configuration Objects

Developing an Automated Trading System with Python

Smarter Enemies with BFS!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alonso Del Arte

Alonso Del Arte

is a composer and photographer from Detroit, Michigan. He has been working on a Java program to display certain mathematical diagrams.

More from Medium

Scala: for-comprehension stops at the empty box

Essential effects

Restricting sum type instance creation

Achieving Indisputable Job Security Using Novel Scala 3 Features: A Case Study