This page is no longer maintained — Please continue to the home page at www.scala-lang.org

An Efficient Scalar Package in Scala

29 replies
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
A while back I developed a Python package called "scalar" to represent physical units and scalars. I made it publicly available, and I am also using it extensively in my R&D work in air traffic management. A key feature is that, with the flip of a software switch, scalar objects can be replaced with basic numeric types for more efficient production runs.

As an exercise in learning Scala, I decided to convert my scalar package to Scala. The name itself just seemed to be begging me to do it! I just released the first version on sbaz, but I decided to also mention it here just to make sure it gets noticed.

Along with a complete user guide, it is available at my website at

http://russp.us/scalar-scala.htm

Here is the summary that appears there:

Summary-- A Scala class was designed to represent physical scalars and to eliminate errors involving implicit physical units (e.g., confusing radians and degrees). The standard arithmetic operators are overloaded to provide syntax identical to that for basic numeric types. The Scalar class itself does not define any units but is part of a package that includes a complete implementation of the standard metric system of units and many common non-metric units. The scalar package also allows the user to define a specialized or reduced set of physical units for any particular application or domain. Once an application has been developed and tested, the Scalar class can be switched off at compile time to achieve the execution efficiency of operations on basic numeric types, which are an order of magnitude faster. The scalar class can also be used for discrete units to enforce type checking of integer counts, thereby enhancing the static type checking of Scala with additional dynamic type checking.

I may post a few questions about it here in the near future.

Russ P.
http://RussP.us
Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

Russ Paielli wrote:
> A while back I developed a Python package called "scalar" to represent
> physical units and scalars. I made it publicly available, and I am also
> using it extensively in my R&D work in air traffic management. A key
> feature is that, with the flip of a software switch, scalar objects can
> be replaced with basic numeric types for more efficient production runs.
>
> As an exercise in learning Scala, I decided to convert my scalar package
> to Scala. The name itself just seemed to be begging me to do it! I just
> released the first version on sbaz, but I decided to also mention it
> here just to make sure it gets noticed.

Looks interesting. Note that it's possible to check physical units at
compile time using a bit of metaprogramming, see
http://trac.assembla.com/metascala/browser/src/metascala/Units.scala for
an example. There are some downsides though:

- requires the experimental "-Yrecursion" compiler option
- compile times can be quite slow
- performance will probably suffer because doubles are "boxed", but
there are no runtime checks

/Jesper Nordenberg

sadie
Joined: 2008-12-21,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

If it's possible, I think a statically checked units library would be much
more helpful than a dynamic one. The idea of static typing is to alert you
as soon as possible when a mistake happens. If the error isn't noticed until
runtime, then it gains you little over the plain decimal.

The package linked to by Jesper is an interesting start: each value is
statically typed with a representation of its number in all the dimensions.
In Java this would be insanely clumsy, but type inference changes the game.
I don't know enough about the compiler to know what the performance
implications of this are. Also, with types erased, there are no runtime
checks.

To get static checking, rumtime checking and top performance, you may be
better off writing a compiler plug-in... but if so, you're a braver man than
I.

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: An Efficient Scalar Package in Scala
On Fri, Feb 13, 2009 at 9:41 AM, Marcus Downing <marcus@minotaur.it> wrote:

If it's possible, I think a statically checked units library would be much
more helpful than a dynamic one. The idea of static typing is to alert you
as soon as possible when a mistake happens. If the error isn't noticed until
runtime, then it gains you little over the plain decimal.

I agree that statically checked units with zero run-time overhead would be ideal (if they are possible), but I strongly disagree with your claim that, "If the error isn't noticed until runtime, then it gains you little over the plain decimal." That might be true for lines of code that are never executed until they are deployed to the field, but if that is the case for many of your lines of code, then you have bigger problems than unit consistency.

Many years ago I heard of a fast-time aircraft aerodynamic simulation program that was run as part of a research program for months before someone realized that the wing sweep angle was being entered in degrees when it should have been radians (or maybe it was the other way around; I can't remember). Apparently the results were not obviously wrong, so the error was not detected for a long time. I realize that allowing that to happen may seem ridiculously careless, but "stuff" like that happens all the time. With dynamic checks on the units, that error would have been caught immediately.

I know of another case in which a colleague of mine published a paper on airport arrival scheduling. His results were based on a program he wrote in Python. A couple of years later, someone decided to re-use his code and discovered that he had used seconds for an important parameter when he meant to use minutes. Dynamic unit checking would have prevented that error.

And who knows how many of these kinds of unit errors are subtly corrupting results and are never detected at all?

So, yes, static checks would be ideal, but with proper testing, dynamic checks are perhaps 99% as effective.

Russ P.

Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

Marcus Downing wrote:
> The package linked to by Jesper is an interesting start: each value is
> statically typed with a representation of its number in all the dimensions.
> In Java this would be insanely clumsy, but type inference changes the game.
> I don't know enough about the compiler to know what the performance
> implications of this are. Also, with types erased, there are no runtime
> checks.

If you use -optimise, Hotspot has a good day and the wind is in your
back, there might be close to zero overhead in some code using a simple
wrapper class. The overhead of object arrays can be solved by creating
an double array wrapper class which should result in virtually no overhead.

Regarding runtime checks I don't see the need for them when you have
static checking.

/Jesper Nordenberg

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
An Efficient Scalar Package in Scala
This is an update of some software that I wrote to represent physical scalars. It is a conversion from a Python implementation that I wrote several years ago and have been using for my work in air traffic management. I announced the first Scala version on this email list back in February of 2009. It is available, along with a user guide, at

http://RussP.us/scalar-scala.htm

Comments and suggestions for improvement are welcome, of course. Also, if anyone is aware of similar software in Scala, please let me know. Thanks.

Russ P.

Summary -- The Scalar class represents physical scalars in the Scala programming language. The standard arithmetic operators are overloaded to provide syntax identical to that for basic numeric types. The Scalar class itself does not define any units but is part of a package that includes a complete implementation of the standard SI metric system of units and many common non-metric units. The design also allows users to define a specialized or reduced set of physical units for any particular application or domain. Once an application has been developed and tested, the Scalar class can be disabled or bypassed to achieve the execution efficiency of operations on basic numeric types, which are more than an order of magnitude faster. The scalar package is available from http://RussP.us/scalar-scala.htm.

--
http://RussP.us
Ido M. Tamir
Joined: 2010-05-03,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

On Thursday 10 June 2010 02:45:49 Russ Paielli wrote:
> This is an update of some software that I wrote to represent physical
> scalars. It is a conversion from a Python implementation that I wrote
> several years ago and have been using for my work in air traffic
> management. I announced the first Scala version on this email list back in
> February of 2009. It is available, along with a user guide, at
>
> http://RussP.us/scalar-scala.htm
>
> Comments and suggestions for improvement are welcome, of course. Also, if
> anyone is aware of similar software in Scala, please let me know. Thanks.
>
> Russ P.

Outside of my field, but from your paper it looks very cool and enforcing
valid calculations.
I guess thats the reason why you switched from python to scala.

best,
ido

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: An Efficient Scalar Package in Scala
Russ - you've spelt "metre" wrong everywhere

Date: Wed, 9 Jun 2010 17:45:49 -0700
Subject: [scala-user] An Efficient Scalar Package in Scala
From: russ.paielli@gmail.com

This is an update of some software that I wrote to represent physical scalars. It is a conversion from a Python implementation that I wrote several years ago and have been using for my work in air traffic management. I announced the first Scala version on this email list back in February of 2009. It is available, along with a user guide, at

http://RussP.us/scalar-scala.htm


Get a free e-mail account with Hotmail. Sign-up now.
Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: An Efficient Scalar Package in Scala
Have you seen:Lex Spoon units compiler plugin (not currently maintained): http://lampsvn.epfl.ch/trac/scala/browser/compiler-plugins/units/trunk
...or, drifting slightly off topic and hoping not to attract trolls, the units support in F#: http://research.microsoft.com/en-us/um/people/akenn/units/

On Wed, Jun 9, 2010 at 8:45 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
This is an update of some software that I wrote to represent physical scalars. It is a conversion from a Python implementation that I wrote several years ago and have been using for my work in air traffic management. I announced the first Scala version on this email list back in February of 2009. It is available, along with a user guide, at

http://RussP.us/scalar-scala.htm

Comments and suggestions for improvement are welcome, of course. Also, if anyone is aware of similar software in Scala, please let me know. Thanks.

Russ P.

Summary -- The Scalar class represents physical scalars in the Scala programming language. The standard arithmetic operators are overloaded to provide syntax identical to that for basic numeric types. The Scalar class itself does not define any units but is part of a package that includes a complete implementation of the standard SI metric system of units and many common non-metric units. The design also allows users to define a specialized or reduced set of physical units for any particular application or domain. Once an application has been developed and tested, the Scalar class can be disabled or bypassed to achieve the execution efficiency of operations on basic numeric types, which are more than an order of magnitude faster. The scalar package is available from http://RussP.us/scalar-scala.htm.

--
http://RussP.us



--
http://erikengbrecht.blogspot.com/
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: An Efficient Scalar Package in Scala
On Thu, Jun 10, 2010 at 4:34 AM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
Have you seen:Lex Spoon units compiler plugin (not currently maintained): http://lampsvn.epfl.ch/trac/scala/browser/compiler-plugins/units/trunk
...or, drifting slightly off topic and hoping not to attract trolls, the units support in F#: http://research.microsoft.com/en-us/um/people/akenn/units/

Thanks for the links. I was aware of Lex Spoon's units project, but I thought it had been abandoned. Is that true? Is anyone currently using it?

The F# thing looks interesting. If I understand it correctly, Andrew Kennedy has figured out how to solve the units problem statically, so units are checked at compile time, and no run-time overhead is imposed. I'm not sure what his limitations are, but that's a great accomplishment.

I see also that Lex Spoon's units implementation in Scala is based on Andrew Kennedy's PhD thesis, so apparently it also checks units at compile time and imposes no run-time overhead. If that is the case, why was it abandoned (or was it)? Does anyone know if it works?

As for my implementation, I had originally developed it in Python, and I decided to convert it to Scala initially as an exercise to learn Scala. My approach check units at run time, and it avoids run-time overhead by switching to different "library" code that replaces each instance of the Scalar class with an "unboxed" Double (to produce the same output without requiring any change in the client code).

Russ P.
 

On Wed, Jun 9, 2010 at 8:45 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
This is an update of some software that I wrote to represent physical scalars. It is a conversion from a Python implementation that I wrote several years ago and have been using for my work in air traffic management. I announced the first Scala version on this email list back in February of 2009. It is available, along with a user guide, at

http://RussP.us/scalar-scala.htm

Comments and suggestions for improvement are welcome, of course. Also, if anyone is aware of similar software in Scala, please let me know. Thanks.

Russ P.

Summary -- The Scalar class represents physical scalars in the Scala programming language. The standard arithmetic operators are overloaded to provide syntax identical to that for basic numeric types. The Scalar class itself does not define any units but is part of a package that includes a complete implementation of the standard SI metric system of units and many common non-metric units. The design also allows users to define a specialized or reduced set of physical units for any particular application or domain. Once an application has been developed and tested, the Scalar class can be disabled or bypassed to achieve the execution efficiency of operations on basic numeric types, which are more than an order of magnitude faster. The scalar package is available from http://RussP.us/scalar-scala.htm.

--
http://RussP.us



--
http://erikengbrecht.blogspot.com/



--
http://RussP.us
David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala
Just jumping in to say:Metascala contains a type-checked units implementation. It abuses the fact that every unit is based on a "power combination" of the 7 physical base units. See http://trac.assembla.com/metascala/browser/src/metascala/Units.scala for the implementation.
Please disregard if this is irrelevant at this point in the conversation.

On Fri, Jun 11, 2010 at 1:53 AM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Thu, Jun 10, 2010 at 4:34 AM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
Have you seen:Lex Spoon units compiler plugin (not currently maintained): http://lampsvn.epfl.ch/trac/scala/browser/compiler-plugins/units/trunk
...or, drifting slightly off topic and hoping not to attract trolls, the units support in F#: http://research.microsoft.com/en-us/um/people/akenn/units/

Thanks for the links. I was aware of Lex Spoon's units project, but I thought it had been abandoned. Is that true? Is anyone currently using it?

The F# thing looks interesting. If I understand it correctly, Andrew Kennedy has figured out how to solve the units problem statically, so units are checked at compile time, and no run-time overhead is imposed. I'm not sure what his limitations are, but that's a great accomplishment.

I see also that Lex Spoon's units implementation in Scala is based on Andrew Kennedy's PhD thesis, so apparently it also checks units at compile time and imposes no run-time overhead. If that is the case, why was it abandoned (or was it)? Does anyone know if it works?

As for my implementation, I had originally developed it in Python, and I decided to convert it to Scala initially as an exercise to learn Scala. My approach check units at run time, and it avoids run-time overhead by switching to different "library" code that replaces each instance of the Scalar class with an "unboxed" Double (to produce the same output without requiring any change in the client code).

Russ P.
 

On Wed, Jun 9, 2010 at 8:45 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
This is an update of some software that I wrote to represent physical scalars. It is a conversion from a Python implementation that I wrote several years ago and have been using for my work in air traffic management. I announced the first Scala version on this email list back in February of 2009. It is available, along with a user guide, at

http://RussP.us/scalar-scala.htm

Comments and suggestions for improvement are welcome, of course. Also, if anyone is aware of similar software in Scala, please let me know. Thanks.

Russ P.

Summary -- The Scalar class represents physical scalars in the Scala programming language. The standard arithmetic operators are overloaded to provide syntax identical to that for basic numeric types. The Scalar class itself does not define any units but is part of a package that includes a complete implementation of the standard SI metric system of units and many common non-metric units. The design also allows users to define a specialized or reduced set of physical units for any particular application or domain. Once an application has been developed and tested, the Scalar class can be disabled or bypassed to achieve the execution efficiency of operations on basic numeric types, which are more than an order of magnitude faster. The scalar package is available from http://RussP.us/scalar-scala.htm.

--
http://RussP.us



--
http://erikengbrecht.blogspot.com/



--
http://RussP.us

Danielk
Joined: 2009-06-08,
User offline. Last seen 3 years 21 weeks ago.
Re: An Efficient Scalar Package in Scala
Typechecked at runtime, right?

/Daniel

On Fri, Jun 11, 2010 at 2:32 PM, David Flemström <david.flemstrom@gmail.com> wrote:
Just jumping in to say:Metascala contains a type-checked units implementation. It abuses the fact that every unit is based on a "power combination" of the 7 physical base units. See http://trac.assembla.com/metascala/browser/src/metascala/Units.scala for the implementation.
Please disregard if this is irrelevant at this point in the conversation.

Danielk
Joined: 2009-06-08,
User offline. Last seen 3 years 21 weeks ago.
Re: An Efficient Scalar Package in Scala
Static testing of dimesionality is something I've wanted for a long time, so I had a quick look at the units implementation perhaps six months ago. It seems to be able to check some operations (I can't remember which exactly ) at compile time using a compiler plugin, but it also stores the dimensions at runtime so there is an overhead. I think it is impossible to do *all* dimensionality checking statically - consider e.g. differentiating in a loop.

On Fri, Jun 11, 2010 at 1:53 AM, Russ Paielli <russ.paielli@gmail.com> wrote:..
I see also that Lex Spoon's units implementation in Scala is based on Andrew Kennedy's PhD thesis, so apparently it also checks units at compile time and imposes no run-time overhead. If that is the case, why was it abandoned (or was it)? Does anyone know if it works?
Russ P.
 


David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala
No, it does type checking at compile time, without any plugins.

On Fri, Jun 11, 2010 at 4:06 PM, Daniel Kristensen <daniel.kristensen@gmail.com> wrote:
Typechecked at runtime, right?

/Daniel

On Fri, Jun 11, 2010 at 2:32 PM, David Flemström <david.flemstrom@gmail.com> wrote:
Just jumping in to say:Metascala contains a type-checked units implementation. It abuses the fact that every unit is based on a "power combination" of the 7 physical base units. See http://trac.assembla.com/metascala/browser/src/metascala/Units.scala for the implementation.
Please disregard if this is irrelevant at this point in the conversation.


Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: An Efficient Scalar Package in Scala
On Fri, Jun 11, 2010 at 5:32 AM, David Flemström <david.flemstrom@gmail.com> wrote:
Just jumping in to say:Metascala contains a type-checked units implementation. It abuses the fact that every unit is based on a "power combination" of the 7 physical base units. See http://trac.assembla.com/metascala/browser/src/metascala/Units.scala for the implementation.
http://RussP.us


The Metascala units implementation looks interesting, but I see that it is pre-alpha and unstable. I wonder how well static units checking would work in practice and what it's basic limitations are.

Let me provide some background here. There are two basic types of unit errors. Let's call them scaling errors and compatibility errors.

A scaling error occurs when the physical dimensions are compatible, but the implicit scale of the units is wrong. An example is adding a length scaled in feet to a length scaled in meters.

A compatibility error occurs when incompatible units are added, subtracted, or compared. An example is adding a length to a time.

I haven't done a formal study, but my experience leads me to believe that scaling errors are much more common than compatibility errors. Scaling errors are also much easier to avoid than compatibility errors. You don't need anything fancy, and you don't need any significant runtime overhead. All you need is something like this:

