Note: I don't have any immediate solutions in this article; it's more of a discussion of where I'm at today when looking at handling money/currency in Scala.
As a quick note, I've started to look at handling money/currency in Scala, and I'm also starting to explore a couple of money/currency libraries.
The BigDecimal class
As a bit of background, almost everyone handles currency with the BigDecimal class. There's a bit more to it than that, as described in this "Representing Money" article, but it usually comes down to BigDecimal.
Joda Money and other currency libraries
The most promising Scala money/currency libraries I've found are listed here:
- http://joda-money.sourceforge.net/ (a Java library, current release is 0.7)
- http://www.thomasknierim.com/114/scala/scala-currency-class/ (not on Github or Sourceforge, but you can download source from the author's site)
- http://timeandmoney.sourceforge.net/ ("need alpha users")
Frankly, I'd only use the last two links if the Joda Money library didn't work. I don't remember the specific problems, but the unit tests for the second link won't compile under Scala 2.9, and as the author states, the code is a little "monolithic". That being said, if nothing else existed, I'd use his code base as a starting point for my own library. The "need alpha users" on the third link scared me off right away, though again, if nothing else existed, I'd take a harder look at their code.
So at this point it's down to working with currency in Scala using either a) the Joda Money library or b) just using the BigDecimal class. The things that concern me about Joda Money are the 0.7 release, and the lack of interaction on their discussion forum.
BigDecimal problems and solutions
I don't have time to get into all the details today, but here's a quick example of a problem with using the BigDecimal class to handle money:
scala> val salary = 100000: BigDecimal salary: BigDecimal = 100000 scala> val weekly = salary / 52 weekly: scala.math.BigDecimal = 1923.076923076923076923076923076923 scala> val biWeekly = salary / 26 biWeekly: scala.math.BigDecimal = 3846.153846153846153846153846153846
As you can see, the weekly and biWeekly salary numbers run off there for a while, so you always need to do something to deal with rounding issues.
And just as quick, here's the beginning of a solution to that problem:
scala> import scala.math.BigDecimal.RoundingMode import scala.math.BigDecimal.RoundingMode scala> weekly.setScale(2, RoundingMode.HALF_EVEN) res0: scala.math.BigDecimal = 1923.08
The following URL shows how to do a few things with BigDecimal and MathContext:
This URL has a few discussions about how to use BigDecimal with currency:
Scala money/currency - Summary
I'm sorry that I'm not much help today; as mentioned, I'm just beginning to head down this road.
If you already have experience in deal with money and currency in Scala, I'd be glad to hear your thoughts. Just leave a note in the Comments section below.