- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Implicit class + inline class SID (Scala Improvement Document)
Cross-posting to scala-language + scala-internals because I wasn't sure where else to push this.
You asked for it, and it's ready for public viewing! Here is a modified proposal for implicit classes that includes the ability to inline classes. The ulitmate goal of this proposal is for better 'implicit' performance within Scala. Specifically for the extension method + typeclass/typetrait patterns embedded in Scala implicits.
Please take a look and offer constructive feedback!
https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc07zPrzQ/edit?hl=en_US
Note: This proposal does not include any syntax sugar fixes for defining typeclasses. I have an alternative, much more controversial, SID that outlines an annotaiton-based approach to generating typeclass boilerlate. I can send it to those who are interested, because it's designed to be acheived via annotations + a compiler plugin currently.
- Josh
You asked for it, and it's ready for public viewing! Here is a modified proposal for implicit classes that includes the ability to inline classes. The ulitmate goal of this proposal is for better 'implicit' performance within Scala. Specifically for the extension method + typeclass/typetrait patterns embedded in Scala implicits.
Please take a look and offer constructive feedback!
https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc07zPrzQ/edit?hl=en_US
Note: This proposal does not include any syntax sugar fixes for defining typeclasses. I have an alternative, much more controversial, SID that outlines an annotaiton-based approach to generating typeclass boilerlate. I can send it to those who are interested, because it's designed to be acheived via annotations + a compiler plugin currently.
- Josh










Re: Implicit class + inline class SID (Scala Improvement Docume
--Rex
On Mon, Aug 22, 2011 at 8:29 AM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 4:36 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 4:36 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
I specifically proposed @inline(SILENT), which means that if the implicit class can't be inlined, the compiler won't complain (but won't inline it either).
Unless you mean that if you @inline something, it only complains at _use_ sites and not if the class itself is inherently incompatible. In that case, if you really need to distinguish the two, I suggest adding another option to the annotation to make the compiler try to incorporate inlining information into the class, but not to complain if it can't (and then use that on the implicit classes).
One of the main lessons I've learned from Java is that the common use cases should be easy to type or when reading code you public static final get lost in the mostly-meaningless clutter throws IDontCareAboutThisException.
--Rex
On Mon, Aug 22, 2011 at 4:48 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
Note: One option for inline classes is that the compiler can do inline checking for *every* class and only use the annotation to *ensure* that the optimization happens (like @tailrec and @switch). In that case, there would be no issue with adding @inline or not, and @inline(SILENT) would go away.
- Josh
On Mon, Aug 22, 2011 at 6:47 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
So I could argue it approaches 99% for me.
--Rex
On Mon, Aug 22, 2011 at 6:59 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
1. It seems to me that the inlining semantics moves a lot of runtime responsibility into the semantics of the language. To me this is a smell, the language should be optimized for expressibility and not concern it self with the runtime semantics too much.
I do think it can, and should, make sure that the language semantics is such that certain runtime optimization _can_ be performed.
So IMHO an alternative approach would be to just specify that @inline means that an object instantiation _can_ be inlined, but not enforce in the language semantics that it _will_ be inlined. Then add a compiler option to scalac that enforce the inlining in the compiler. Not as a language semantic but as a compiler feature.
Now that is just my opinion. What triggers it is that the SID specifies not only inlining of object construction but also of method calls. While the former is not very reliable on current VMs the latter should be solid by now.
2. The SID explicitly targets performance of a particular pattern aimed at syntactic convenience. I agree with the general approach of removing the runtime semantics implied by the pattern, they are, so to speak, accidental complexity. I also think it is a good thing that the implicit class syntax remove some boilerplate associated with expressing the pattern.
However, as the goal of the changes in this SID seems to be to remove class semantics from the boiler plate required to gain a purely syntactic benefit, maybe a better approach is to add a syntactic sugar not implying any class semantics in the first place? Besides, adding implicit semantics to classes might introduce conflicts with other ways of addressing the boilerplate.
So, if the motivation is to gain infix notation for type classes maybe explicit support for infix operations could be added?
trait TypeClass[T] {
def operation(t1:T,t2:T):T
infix @ = operation
}
or
trait TypeClass[T] {
def (t1:T) @ (t1:T): T
}
I'm just addressing the use of implicit classes for infix methods of type classes here. The use of implicit classes when one really wants class semantics is a nice addition. I just fear that it might interfere with more targeted boilerplate reductions for the type class pattern.
BR,
John
On Mon, Aug 22, 2011 at 2:29 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 3:58 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
I think we need both at this point in time to be able to inline the most common pattern:
@inline implicit final def impOps(x: Foo) = new FooOps(x)*and* @inline class FooOps(x: Foo) { def +(y: Foo) = ...}
(x: Foo) + y
desugars to:
impOps(x).+(y)
Which would *not* have any inlining. You need to have both in the compiler so that the interactions between class inlining and method inlining happen. Otherwise you're severely restricting the later. You're right that if the JVM optimised this, it would not be needed.
As for making it optional... I'd prefer to have this optimisation on by default, but I could see adding a flag to prevent it's occurrence. As for the annotation, I see it more akin to the "tailrec" optimisation. It ensures that something can, and is, optimised so there is no confusion as to what's happening. However, unlike those others, I think the search space for inline classes may be too high to justify running on un-annotated classes.
Look forward to your thoughts on these responses :)
- Josh
There's actually a separate SID for type classes. This SiD will just bring their performance up-to-snuff if they use "Ops" classes. The implicit class portion of this proposal is targeted at "extension method" patterns in Scala, which typeclass Ops are but a small fraction of. the Rich* classes in Scala are other examples.
My specific proposal for typeclasses is not quite ready for prime time viewing. It's a very controversial topic, as I'm sure the syntax you suggested, if it were in a proposal, would be as well. However, I appreciate the ideas, and I'll incorporate them in the second proposal. I'd like to focus on the inlining proposal first, because this remove the runtime punishments for using type-class + extension method patterns.
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 3:58 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
I think we need both at this point in time to be able to inline the most common pattern:
@inline implicit final def impOps(x: Foo) = new FooOps(x)*and* @inline class FooOps(x: Foo) { def +(y: Foo) = ...}
(x: Foo) + y
desugars to:
impOps(x).+(y)
Which would *not* have any inlining. You need to have both in the compiler so that the interactions between class inlining and method inlining happen. Otherwise you're severely restricting the later. You're right that if the JVM optimised this, it would not be needed.
As for making it optional... I'd prefer to have this optimisation on by default, but I could see adding a flag to prevent it's occurrence. As for the annotation, I see it more akin to the "tailrec" optimisation. It ensures that something can, and is, optimised so there is no confusion as to what's happening. However, unlike those others, I think the search space for inline classes may be too high to justify running on un-annotated classes.
Look forward to your thoughts on these responses :)
- Josh
There's actually a separate SID for type classes. This SiD will just bring their performance up-to-snuff if they use "Ops" classes. The implicit class portion of this proposal is targeted at "extension method" patterns in Scala, which typeclass Ops are but a small fraction of. the Rich* classes in Scala are other examples.
My specific proposal for typeclasses is not quite ready for prime time viewing. It's a very controversial topic, as I'm sure the syntax you suggested, if it were in a proposal, would be as well. However, I appreciate the ideas, and I'll incorporate them in the second proposal. I'd like to focus on the inlining proposal first, because this remove the runtime punishments for using type-class + extension method patterns.
Re: Implicit class + inline class SID (Scala Improvement Docume
I was actually reacting at "a third pass of the inliner will attempt to remove any method calls after class inlining has been acheived" which, granted, was a little bit knee-jerk. Given the first two inlining passes I guess nothing significantly different is introduced by a third pass. It just strikes me as something belonging to the runtime. I'm a bit weary of removing information about the original program before it VM has chance to look at it.
Yes, I can see how the first pass is required to enable the second pass. I'm thinking that all three passes can be avoided given a different language semantic though.
I'm not against having it on by default. I'm just thinking that it should be defined as a feature of the typsafe implementation of a scala compiler and not feature of the language as such.
Now back to the @inline vs implicit class semantic:
If, instead of generating an implicit def, the implicit lookup rules are changed to also look for implicit constructors (now theres an interesting distinction, is it a constructor for an implicit class, or is it an implicit constructor for a class? The latter allows for more than one implicit definition for the same class...) there is no longer a need for the factory method, and thus no need for the first inlining pass.
So at least the inlining is limited to just construction. I still maintain, though, that the implied semantics
of "@inline implicit class" is to nullify the effects of "new". Which feel awkward, why do I need to use one language construct to remove the effects of another when I can just not use the one I want to avoid?
I think Pimp my Library as well as type classes share the common problem of wanting convenient syntax without paying the object tax. Its not only the possible overhead of heap allocation (a concern that really shouldn't have anything to do with the language, being entirely a runtime implementation issue), it's also questions like do my wrapper have a separate identity? What does "this" mean when defining an extension method? Can I place a lock on the wrapper? Will another method call to the "same" object see the lock?
All those questions are, in my opinion, valid reasons for wanting to remove the effects of new. But in my mind we are searching for a language construct that gives us what we want, instead of one that removes what we don't want. And if I understand what is left after we remove new it's just some infix method calls.
BR,
John
Re: Implicit class + inline class SID (Scala Improvement Docume
I see what you're saying with the third pass to remove methods. I can remove that from the SID as it's most likely not necessary, and we do want the JVM to do what it does best.
I understand what you're saying about taking things we don't want away. Isn't that what the inline class proposal is doing? Removing the performance hit for simple wrapper classes? This goes beyond 'extension method' and 'type trait' idioms.
As for the implicit class syntax, I personally am a fan, but when push comes to shove it's the inline class stuff I want in Scala ASAP. I can wait for sugar, but performance is powerful. I do think the proposed syntax makes sense, but your idea of implicit *constructors* is really powerful. I'm hoping Martin is reading this to discuss. However, if it's an implicit constructor, I would guess the annotation (implicit in this case) would have to be where constructor annotations exist, which feels a bit odd. Let me toy with that idea (and farm it around) a bit, as i think you may be onto something big.
- Josh
On Mon, Aug 22, 2011 at 6:35 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
I see what you're saying with the third pass to remove methods. I can remove that from the SID as it's most likely not necessary, and we do want the JVM to do what it does best.
I understand what you're saying about taking things we don't want away. Isn't that what the inline class proposal is doing? Removing the performance hit for simple wrapper classes? This goes beyond 'extension method' and 'type trait' idioms.
As for the implicit class syntax, I personally am a fan, but when push comes to shove it's the inline class stuff I want in Scala ASAP. I can wait for sugar, but performance is powerful. I do think the proposed syntax makes sense, but your idea of implicit *constructors* is really powerful. I'm hoping Martin is reading this to discuss. However, if it's an implicit constructor, I would guess the annotation (implicit in this case) would have to be where constructor annotations exist, which feels a bit odd. Let me toy with that idea (and farm it around) a bit, as i think you may be onto something big.
- Josh
On Mon, Aug 22, 2011 at 6:35 PM, John Nilsson <john [at] milsson [dot] nu> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
How about overriding the generated implicit definition?
One useful thing which I can do with the current idiom is:
trait Functionality { implicit def addFunction[T](t: T) = new AddFunction(t) class AddFunction[T](t: T) { def function = ... }}
and
trait Client extends Functionality { // "deactivate" the implicit override def addFunction[T](t: T) = super.addFunction(t)
// "string".function will not compile anymore}
For this to work with implicit classes, I have to rely on the generated name for the implicit definition, don't I? Is it an issue?
Thanks,
Eric.
Re: Re: Implicit class + inline class SID (Scala Improvement D
It's still a good point though... how to remove implicits.
Note: A non-final class in a trait may not get inlined in an expression, depending on where it shows up. The compiler has to know that the class is closed when it inlines things. Therefore your method would have to be final to be inlined, as would the class itself. That's an interesting wrinkle in the implicit class proposal.
let me think about that one, any ideas welcome :)
- Josh
On Mon, Aug 22, 2011 at 7:34 PM, etorreborre <etorreborre [at] gmail [dot] com> wrote:
Re: Re: Implicit class + inline class SID (Scala Improvement D
It's still a good point though... how to remove implicits.
Note: A non-final class in a trait may not get inlined in an expression, depending on where it shows up. The compiler has to know that the class is closed when it inlines things. Therefore your method would have to be final to be inlined, as would the class itself. That's an interesting wrinkle in the implicit class proposal.
let me think about that one, any ideas welcome :)
- Josh
On Mon, Aug 22, 2011 at 7:34 PM, etorreborre <etorreborre [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
might have superclass(es), as in
class RichInt(n: Int) extends Ordered[Int]
this is not trivial so to check; you'd need know that the super constructor call is side-effect-free, and you end up needing an effect system.. What's the plan? Just trust the user that inlining is fine when he writes "@inline class"?
Lukas
On Mon, Aug 22, 2011 at 14:29, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
This is really great stuff!
Now to my constructive feedback. ;-)
I think it would be nice to be able to define implicit classes at the
top level. The generated implicit method could then be put in a
generated companion object. But the question would be how to import
the implicit conversion then. Importing using the name of the implicit
class would not work, which is a shame. Am I right that this is one of
the reasons why the proposal does not allow implicit classes at the
top level?
But why does it say in the "Specification" paragraph: "The language
specification (SLS 7.1) would be modified to allow the use of the
implicit modifier for classes, even at the top-level."? Emphasis on
"even at the top-level".
Also, I like the idea of desugaring implicit class method invocations
to static method calls. It would be nice if this was also done when
not using the optimizer, as I'm always quite hesitant to use it, given
its track record of not speeding things up, slowing down compilation
and introducing bugs (at least it seems to me this way).
Regards,
Rüdiger
2011/8/22 Josh Suereth :
> Cross-posting to scala-language + scala-internals because I wasn't sure
> where else to push this.
>
> You asked for it, and it's ready for public viewing! Here is a modified
> proposal for implicit classes that includes the ability to inline classes.
> The ulitmate goal of this proposal is for better 'implicit' performance
> within Scala. Specifically for the extension method + typeclass/typetrait
> patterns embedded in Scala implicits.
> Please take a look and offer constructive feedback!
> https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc...
>
> Note: This proposal does not include any syntax sugar fixes for defining
> typeclasses. I have an alternative, much more controversial, SID that
> outlines an annotaiton-based approach to generating typeclass boilerlate. I
> can send it to those who are interested, because it's designed to be
> acheived via annotations + a compiler plugin currently.
> - Josh
>
Re: Implicit class + inline class SID (Scala Improvement Docume
This is really great stuff!
Now to my constructive feedback. ;-)
I think it would be nice to be able to define implicit classes at the
top level. The generated implicit method could then be put in a
generated companion object. But the question would be how to import
the implicit conversion then. Importing using the name of the implicit
class would not work, which is a shame. Am I right that this is one of
the reasons why the proposal does not allow implicit classes at the
top level?
But why does it say in the "Specification" paragraph: "The language
specification (SLS 7.1) would be modified to allow the use of the
implicit modifier for classes, even at the top-level."? Emphasis on
"even at the top-level".
Also, I like the idea of desugaring implicit class method invocations
to static method calls. It would be nice if this was also done when
not using the optimizer, as I'm always quite hesitant to use it, given
its track record of not speeding things up, slowing down compilation
and introducing bugs (at least it seems to me this way).
Regards,
Rüdiger
2011/8/22 Josh Suereth :
> Cross-posting to scala-language + scala-internals because I wasn't sure
> where else to push this.
>
> You asked for it, and it's ready for public viewing! Here is a modified
> proposal for implicit classes that includes the ability to inline classes.
> The ulitmate goal of this proposal is for better 'implicit' performance
> within Scala. Specifically for the extension method + typeclass/typetrait
> patterns embedded in Scala implicits.
> Please take a look and offer constructive feedback!
> https://docs.google.com/document/d/1k-aGAGmbrDB-2pJ3uDPpHVKno6p-XbnkVHDc...
>
> Note: This proposal does not include any syntax sugar fixes for defining
> typeclasses. I have an alternative, much more controversial, SID that
> outlines an annotaiton-based approach to generating typeclass boilerlate. I
> can send it to those who are interested, because it's designed to be
> acheived via annotations + a compiler plugin currently.
> - Josh
>
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 9:22 AM, Ruediger Keller <ruediger [dot] keller [at] rk42 [dot] de> wrote:
I think you nailed it on the head. This is a no-go because it means 'implicit class ' operates differently from every other 'implicit foo' in the language. However you *could* put the implicit class on a package object, which is akin to top-level.
Copy-Paste Error!!! Good catch, thanks!
That's a great question. I want @inline classes to work regardless of -optimise or not, but the aggression of it may change...
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 9:22 AM, Ruediger Keller <ruediger [dot] keller [at] rk42 [dot] de> wrote:
I think you nailed it on the head. This is a no-go because it means 'implicit class ' operates differently from every other 'implicit foo' in the language. However you *could* put the implicit class on a package object, which is akin to top-level.
Copy-Paste Error!!! Good catch, thanks!
That's a great question. I want @inline classes to work regardless of -optimise or not, but the aggression of it may change...
Re: Implicit class + inline class SID (Scala Improvement Documen
Another thing: Is it true that, given an implicit class, it is not
possible to define a companion object for that class? I think that's the
case because for an 'implicit class Foo' there will be a generated
method called 'Foo'; adding an 'object Foo' would result in a name clash.
(Sorry if that's obvious, but I couldn't find anything about it.)
Re: Implicit class + inline class SID (Scala Improvement Documen
Another thing: Is it true that, given an implicit class, it is not
possible to define a companion object for that class? I think that's the
case because for an 'implicit class Foo' there will be a generated
method called 'Foo'; adding an 'object Foo' would result in a name clash.
(Sorry if that's obvious, but I couldn't find anything about it.)
Re: Re: Implicit class + inline class SID (Scala Improvement Do
- Josh
On Mon, Aug 22, 2011 at 4:00 PM, Lars Hupel <hupel [at] in [dot] tum [dot] de> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
might have superclass(es), as in
class RichInt(n: Int) extends Ordered[Int]
this is not trivial so to check; you'd need know that the super constructor call is side-effect-free, and you end up needing an effect system.. What's the plan? Just trust the user that inlining is fine when he writes "@inline class"?
Lukas
On Mon, Aug 22, 2011 at 14:29, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
for example RichInt could be marked @inline if all parents were also @inline, and then we can place restrictions on constructors to compile.... WDYT?
On Mon, Aug 22, 2011 at 9:21 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
On 22 August 2011 14:21, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
It does seem that most fun things we'd like to do with improving the scala compiler come back to this.
Matthew
--
Dr Matthew PocockVisitor, School of Computing Science, Newcastle Universitymailto: turingatemyhamster [at] gmail [dot] com gchat: turingatemyhamster [at] gmail [dot] commsn: matthew_pocock [at] yahoo [dot] co [dot] uk irc.freenode.net: drdozertel: (0191) 2566550mob: +447535664143
Re: Implicit class + inline class SID (Scala Improvement Docume
for example RichInt could be marked @inline if all parents were also @inline, and then we can place restrictions on constructors to compile.... WDYT?
On Mon, Aug 22, 2011 at 9:21 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Re: Implicit class + inline class SID (Scala Improvement Docume
Begin forwarded message:
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 15:34, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Sounds reasonable to me. An easy solution to check purity would be to allow only methods in @inline classes, no fields.
Re: Implicit class + inline class SID (Scala Improvement Docume
On Mon, Aug 22, 2011 at 15:34, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
Sounds reasonable to me. An easy solution to check purity would be to allow only methods in @inline classes, no fields.
Re: Implicit class + inline class SID (Scala Improvement Docume
I think it's awesome, but it needs more cowbell!
On Mon, Aug 22, 2011 at 2:29 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
--
Viktor Klang
Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts
Twitter: @viktorklang
Re: Implicit class + inline class SID (Scala Improvement Docume
I think it's awesome, but it needs more cowbell!
On Mon, Aug 22, 2011 at 2:29 PM, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
--
Viktor Klang
Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts
Twitter: @viktorklang
Re: Re: Implicit class + inline class SID (Scala Improvement D
2011/8/22 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
Re: Re: Implicit class + inline class SID (Scala Improvement D
2011/8/22 √iktor Ҡlang <viktor [dot] klang [at] gmail [dot] com>
Re: Re: Implicit class + inline class SID (Scala Improvement D
Thanks,
Matthew
On 22 August 2011 14:09, Josh Suereth <joshua [dot] suereth [at] gmail [dot] com> wrote:
--
Dr Matthew PocockVisitor, School of Computing Science, Newcastle Universitymailto: turingatemyhamster [at] gmail [dot] com gchat: turingatemyhamster [at] gmail [dot] commsn: matthew_pocock [at] yahoo [dot] co [dot] uk irc.freenode.net: drdozertel: (0191) 2566550mob: +447535664143