val meter = 1 // base unit
val km = 1000
val mm = 0.001
val cm = 0.01
val nmi = 1852 // nautical mile

val sec = 1 // base unit
val Min = 60
val hr = 60 * Min

val knot = nmi / hr
...

Compatibility errors are less common and more fundamental. If you are adding a length to a speed, your problem is more fundamental than incorrect units. Nevertheless, there should be a way to catch these errors too. That's where the problem gets much more complicated. And if you check unit compatibility at runtime, you impose a large overhead.

My approach is to provide a simple, efficient solution to the scaling problem, but do it in such a way that you can "switch on" the compatibility checks with no changes to the client code. The switching is done by swapping a single source file and recompiling or by maintaining compiled versions of both and modifying your class path. The compatibility checks only need to be done during once in a while, or while you are doing preliminary, fast testing. But even if you never bother with the compatibility checks, you still get perhaps 90% of the benefit. And if your application is not computationally intensive, you can simply  leave the compatibility checks on all the time.

Russ P.

--
http://RussP.us
Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

Russ Paielli skrev 2010-06-11 21:42:
> The Metascala units implementation looks interesting, but I see that it
> is pre-alpha and unstable. I wonder how well static units checking would
> work in practice and what it's basic limitations are.

The Metascala units represents a quantities unit as a vector of integral
exponents for the seven SI units. It's based on similar C++ template
implementations which I think work well in practice (except for the
sometimes incomprehensible compiler error messages :) ). It should be
possible to model units in other forms in the Scala type system, for
example as a list of unit and exponent pairs which would have the
advantage of being extendable with new unit "atoms".

The reason for the alpha status is simply that I haven't used the code
in a practical application. I don't do scientific programming myself (in
Scala at least), but it would be interesting to see the concept being
used in that context.

> Let me provide some background here. There are two basic types of unit
> errors. Let's call them scaling errors and compatibility errors.

My implementation should catch both types of errors are compile time.

/Jesper Nordenberg

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala
First off, I'll say that I'm not associated with Metascala in any way, and that I only used it once for a project half a year ago. I just think that it's worth discussing about, since a statically-typed unit system is preferred to a dynamically-typed unit system any day, and I'd like to see what advantages a dynamically-typed unit system could have.
On Fri, Jun 11, 2010 at 9:42 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
The Metascala units implementation looks interesting, but I see that it is pre-alpha and unstable. I wonder how well static units checking would work in practice and what it's basic limitations are. 
Arguing that something that is marked as alpha also is unstable is a fallacy. The Scala type system ensures that the Metascala Units implementation must be bug-free, and this is one of those few instances when you can say that something really is bug free... The implementation uses pure type-arithmetic, so it's even possible to prove that a given bug does not exist. The only way a bug could occur is if someone found a bug in the scala compiler.
The implementation isn't unstable, only incomplete, meaning that there only are pre-defined members for the base units (m, kg, s, a, k, mol, cd; aka meter, kilogram, second, ampère, kelvin, mol, candela). It is up to the user to e.g. define "val mm = m / 1000.0".
The basic limitations that the Metascala implementation has, is that it only supports powers up to 10 (aka you could max have an unit called m¹⁰kg¹⁰s¹⁰a¹⁰k¹⁰mol¹⁰cd¹⁰ or m⁻¹⁰kg⁻¹⁰s⁻¹⁰a⁻¹⁰k⁻¹⁰mol⁻¹⁰cd⁻¹⁰; anything beyond that won't work). This limitation can be changed by adding more types in http://trac.assembla.com/metascala/browser/src/metascala/Integers.scala on line 68 and 80. Oh, and please remember that the Universe only has 10 dimensions (some claim that it has 11, but that's pushing it), so adding more would be redundant ;-)
Another limitation is that there only are the 7 SI base units to choose from. This problem could be solved by e.g. using n-tuple type arithmetic for the types instead, or by using some kind of HList. There's usually no need for this, however, since all physics-based units can be expressed via the SI units.
Other limitations that the framework has are inherited from the Double type and related to "offset errors", see below; these limitations should also exist in a dynamically typed unit system, however.  
Let me provide some background here. There are two basic types of unit errors. Let's call them scaling errors and compatibility errors.
I would argue that there are two kinds of error, but that "scaling errors" isn't one of them.There are compatibility errors (as you explained) and offset errors.Why aren't there scaling errors? Because it's just factors we're talking about. By your reasoning, Ints should have 'scaling errors' too every time you multiply them together, since there's nothing that's keeping track on 'how much the Int has been multiplied'. Trivial factor management is, as you say, trivial, and not a problem in any system I know of. Or am I missing your point?
A greater issue is offset management, e.g. how do you convert °C into °F? You cannot do this with scaling alone, and the Metascala Units implementation is unable to handle this efficiently as well.  
Compatibility errors are less common and more fundamental. If you are adding a length to a speed, your problem is more fundamental than incorrect units. Nevertheless, there should be a way to catch these errors too. That's where the problem gets much more complicated. And if you check unit compatibility at runtime, you impose a large overhead.
The Metascala implementation checks this at compile-time for exactly this reason. 
My approach is to provide a simple, efficient solution to the scaling problem, but do it in such a way that you can "switch on" the compatibility checks with no changes to the client code. The switching is done by swapping a single source file and recompiling or by maintaining compiled versions of both and modifying your class path. The compatibility checks only need to be done during once in a while, or while you are doing preliminary, fast testing. But even if you never bother with the compatibility checks, you still get perhaps 90% of the benefit. And if your application is not computationally intensive, you can simply  leave the compatibility checks on all the time.
This is indeed a great feature, but it can as easily be done with a type-based system. By replacing lines 40-46 in Units.scala, so that every unit is defined to be 1 (e.g. "val m = 1"), and then by replacing line 48-59 with e.g. "type Length = Int" (This can all be done with Double too, of course), you suddenly get a completely Int-based unit system with incredible performance. There aren't even any implicits ;-)
As you can see, I fail to see the advantages with a runtime-based, dynamically typed and checked unit system.
Russ P.

