-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Opaque types implementation #504
Comments
Has the syntax been decided yet? The consensus to Martin's |
I expect we'll go with the syntax from the SIP: |
Tentatively assigning to M5 to keep this on our radar. (I assume it won't be ready until after 2.13.0 final) |
Implementation note: one complication I hadn't considered so far is that baseTypeSeq is pre-computed, and I don't think we already have a mechanism to make sure abstract types in a BTS are treated in a context-dependent way. BTS works very differently in dotty, and would be hard to backport to scalac |
@adriaanm are you still thinking of slipping this into a 2.13.x release under |
Pretty please ... |
What do you think of using a value class with a private constructor instead? // Example taken from the current SIP
package object opaquetypes {
opaque type Logarithm = Double
object Logarithm {
// These are the ways to lift to the logarithm type
def apply(d: Double): Logarithm = math.log(d)
def safe(d: Double): Option[Logarithm] =
if (d > 0.0) Some(math.log(d)) else None
// This is the first way to unlift the logarithm type
def exponent(l: Logarithm): Double = l
// Extension methods define opaque types' public APIs
implicit class LogarithmOps(val `this`: Logarithm) extends AnyVal {
// This is the second way to unlift the logarithm type
def toDouble: Double = math.exp(`this`)
def +(that: Logarithm): Logarithm = Logarithm(math.exp(`this`) + math.exp(that))
def *(that: Logarithm): Logarithm = Logarithm(`this` + that)
}
}
} Alternate syntax, using private constructors of value classes: package object opaquetypes {
class Logarithm private (private val value: Double) extends AnyVal {
// This is the first way to unlift the logarithm type
def toDouble: Double = math.exp(value)
def +(that: Logarithm): Logarithm = Logarithm(math.exp(this.value) + math.exp(that.value))
def *(that: Logarithm): Logarithm = Logarithm(this.value + that.value)
}
object Logarithm {
// These are the ways to lift to the logarithm type
def apply(d: Double): Logarithm = new Logarithm(math.log(d))
def safe(d: Double): Option[Logarithm] =
if (d > 0.0) Some(Logarithm(d)) else None
// This is the second way to unlift the logarithm type
def exponent(l: Logarithm): Double = l.value
}
} The benefit is that we don’t need to introduce a new keyword, we can use plain old methods instead of extension methods, and also, it makes the syntax more similar to value classes, which is a good thing in my opinion because these features are similar. On the other hand, the statu quo has the advantage of having a syntax similar to “transparent” type aliases: defining an opaque type is just a matter of adding an |
I don't know if it has been considered in the SIP, but would it make sense to allow for type bounds in the opaque type definition? opaque type Logarithm <: Double = Double That would allow to use |
This was the very first design. It was rejected because that syntax is completely at odds with the semantics. Value classes are classes: they have a Opaque types do not have any of these things. Their semantics are literally the same as (transparent) type aliases, with one exception: they do not participate in subtying relationships outside the companion object. So using the type alias syntax with a modifier is a much better fit for the specific semantics that they carry. |
Will this be backported to 2.12.x? |
No, 2.12 is in maintenance mode.
…On Sun, Dec 16, 2018 at 06:36 kerr ***@***.***> wrote:
Will this be backported to 2.12.x?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#504 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFjyw2GmwkRYkTGOP-NOHj7u0elKhMuks5u5dvSgaJpZM4T6Fdm>
.
|
Will the |
Yes, see e.g. the immutable array example in the SIP: https://docs.scala-lang.org/sips/opaque-types.html#immutable-ie-write-once-arrays |
Now that 2.13.0 has been released, what's the current thinking on how long it is likely to be until this ships? |
I can see a way to support the self type encoding in 2.13 and support a subset of 3.0 opaque types in 2.14 (you’d have to be a bit more explicit inside the scope of the opaque type that your selecting the type member on this and not on the containing object). I can elaborate after scala days if you’re curious :) as soon as we’ve recovered from 2.13 and the conf, we’ll work on sharing and refining the 2.14 roadmap. |
So, will it happen? |
no, afraid not |
What if we prefer the previous opaque reply? |
implementation of https://docs.scala-lang.org/sips/opaque-types.html
will be available during the 2.13.x cycle under -Xsource:2.14. If all goes well, on by default in 2.14.0
The text was updated successfully, but these errors were encountered: