- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Ada-like typing in Scala?
Fri, 2009-01-09, 19:45
I'm fairly new to Scala and was wondering whether it offers a quick way to segregate primitive values like in Ada, which allows types to share an implementation (i.e. code reuse) but segregates their objects.
For example:
type Weight is new Float;
type Velocity is new Float;
A : Weight := 10;
B : Velocity := 20;
A := B -- this assignment is illegal, the compiler will complain
Implementing this in Java takes pages of code per type, which makes it impractical without code-generation. Despite Scala's massive superiority over Java, I can't see this being much easier in Scala. I'd be happy to be proven wrong, though.
Thanks for any thoughts.
Remarque concernant la sécurité:
Ce courriel provenant de PostFinance est signé. Vous trouverez d'autres informations à ce sujet sous:
https://www.postfinance.ch/e-signature.
Ne divulguez jamais vos éléments de sécurité à des tiers.
Fri, 2009-01-09, 20:37
#2
Re: Ada-like typing in Scala?
I don't think it takes "pages of code" in Java. For example, see:
http://www.jscience.org/api/org/jscience/physics/amount/package-summary.html#package_description
In Scala with a class similar to Amount, you could write something like:
implicit def amt2double(amt: Amount[_]) = amt.doubleValue()
type Weight = Amount[measure.Weight]
implicit def double2weight(f: Double) = new Weight(f)
type Velocity = Amount[measure.Velocity]
implicit def double2velocity(f: Double) = new Velocity(f)
var w: Weight = 100.0
var v: Velocity = 75.0
w = v //comile error
...and if you wrapped the conversions and type definitions in a module you could probably get it down to:
class AbstractAmount[T <: Measure] { /* some stuff, which would be in a library */ }
object Weight extends AbstractAmount[Weight]
import Weight._
On Fri, Jan 9, 2009 at 1:44 PM, <eugene.wagner@postfinance.ch> wrote:
--
http://erikengbrecht.blogspot.com/
On Fri, Jan 9, 2009 at 1:44 PM, <eugene.wagner@postfinance.ch> wrote:
I'm fairly new to Scala and was wondering whether it offers a quick way to segregate primitive values like in Ada, which allows types to share an implementation (i.e. code reuse) but segregates their objects.
For example:
type Weight is new Float;
type Velocity is new Float;
A : Weight := 10;
B : Velocity := 20;
A := B -- this assignment is illegal, the compiler will complain
Implementing this in Java takes pages of code per type, which makes it impractical without code-generation. Despite Scala's massive superiority over Java, I can't see this being much easier in Scala. I'd be happy to be proven wrong, though.
Thanks for any thoughts.
Remarque concernant la sécurité:
Ce courriel provenant de PostFinance est signé. Vous trouverez d'autres informations à ce sujet sous:
https://www.postfinance.ch/e-signature.
Ne divulguez jamais vos éléments de sécurité à des tiers.
--
http://erikengbrecht.blogspot.com/
Fri, 2009-01-09, 23:47
#3
Re: Ada-like typing in Scala?
It is a valid point however. As pointed out one can use phantom type to
parameterize a class to generate new types to sort Weight vs. Height. or
ShoeSize vs. HatSize but its a lot of cannon.
In a way the question is should Scala have 'type' for simple, transparent,
type aliasing and an equivalent to 'newtype' which is generative of an
opaque type in an object module. You just can't see its Int'ness but it
operates as an Int in the sense I can add two Weights, but not a Weight and
a Height.
So given:
object Weight {
type Weight = Int
def apply (n: Weight): Weight = n
}
object Height {
type Height = Int
def apply (n: Height): Height = n
}
Height (72) + Weight (100) // works as we are just Ints
It is transparent that Weight and Height are simple aliases for the same
type, Int.
But its often nice to be able generate module specific opaque types as well.
Something like:
object Weight {
newtype Weight = Int
def apply (n: Int): Weight = n
}
OR
object Weight {
new type Weight = Int
def apply (n: Int): Weight = n
}
Its funny, I seem to recall in SML I used to spend a great deal of energy
convincing the compiler that, yep, that type T in those 2 sigs and those 2
structs are really the same type T.
For simplicity, I like Scala's default, transparent, non-generative, simple
aliasing behaviour of 'type'. But it would be nice to have a 'newtype' as
well.
This would be an alternative to the Amount[Height], Amount[Weight] approach.
eugene.wagner wrote:
>
> I'm fairly new to Scala and was wondering whether it offers a quick way to
> segregate primitive values like in Ada, which allows types to share an
> implementation (i.e. code reuse) but segregates their objects.
>
> For example:
> type Weight is new Float;
> type Velocity is new Float;
> A : Weight := 10;
> B : Velocity := 20;
> A := B -- this assignment is illegal, the compiler will
> complain
>
> Implementing this in Java takes pages of code per type, which makes it
> impractical without code-generation. Despite Scala's massive superiority
> over Java, I can't see this being much easier in Scala. I'd be happy to
> be proven wrong, though.
>
> Thanks for any thoughts.
>
> Remarque concernant la sécurité:
> Ce courriel provenant de PostFinance est signé. Vous trouverez d'autres
> informations à ce sujet sous:
> https://www.postfinance.ch/e-signature.
> Ne divulguez jamais vos éléments de sécurité à des tiers.
>
>
Sat, 2009-01-10, 07:37
#4
Re: Re: Ada-like typing in Scala?
I would like to see this as well. The proposed existing solutions all have the serious problem of implementation overhead, i.e. the primitive Int or Double is wrapped into an object. What is being asked for is a type that is indistinguishable from Int or Double in implementation and exists solely to disallow improper mixing of Dollars and Euros, weight and height, or any other categories of numbers. Such a feature would greatly reduce the occurrence of bugs in computations, such as the one that doomed an expensive Mars probe a few years back. There would be no runtime cost at all.
Andreas
Sat, 2009-01-10, 10:17
#5
Re: Ada-like typing in Scala?
I don't think performance is a good incentive to add a language feature.
This should rather be fixed at a lower level, in the Scala compiler or
in the JVM. AFAIK, there has already been quite a bit of work on scalar
replacement in Open JDK which will reduce the overhead of object
wrappers substantially.
/Jesper Nordenberg
Windemuth Andreas wrote:
> I would like to see this as well. The proposed existing solutions all have the serious problem of implementation overhead, i.e. the primitive Int or Double is wrapped into an object. What is being asked for is a type that is indistinguishable from Int or Double in implementation and exists solely to disallow improper mixing of Dollars and Euros, weight and height, or any other categories of numbers. Such a feature would greatly reduce the occurrence of bugs in computations, such as the one that doomed an expensive Mars probe a few years back. There would be no runtime cost at all.
>
> Andreas
>
>
>
> ----- Original Message ----
> From: Jesper Nordenberg
> To: scala@listes.epfl.ch
> Sent: Friday, January 9, 2009 2:21:56 PM
> Subject: [scala] Re: Ada-like typing in Scala?
>
> eugene.wagner@postfinance.ch wrote:
>> I'm fairly new to Scala and was wondering whether it offers a quick way to segregate primitive values like in Ada, which allows types to share an implementation (i.e. code reuse) but segregates their objects.
>>
>> For example:
>> type Weight is new Float;
>> type Velocity is new Float;
>> A : Weight := 10;
>> B : Velocity := 20;
>> A := B -- this assignment is illegal, the compiler will complain
>>
>> Implementing this in Java takes pages of code per type, which makes it impractical without code-generation. Despite Scala's massive superiority over Java, I can't see this being much easier in Scala. I'd be happy to be proven wrong, though.
>>
>> Thanks for any thoughts.
>
> You can implement typed units in Scala, at least to some extent. See
>
> http://trac.assembla.com/metascala/browser/src/metascala/Units.scala
> http://trac.assembla.com/metascala/browser/src/metascala/test/UnitsTest....
>
> for an example.
>
> /Jesper Nordenberg
>
>
>
>
Sat, 2009-01-10, 11:37
#6
Re: Ada-like typing in Scala?
On Fri, Jan 09, 2009 at 07:44:48PM +0100, eugene.wagner@postfinance.ch wrote:
> type Weight is new Float;
> type Velocity is new Float;
> A : Weight := 10;
> B : Velocity := 20;
> A := B -- this assignment is illegal, the compiler will complain
trait NewType[A] {
type T
def apply(a : A) : T
def unwrap(t : T) : A
}
def newtype[A] : NewType[A] = new NewType[A] {
type T = A
def apply(a : A) = a
def unwrap(t : T) = t
}
val Weight = newtype[Float]
val Velocity = newtype[Float]
var a : Weight.T = Weight(10)
var b : Velocity.T = Velocity(10)
a = b // type error
You can probably get rid of the explicit wrappings with some implicit
conversions, but I'm not sure that's good style.
Lauri
Sat, 2009-01-10, 11:47
#7
Re: Re: Ada-like typing in Scala?
On Sat, 2009-01-10 at 10:12 +0100, Jesper Nordenberg wrote:
> I don't think performance is a good incentive to add a language feature.
> This should rather be fixed at a lower level, in the Scala compiler or
> in the JVM. AFAIK, there has already been quite a bit of work on scalar
> replacement in Open JDK which will reduce the overhead of object
> wrappers substantially.
>From my experiments, it's still unclear how much this will help in
practice so I would not rely on it just yet.
Ismael
Sat, 2009-01-10, 11:57
#8
Re: Ada-like typing in Scala?
On Sat, Jan 10, 2009 at 12:26:26PM +0200, Lauri Alanko wrote:
> trait NewType[A] {
> type T
> def apply(a : A) : T
> def unwrap(t : T) : A
> }
Regarding performance: although it's true that T gets erased into
Object and primitive types get wrapped, this is only a quality of
implementation issue. I don't think anything in the language
specification forbids heterogeneous compilation, i.e. creating a
different representation for NewType[A] when A is a primitive
type. The compiler just doesn't do this currently.
However, here's an alternative:
trait FloatType {
type T <: Float
def apply(a : Float) : T
def unwrap(t : T) : Float
}
def floattype : FloatType = new FloatType {
type T = Float
def apply(a : Float) = a
def unwrap(t : T) = t
}
val Weight = floattype
val Velocity = floattype
var a : Weight.T = Weight(10)
var b : Velocity.T = Velocity(10)
a = b // type error
Now FloatType.T gets erased into Float, and Weight.T and Velocity.T
are not compatible with each other. However, now both are compatible
with Float, which may or may not be desirable.
Lauri
eugene.wagner@postfinance.ch wrote:
> I'm fairly new to Scala and was wondering whether it offers a quick way to segregate primitive values like in Ada, which allows types to share an implementation (i.e. code reuse) but segregates their objects.
>
> For example:
> type Weight is new Float;
> type Velocity is new Float;
> A : Weight := 10;
> B : Velocity := 20;
> A := B -- this assignment is illegal, the compiler will complain
>
> Implementing this in Java takes pages of code per type, which makes it impractical without code-generation. Despite Scala's massive superiority over Java, I can't see this being much easier in Scala. I'd be happy to be proven wrong, though.
>
> Thanks for any thoughts.
You can implement typed units in Scala, at least to some extent. See
http://trac.assembla.com/metascala/browser/src/metascala/Units.scala
http://trac.assembla.com/metascala/browser/src/metascala/test/UnitsTest....
for an example.
/Jesper Nordenberg