Cheers,David Flemström 
Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: An Efficient Scalar Package in Scala

I use a mostly dynamically checked units system to keep track of
currencies through financial calculations. The particular currencies
involved aren't known at compile time. I don't think I could express
all of the constraints at compile time, although some of the
limitations were due to Java generics and might better tackled in
Scala.

-jason

On Fri, Jun 11, 2010 at 10:38 PM, David Flemström
wrote:
> As you can see, I fail to see the advantages with a runtime-based,
> dynamically typed and checked unit system.

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: An Efficient Scalar Package in Scala


On Fri, Jun 11, 2010 at 1:38 PM, David Flemström <david.flemstrom@gmail.com> wrote:
First off, I'll say that I'm not associated with Metascala in any way, and that I only used it once for a project half a year ago. I just think that it's worth discussing about, since a statically-typed unit system is preferred to a dynamically-typed unit system any day, and I'd like to see what advantages a dynamically-typed unit system could have.
On Fri, Jun 11, 2010 at 9:42 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
The Metascala units implementation looks interesting, but I see that it is pre-alpha and unstable. I wonder how well static units checking would work in practice and what it's basic limitations are. 
Arguing that something that is marked as alpha also is unstable is a fallacy.


I made no such argument. I merely repeated what I read on Mr. Nordenberg's own website about the code being unstable.
 
The Scala type system ensures that the Metascala Units implementation must be bug-free, and this is one of those few instances when you can say that something really is bug free... The implementation uses pure type-arithmetic, so it's even possible to prove that a given bug does not exist. The only way a bug could occur is if someone found a bug in the scala compiler.
The implementation isn't unstable, only incomplete, meaning that there only are pre-defined members for the base units (m, kg, s, a, k, mol, cd; aka meter, kilogram, second, ampère, kelvin, mol, candela). It is up to the user to e.g. define "val mm = m / 1000.0".
The basic limitations that the Metascala implementation has, is that it only supports powers up to 10 (aka you could max have an unit called m¹⁰kg¹⁰s¹⁰a¹⁰k¹⁰mol¹⁰cd¹⁰ or m⁻¹⁰kg⁻¹⁰s⁻¹⁰a⁻¹⁰k⁻¹⁰mol⁻¹⁰cd⁻¹⁰; anything beyond that won't work). This limitation can be changed by adding more types in http://trac.assembla.com/metascala/browser/src/metascala/Integers.scala on line 68 and 80. Oh, and please remember that the Universe only has 10 dimensions (some claim that it has 11, but that's pushing it), so adding more would be redundant ;-)

Limiting powers to 10 is not a practical limitation. No argument there.
 
Another limitation is that there only are the 7 SI base units to choose from. This problem could be solved by e.g. using n-tuple type arithmetic for the types instead, or by using some kind of HList. There's usually no need for this, however, since all physics-based units can be expressed via the SI units.
Other limitations that the framework has are inherited from the Double type and related to "offset errors", see below; these limitations should also exist in a dynamically typed unit system, however.  

Hey, if it works, that's wonderful. Maybe I'll even start using it myself someday. However, I think my approach is 98% as useful in practice.

Let me give some examples of what you can do with my approach but not with metascala. I'm not claiming these are important advantages -- maybe they are trivial, but here they are.

My approach allows non-integer exponents. These are rarely needed, but I have seen them in power spectral densities, for example. Maybe metascala could be modified to allow non-integer exponents too.

My approach allows new, arbitrary units to be easily created. Suppose you are doing inventory, and you want to keep a count of loaves of bread or bags of concrete. These are not standard physical units, but they are units, and you don't want to add bottles of wine to cases of wine, for example. Now, maybe it's a stretch, but I can imagine that dynamic type checking could potentially be useful for something like that.

 
Let me provide some background here. There are two basic types of unit errors. Let's call them scaling errors and compatibility errors.
I would argue that there are two kinds of error, but that "scaling errors" isn't one of them.There are compatibility errors (as you explained) and offset errors. Why aren't there scaling errors? Because it's just factors we're talking about. By your reasoning, Ints should have 'scaling errors' too every time you multiply them together, since there's nothing that's keeping track on 'how much the Int has been multiplied'. Trivial factor management is, as you say, trivial, and not a problem in any system I know of. Or am I missing your point?

Yes, I think you are missing the point. I have seen real-world examples of what I called scaling errors. In one case, confusion between radians and degrees contaminated six months of simulation results. In another case, a research engineer interpreted seconds as minutes and didn't become aware of the error until three years after the results were published. Then there is the widely publicized NASA error, in which a spacecraft was lost. If you don't think scaling errors are significant, you are sadly mistaken.

 
A greater issue is offset management, e.g. how do you convert °C into °F? You cannot do this with scaling alone, and the Metascala Units implementation is unable to handle this efficiently as well.  
Compatibility errors are less common and more fundamental. If you are adding a length to a speed, your problem is more fundamental than incorrect units. Nevertheless, there should be a way to catch these errors too. That's where the problem gets much more complicated. And if you check unit compatibility at runtime, you impose a large overhead.
The Metascala implementation checks this at compile-time for exactly this reason. 

But you can check it at runtime in short tests. You don't need to check it every time you run. Also, many applications are not computationally intensive, and checking it all the time is not a problem anyway.
 Russ P.

--
http://RussP.us
Danielk
Joined: 2009-06-08,
User offline. Last seen 3 years 21 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
That is really interesting! I didn't think static type checking of units could be encoded in the Scala type system without having 21^7 different types (the 7 SI units, powers -10 ... 10). I'll have to check that out and see how it's done :)

Just to be clear, would metascala flag the error in code like this:

val speed = 10 [m/s]
val mass = 5 [kg]
val energy : [joule] = speed * mass


/Daniel


On Fri, Jun 11, 2010 at 10:14 PM, Jesper Nordenberg <megagurka@yahoo.com> wrote:
Russ Paielli skrev 2010-06-11 21:42:
The Metascala units implementation looks interesting, but I see that it
is pre-alpha and unstable. I wonder how well static units checking would
work in practice and what it's basic limitations are.

The Metascala units represents a quantities unit as a vector of integral exponents for the seven SI units. It's based on similar C++ template implementations which I think work well in practice (except for the sometimes incomprehensible compiler error messages :) ). It should be possible to model units in other forms in the Scala type system, for example as a list of unit and exponent pairs which would have the advantage of being extendable with new unit "atoms".

The reason for the alpha status is simply that I haven't used the code in a practical application. I don't do scientific programming myself (in Scala at least), but it would be interesting to see the concept being used in that context.

Let me provide some background here. There are two basic types of unit
errors. Let's call them scaling errors and compatibility errors.

My implementation should catch both types of errors are compile time.

/Jesper Nordenberg


Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

Daniel Kristensen skrev 2010-06-12 01:12:
> That is really interesting! I didn't think static type checking of units
> could be encoded in the Scala type system without having 21^7 different
> types (the 7 SI units, powers -10 ... 10).

Now, that would be impractical. :) Besides there's nothing preventing
larger exponents than 10 to be used, it's just that there's no type
alias defined for them (you can still write 11 as Succ[10] for example).

> Just to be clear, would metascala flag the error in code like this:
>
> val speed = 10 [m/s]
> val mass = 5 [kg]
> val energy : [joule] = speed * mass

Yes, that's the idea.

/Jesper Nordenberg

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: An Efficient Scalar Package in Scala

On Sat, Jun 12, 2010 at 1:12 AM, Daniel Kristensen <daniel.kristensen@gmail.com> wrote:
Just to be clear, would metascala flag the error in code like this:

val speed = 10 [m/s]
val mass = 5 [kg]
val energy : [joule] = speed * mass


/Daniel
That'll not work, since energy has the unit Joule (kg * m² / s²) while (speed * mass) would have the unit (kg * m / s). This isn't Metascala's fault, however ;-)(Did you think about e=mc²? Because you forgot the ²)
Anyways, I tried to run the following code with Metascala HEAD and Scala 2.8.0.RC3, and it fails because of the slacking type inferencer (which is really strange since I remember it working on Scala 2.7, or it might have been 2.8.0.rsomethingsomething): ========================================import metascala.Integers._import metascala.Utils._import metascala.Addables._import metascala.Subtractables._import metascala.Units._
type Energy = Quantity[_2, _1, _2#Neg, _0, _0, _0, _0] //Energy isn't defined yetval joule = new Energy(1) //I could theoretically do something with joules now
val M: Mass = 1 * kg val C: Speed = 299792458 * m / s //←Compiler fails here alreadyval E: Energy = M * C * C========================================
I don't know what has changed since the release I successfully used, but this 
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
On Fri, Jun 11, 2010 at 1:14 PM, Jesper Nordenberg <megagurka@yahoo.com> wrote:
Russ Paielli skrev 2010-06-11 21:42:
The Metascala units implementation looks interesting, but I see that it
is pre-alpha and unstable. I wonder how well static units checking would
work in practice and what it's basic limitations are.

The Metascala units represents a quantities unit as a vector of integral exponents for the seven SI units. It's based on similar C++ template implementations which I think work well in practice (except for the sometimes incomprehensible compiler error messages :) ). It should be possible to model units in other forms in the Scala type system, for example as a list of unit and exponent pairs which would have the advantage of being extendable with new unit "atoms".

The reason for the alpha status is simply that I haven't used the code in a practical application. I don't do scientific programming myself (in Scala at least), but it would be interesting to see the concept being used in that context.

Let me provide some background here. There are two basic types of unit
errors. Let's call them scaling errors and compatibility errors.

My implementation should catch both types of errors are compile time.


Jesper,

I have taken a closer look at your Metascala units implementation, and I have a few comments. First, my hat is off to you for ingenuity. No argument there. However, I see a few important missing features . Most of them can probably be added, but I can think of at least one important missing feature that I don't think can be added. Please correct me if I am wrong.

First, you need a conversion to Double, preferably an implicit conversion. If a value is passed to a trig function (or any other function that takes a Double argument), you should automatically check to see if the scalar is dimensionless, and implicitly convert to a Double if it is. If it is not dimensionless, then you need to throw an exception (or prevent it from compiling). At the very least, you need an explicit conversion that checks for dimensionless status. I figure that can be done, but I am not sure.

By the way, how do you handle angular degrees? In my scheme, I can write

val x = sin(30 * deg)

and it gives the right result. Degree/radian errors are probably the most common unit error, and you need a good way to prevent them. How would that be done in your scheme?

Also, you need to deal with the atan2 function. In my scheme, I can write

val y = atan2(4 * km, 3 * km)

Can you do something like that? Note that the regular atan2 function will not work here, because it takes dimensionless arguments.

Finally, you need power and square root functions. Correct me if I am wrong, but this is where I think you have a serious problem. I don't think your ingenius scheme for simulating integer addition and subtraction of exponents will scale to multiplication and division.

To take a square root, you need to divide the exponents by 2. If you can't do that, you are dead in the water. Without square roots, you cannot even compute the distance between two points.

The problem here, I think, is that your solution is a just a bit too clever and boils down to a hack. Your clever simulation of integers is just not natural. But it was a nice try anyway.

IMO, to properly implement static checking of physical units in Scala, some new features would need to be added to the language, and I am not sure it can even be done.

Russ P.

--
http://RussP.us
Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
I'm pretty sure someone could write a compiler plugin that performs static unit checking at lets everything reduce back down to doubles (or any other desired numeric type) at runtime so there is no additional overhead.  I don't think the language needs to be directly modified...and probably shouldn't be.  This is a fairly special purpose feature.
On Fri, Jun 11, 2010 at 8:20 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Fri, Jun 11, 2010 at 1:14 PM, Jesper Nordenberg <megagurka@yahoo.com> wrote:
Russ Paielli skrev 2010-06-11 21:42:
The Metascala units implementation looks interesting, but I see that it
is pre-alpha and unstable. I wonder how well static units checking would
work in practice and what it's basic limitations are.

The Metascala units represents a quantities unit as a vector of integral exponents for the seven SI units. It's based on similar C++ template implementations which I think work well in practice (except for the sometimes incomprehensible compiler error messages :) ). It should be possible to model units in other forms in the Scala type system, for example as a list of unit and exponent pairs which would have the advantage of being extendable with new unit "atoms".

The reason for the alpha status is simply that I haven't used the code in a practical application. I don't do scientific programming myself (in Scala at least), but it would be interesting to see the concept being used in that context.

Let me provide some background here. There are two basic types of unit
errors. Let's call them scaling errors and compatibility errors.

My implementation should catch both types of errors are compile time.


Jesper,

I have taken a closer look at your Metascala units implementation, and I have a few comments. First, my hat is off to you for ingenuity. No argument there. However, I see a few important missing features . Most of them can probably be added, but I can think of at least one important missing feature that I don't think can be added. Please correct me if I am wrong.

First, you need a conversion to Double, preferably an implicit conversion. If a value is passed to a trig function (or any other function that takes a Double argument), you should automatically check to see if the scalar is dimensionless, and implicitly convert to a Double if it is. If it is not dimensionless, then you need to throw an exception (or prevent it from compiling). At the very least, you need an explicit conversion that checks for dimensionless status. I figure that can be done, but I am not sure.

By the way, how do you handle angular degrees? In my scheme, I can write

val x = sin(30 * deg)

and it gives the right result. Degree/radian errors are probably the most common unit error, and you need a good way to prevent them. How would that be done in your scheme?

Also, you need to deal with the atan2 function. In my scheme, I can write

val y = atan2(4 * km, 3 * km)

Can you do something like that? Note that the regular atan2 function will not work here, because it takes dimensionless arguments.

Finally, you need power and square root functions. Correct me if I am wrong, but this is where I think you have a serious problem. I don't think your ingenius scheme for simulating integer addition and subtraction of exponents will scale to multiplication and division.

To take a square root, you need to divide the exponents by 2. If you can't do that, you are dead in the water. Without square roots, you cannot even compute the distance between two points.

The problem here, I think, is that your solution is a just a bit too clever and boils down to a hack. Your clever simulation of integers is just not natural. But it was a nice try anyway.

IMO, to properly implement static checking of physical units in Scala, some new features would need to be added to the language, and I am not sure it can even be done.

Russ P.

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
On Fri, Jun 11, 2010 at 5:48 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
I'm pretty sure someone could write a compiler plugin that performs static unit checking at lets everything reduce back down to doubles (or any other desired numeric type) at runtime so there is no additional overhead.  I don't think the language needs to be directly modified...and probably shouldn't be.  This is a fairly special purpose feature.


I'll believe it when I see it. And as I pointed out in my previous message, it needs power and square root functions.

As far as I can tell, static type checking of physical units is a hack -- a clever hack, but a hack nonetheless.

Russ P.

--
http://RussP.us
Arthur Peters 2
Joined: 2009-01-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: An Efficient Scalar Package in Scala

I'm pretty sure the way people represent numbers in the scala type system is basically church numerals. And you can divid those. Though I don't remember how at the moment. It requires recursion but the scala type system has that I think.

-Arthur (sent from phone)

On Jun 11, 2010 9:09 PM, "Russ Paielli" <russ.paielli@gmail.com> wrote:

On Fri, Jun 11, 2010 at 5:48 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:

>
> I'm pretty sure someone could write a compiler plugin that performs static unit checking at lets...



I'll believe it when I see it. And as I pointed out in my previous message, it needs power and square root functions.

As far as I can tell, static type checking of physical units is a hack -- a clever hack, but a hack nonetheless.

Russ P.

--
http://RussP.us

Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: An Efficient Scalar Package in Scala

Russ Paielli skrev 2010-06-12 02:20:
> First, you need a conversion to Double, preferably an implicit
> conversion. If a value is passed to a trig function (or any other
> function that takes a Double argument), you should automatically check
> to see if the scalar is dimensionless, and implicitly convert to a
> Double if it is. If it is not dimensionless, then you need to throw an
> exception (or prevent it from compiling). At the very least, you need an
> explicit conversion that checks for dimensionless status. I figure that
> can be done, but I am not sure.

It's easily done:

implicit def quantityToDouble(q : Quantity[_0, _0, _0, _0, _0, _0, _0])
= q.value

> By the way, how do you handle angular degrees? In my scheme, I can write
>
> val x = sin(30 * deg)
>
> and it gives the right result. Degree/radian errors are probably the
> most common unit error, and you need a good way to prevent them. How
> would that be done in your scheme?

I'm not sure what you mean here. Is deg a unit or a constant factor?

> Also, you need to deal with the atan2 function. In my scheme, I can write
>
> val y = atan2(4 * km, 3 * km)
>
> Can you do something like that? Note that the regular atan2 function
> will not work here, because it takes dimensionless arguments.

There's nothing preventing you from writing your own unit safe
mathematical functions working on quantities instead of doubles. atan2
should handle units similar to division (ie subtract them) if I'm not
mistaken, and division is already defined in Metascala.

> Finally, you need power and square root functions. Correct me if I am
> wrong, but this is where I think you have a serious problem. I don't
> think your ingenius scheme for simulating integer addition and
> subtraction of exponents will scale to multiplication and division.

It's quite easy to define multiplication and division for Church
numerals. You will even get a compiler error if the division is not
possible, for example "_3 / _2".

> The problem here, I think, is that your solution is a just a bit too
> clever and boils down to a hack. Your clever simulation of integers is
> just not natural. But it was a nice try anyway.

I wouldn't call it a hack. It's limited to SI units and integral
exponents that's all. Both limitations can be worked around using
another representation for units. After all there's absolutely nothing
preventing you from encoding IEEE floating point arithmetic or rational
numbers in the Scala type system.

The limitation of fixed number of unit "atoms" is trickier to work
around as an optimal solution would require type equality checks which I
think is not possible to implement using the current Scala compiler. If
the unit "atoms" can be mapped to natural numbers it would work fine.

> IMO, to properly implement static checking of physical units in Scala,
> some new features would need to be added to the language, and I am not
> sure it can even be done.

I don't know how you came to that conclusion.

/Jesper Nordenberg

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
On Sat, Jun 12, 2010 at 10:17 AM, Jesper Nordenberg <megagurka@yahoo.com> wrote:
It's quite easy to define multiplication and division for Church numerals. You will even get a compiler error if the division is not possible, for example "_3 / _2".
I'm intrigued: how would this be done? I know from lambda calculus that it must be possible, but how would it map to the Scala type system?
Also: what about the type inference issue I had above, is this a new issue or not? 
The problem here, I think, is that your solution is a just a bit too
clever and boils down to a hack.
Scala has a strong type system, and it is there to be used. The whole Scala collections library would also have to be 'a hack' by this reasoning, since it also uses type checks to find source and target collection implementations. If the tools are there, why not use them? Especially when you're dealing with something like units, which is so easily mapped to types ("3 cm is of type Length", "17.3 joule is of type Energy"; this makes sense, and more so than "3 cm is of type Unit")
Danielk
Joined: 2009-06-08,
User offline. Last seen 3 years 21 weeks ago.
Re: Re: An Efficient Scalar Package in Scala
Actually leaving out the power was intentional - an error because of bad units is exactly what I wanted. Having the compiler prevent silly mistakes like trying to assign a momentum to a variable of unit energy seems very useful to me. Now if it could also warn me if I forget the integration factor ;) 

(val e: energy = mass * speed ^2  instead of val e: energy = mass * speed ^2 /2).

Seriously though, this is very impressive!

/Daniel




On Sat, Jun 12, 2010 at 1:49 AM, David Flemström <david.flemstrom@gmail.com> wrote:

On Sat, Jun 12, 2010 at 1:12 AM, Daniel Kristensen <daniel.kristensen@gmail.com> wrote:
Just to be clear, would metascala flag the error in code like this:

val speed = 10 [m/s]
val mass = 5 [kg]
val energy : [joule] = speed * mass


/Daniel
That'll not work, since energy has the unit Joule (kg * m² / s²) while (speed * mass) would have the unit (kg * m / s). This isn't Metascala's fault, however ;-)(Did you think about e=mc²? Because you forgot the ²)

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: Re: An Efficient Scalar Package in Scala


On Sat, Jun 12, 2010 at 1:17 AM, Jesper Nordenberg <megagurka@yahoo.com> wrote:
Russ Paielli skrev 2010-06-12 02:20:
First, you need a conversion to Double, preferably an implicit
conversion. If a value is passed to a trig function (or any other
function that takes a Double argument), you should automatically check
to see if the scalar is dimensionless, and implicitly convert to a
Double if it is. If it is not dimensionless, then you need to throw an
exception (or prevent it from compiling). At the very least, you need an
explicit conversion that checks for dimensionless status. I figure that
can be done, but I am not sure.

It's easily done:

implicit def quantityToDouble(q : Quantity[_0, _0, _0, _0, _0, _0, _0]) = q.value

By the way, how do you handle angular degrees? In my scheme, I can write

val x = sin(30 * deg)

and it gives the right result. Degree/radian errors are probably the
most common unit error, and you need a good way to prevent them. How
would that be done in your scheme?

I'm not sure what you mean here. Is deg a unit or a constant factor?


I have it as a unit, but now that you mention it, a constant Double will do.
 


Also, you need to deal with the atan2 function. In my scheme, I can write

val y = atan2(4 * km, 3 * km)

Can you do something like that? Note that the regular atan2 function
will not work here, because it takes dimensionless arguments.

There's nothing preventing you from writing your own unit safe mathematical functions working on quantities instead of doubles. atan2 should handle units similar to division (ie subtract them) if I'm not mistaken, and division is already defined in Metascala.

Yeah, now that I think about it some more, it shouldn't be a problem. You just divide one operand by the other and take note of the original signs.
 

Finally, you need power and square root functions. Correct me if I am
wrong, but this is where I think you have a serious problem. I don't
think your ingenius scheme for simulating integer addition and
subtraction of exponents will scale to multiplication and division.

It's quite easy to define multiplication and division for Church numerals. You will even get a compiler error if the division is not possible, for example "_3 / _2".


If that's the case, then I'd say you could be on your way to a reasonably complete, practical solution, with square roots and all. Let us know when you get it done. I would suggest you write at least a basic user guide too. I may give it a try.




The problem here, I think, is that your solution is a just a bit too
clever and boils down to a hack. Your clever simulation of integers is
just not natural. But it was a nice try anyway.

I wouldn't call it a hack. It's limited to SI units and integral exponents that's all. Both limitations can be worked around using another representation for units. After all there's absolutely nothing preventing you from encoding IEEE floating point arithmetic or rational numbers in the Scala type system.

It seemed like a hack to me because it doesn't look like normal Scala code, and you seem to have to do unusual "tricks" to do basic arithmetic on exponents, but I guess one man's hack is another man's elegant solution.

In any case, I'm on my way out the door to Big Sur for a few days of R&R on the Northern California coast.

Russ P.

--
http://RussP.us

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland