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

On the topic of the 'pimp-my-library' pattern and performance

16 replies
David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Scalaites,
I will try to keep this message as brief as possible, but I will still try to keep it understandable.

I currently observe three things when using Scala:
  1. Implicit defs with more than one parameter have very limited use
  2. There is currently no way to use "pimp-my-library" without either sacrificing performance or relying on your client having the latest HotSpot JVM (a luxury that not everyone has) to optimize away the flaws in your code.
  3. It is currently a syntax error to have curried methods with implicit argument lists in any position other than at the end.
To elaborate:
  1. Code like the following is useful:
    ========================================
    implicit def int2x(left: Int) = new {
      def x(right: Int) = { println("do something"); left * right }
    }
    1 x 4
    ========================================
    This code, not so much (there are of course use cases but they are rare, and unaffected by my proposals below):
    ========================================
    implicit def convert(x: Int, y: Int) =
      println("""There are very few realistic use cases where
    you'd need a method like this""")

    def contrivedExample(x: Int)(implicit y: (Int, Int) => Unit) {
      println("Heed these words of wisdom:")
      y(2, 3)
    }
    contrivedExample(5)
    ========================================

  2. The first code example as seen under 1. makes any call to x() via Int relatively expensive, since a wrapper object has to be created for each call. This adds up with the number of calls if your JVM can't do JIT or has very limited abilities, and even with a JIT such as HotSpot, it wastes some, if not essential then at least better spendable, resources.

  3. You can have a method like:
    ========================================
    def method[T](x: t)(implicit manifest: Manifest[T], num: Numeric[T]) = ...
    ========================================
    ...but not like:
    ========================================
    def method(implicit x: Int)(y: Int) = ...
    ========================================
I therefore have two proposals, one of which I would like to see implemented in the Scala compiler (I favor the second one):

Proposal 1:Given the code:
========================================
implicit def method(x0: A, x1: B, x2: C, x3: D, ..., xN: Z): T = ...
y0.method(y1, y2, y3, ..., yN)
y0 method (y1, y2, y3, ..., yN)
========================================
...the compiler should transform it to (via desugaring):
========================================
implicit def method(x0: A, x1: B, x2: C, x3: D, ..., xN: Z): T = ...
method(y0, y1, y2, y3, ..., yN)
method(y0, y1, y2, y3, ..., yN)
========================================This is rather self-explanatory, and addresses points 1 and 2 above.
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================This makes more sense than the above proposal, addresses points 2 and 3 above, and is rather similar to the feature that was introduced in C# ~3.0. The "implicit" keyword may be unfit for this use, however, in which case another one could be chosen.
Neither of these additions should break any existing code. The potential use cases for one of these features are, at least to me, seemingly endless. It is currently not possible to implement one of these as a compiler plugin, because of the involved syntax changes.
I would like to hear everyone's opinions.
David Flemström
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performan

On Sat, Jan 02, 2010 at 08:24:29PM +0100, David Flemström wrote:
> def times(implicit x: Int)(y: Int) = x * y
> def times2(implicit x: Int)(y: Int)(z: Int) = x * y * z
> times(x)(y)
> times(x)(y)
> times2(x)(y)(z)

+1 to this or something like it if martin can be convinced.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
On Sat, Jan 2, 2010 at 2:24 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================

I like the idea of being able to do something like this, and I think this one slightly better, though I dislike the implicit keyword.  The parameter isn't implicit at all--it's explicit, just in a different position.  Maybe "this" instead, to signify that the parameter can appear on the left as though it's the caller?  And then you could allow it anywhere, and not have confusion with a single-argument implicit.  For example:

def times(this x: Int,y: Int) = x * y
5 times 7

def consString(s: String,this ls:List[String]) = s :: ls
s consString ls

  --Rex

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performa

Why can the compiler not optimize the implicit wrapper away? In fact,
I believe with -optimize we are already there in many situations.
Adding new language rules seems quicker in the short run but isn't if
you consider the following:

- new rules mean that all language books become outdated and have to
be rewritten.

- all IDEs have to be updated.

- the language becomes more complex, so barrier to entry increases.

Compared to this some serious investment in the Scala optimizer is
excellent value.

Cheers

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
On Sat, Jan 2, 2010 at 11:41 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
Compared to this some serious investment in the Scala optimizer is
excellent value.
 So you mean that the special case(s) of========================================
implicit def first(y: Z) = new { def a = y; def b = y }implicit def second(y: Z) = new AnyRef { def c(d: Z) = d; def e(f: Z) = f } (new Z).a.b.c((new Z).e(new Z))========================================...could be expanded?That would be a very concrete optimization, but if it does the job, I don't see why not. How would it be expanded, though? To something like this maybe:========================================def first_a(y: Z) = y //replace "_" with the usual "$uid$" stuffdef first_b(y: Z) = y def second_c(y: Z)(d: Z) = ddef second_e(y: Z)(f: Z) = fsecond_c(first_b(first_a(new Z)), second_e(new Z, new Z))========================================
Sounds like a plan if it is done like that, but as I said: it's a  very concrete optimization. As soon as the "new {}" part gets some kind of state, extends another class or does something similar, it becomes "impossible" to apply the optimization.
Also, the compiler grows by the second with more and more special-case optimizations it seems. We all know that the JVM is (partly) to blame of course, and that there might be nothing we can do about it, but still; some warning bells should start to ring when compile times go above 10 seconds via "scalac" (using "fsc" is cheating :-) ) for just a single code file.
(Hoping that the CLI port of Scala will mature soon so that a lot of this chaos can come to an end, as I'm sure it will, in time)
David Flemström
John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
I know Martin has already voiced his opinion on the issue. But I'd like to add an option that might be worth pursuing
defs allready supports multiple parameter lists, maybe one could add the option to have parameter lists to the left of the def ?
This
def (x:Int)times(y:Int) = ...
x.times(y) would be a type error, but
(x)times(y)x times yx ops.times y // If times as defined in the object referenced by ops
would not.
BR,John
On Sat, Jan 2, 2010 at 8:24 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================This makes more sense than the above proposal, addresses points 2 and 3 above, and is rather similar to the feature that was introduced in C# ~3.0. The "implicit" keyword may be unfit for this use, however, in which case another one could be chosen.
Neither of these additions should break any existing code. The potential use cases for one of these features are, at least to me, seemingly endless. It is currently not possible to implement one of these as a compiler plugin, because of the involved syntax changes.
I would like to hear everyone's opinions.
David Flemström

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
I'm pretty much with Martin on this one. Why define a new syntax whose only purpose is to tell the compiler to optimize away an object creation? That's the job of the compiler -- or even the VM --, not the programmer.

On Sun, Jan 3, 2010 at 2:59 AM, John Nilsson <john [at] milsson [dot] nu> wrote:
I know Martin has already voiced his opinion on the issue. But I'd like to add an option that might be worth pursuing
defs allready supports multiple parameter lists, maybe one could add the option to have parameter lists to the left of the def ?
This
def (x:Int)times(y:Int) = ...
x.times(y) would be a type error, but
(x)times(y)x times yx ops.times y // If times as defined in the object referenced by ops
would not.
BR,John
On Sat, Jan 2, 2010 at 8:24 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================This makes more sense than the above proposal, addresses points 2 and 3 above, and is rather similar to the feature that was introduced in C# ~3.0. The "implicit" keyword may be unfit for this use, however, in which case another one could be chosen.
Neither of these additions should break any existing code. The potential use cases for one of these features are, at least to me, seemingly endless. It is currently not possible to implement one of these as a compiler plugin, because of the involved syntax changes.
I would like to hear everyone's opinions.
David Flemström




--
Daniel C. Sobral

I travel to the future all the time.
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
Does the -optimize elide the creation of implicit wrappers?

This would be very welcome news!

--j

On Sat, Jan 2, 2010 at 4:41 PM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
Why can the compiler not optimize the implicit wrapper away? In fact,
I believe with -optimize we are already there in many situations.
Adding new language rules seems quicker in the short run but isn't if
you consider the following:

 - new rules mean that all language books become outdated and have to
be rewritten.

 - all IDEs have to be updated.

 - the language becomes more complex, so barrier to entry increases.

Compared to this some serious investment in the Scala optimizer is
excellent value.

Cheers

John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
I don't think this is only about optimization. I see it as different things.
In the implicit wrapping case you are creating an object, with a reference you can pass along to other parts of the code, with dynamic dispatching, state and whatever other semantics you want.
With the "optimized" version you are clearly just applying a calculation, further more this calculation is statically dispatched.
From my point of view the semantics is sufficiently different to allow the alternative to be reasoned about as more than an "optimization".
Now, I don't know if the difference is actually useful. But I have some hunches.1. By knowing that the allocation won't need to be "optimized" away there is less things to worry about, brain cycles I can spend on other things. 
2. Maybe an alternate syntax will allow for better formulations of DSLs?3. Maybe the different semantics allow for other invariants or more flexibility?
BR,John
On Sun, Jan 3, 2010 at 6:21 AM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
I'm pretty much with Martin on this one. Why define a new syntax whose only purpose is to tell the compiler to optimize away an object creation? That's the job of the compiler -- or even the VM --, not the programmer.

On Sun, Jan 3, 2010 at 2:59 AM, John Nilsson <john [at] milsson [dot] nu> wrote:
I know Martin has already voiced his opinion on the issue. But I'd like to add an option that might be worth pursuing
defs allready supports multiple parameter lists, maybe one could add the option to have parameter lists to the left of the def ?
This
def (x:Int)times(y:Int) = ...
x.times(y) would be a type error, but
(x)times(y)x times yx ops.times y // If times as defined in the object referenced by ops
would not.
BR,John
On Sat, Jan 2, 2010 at 8:24 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================This makes more sense than the above proposal, addresses points 2 and 3 above, and is rather similar to the feature that was introduced in C# ~3.0. The "implicit" keyword may be unfit for this use, however, in which case another one could be chosen.
Neither of these additions should break any existing code. The potential use cases for one of these features are, at least to me, seemingly endless. It is currently not possible to implement one of these as a compiler plugin, because of the involved syntax changes.
I would like to hear everyone's opinions.
David Flemström




--
Daniel C. Sobral

I travel to the future all the time.

Kevin Wright
Joined: 2009-06-09,
User offline. Last seen 49 weeks 3 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performa


2010/1/3 John Nilsson <john [at] milsson [dot] nu>
I know Martin has already voiced his opinion on the issue. But I'd like to add an option that might be worth pursuing
defs allready supports multiple parameter lists, maybe one could add the option to have parameter lists to the left of the def ?
This
def (x:Int)times(y:Int) = ...
x.times(y) would be a type error, but
(x)times(y)x times yx ops.times y // If times as defined in the object referenced by ops
would not.

Following this line of thought to its logical conclusion; why not go the whole hog and allow interleaving of parameter lists with the method name in a fashion similar to smalltalk? Maybe even allow spaces.
Such as the following contrived example:
def (x:Int) is in (min: Int) until (max:Int) = min < x && max >= x
println (3 is in 1 until 6) //prints true

This is clearly a syntax change, not something done to help with optimisation.  And I *can* see the appeal here for some problems, especially for implementing DSLs.
Im also very concerned about adding complexity to the language, how should such a feature interact with operator notation and implicit conversions?  Implementing this in the compiler could also be "interesting".  Perhaps worth considering if only to gain insight into other ways that the language might be enhanced, but otherwise this could be a bit of a slippery slope  
BR,John
On Sat, Jan 2, 2010 at 8:24 PM, David Flemström <david [dot] flemstrom [at] gmail [dot] com> wrote:
Proposal 2:
Given the code:
========================================
def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * zx.times(y)
x times yx times2 (y)(z)
========================================...the compiler should transform it to:
========================================def times(implicit x: Int)(y: Int) = x * ydef times2(implicit x: Int)(y: Int)(z: Int) = x * y * ztimes(x)(y)times(x)(y)times2(x)(y)(z) ========================================This makes more sense than the above proposal, addresses points 2 and 3 above, and is rather similar to the feature that was introduced in C# ~3.0. The "implicit" keyword may be unfit for this use, however, in which case another one could be chosen.
Neither of these additions should break any existing code. The potential use cases for one of these features are, at least to me, seemingly endless. It is currently not possible to implement one of these as a compiler plugin, because of the involved syntax changes.
I would like to hear everyone's opinions.
David Flemström




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] googlemail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

John Nilsson
Joined: 2008-12-20,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
On Sun, Jan 3, 2010 at 11:58 AM, Kevin Wright <kev [dot] lee [dot] wright [at] googlemail [dot] com> wrote:
Following this line of thought to its logical conclusion;
Thank you, that was one extra step I hadn't considered. But I see the appeal of it, it's even more what I had in mind.  
Im also very concerned about adding complexity to the language, how should such a feature interact with operator notation and implicit conversions?
I share your concern. Maybe if someone had an actual use case it would be the motivation needed to study the actual implications. 
 Implementing this in the compiler could also be "interesting".  Perhaps worth considering if only to gain insight into other ways that the language might be enhanced, but otherwise this could be a bit of a slippery slope
My sentiment exactly.
BR,John
David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
On Sun, Jan 3, 2010 at 6:21 AM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
I'm pretty much with Martin on this one. Why define a new syntax whose only purpose is to tell the compiler to optimize away an object creation? That's the job of the compiler -- or even the VM --, not the programmer.

Has anyone tried to implement this yet? I've got a code base that I'll basically have to rewrite completely from using "x foo y" to using "SomeCompanion.foo(x, y)" because of this issue; are there any prospects to implement this so that I'll save myself the work? Can I contribute with anything myself? If so, how?

On the syntax change:The "Go" programming language uses a similar syntax as the one described by John (the "def (x: Int) foo (y: Int)" version) to add "methods" to a struct, so it would work in practice. It would be tedious to rewrite all of the specifications, but won't that be necessary for 2.8 anyways?
If not, I like the idea that Rex had, to simply allow for a "this" somewhere in the argument list. No need to extend the syntax then; the following would work instead:
class Foo

object Bar {
  def baz(s: String, this: Foo) = println(this + " does " + s)
}

object Main {
  def main(args: Array[String]) = {
    import Bar._
    val f = new Foo
    baz("nothing", f)
    f.baz("nothing")
  }
}
...or, something that would be really interesting while requiring only minimal syntax changes:
object Bar {
  def baz(s: String) = { this: Foo =>
    println(this + " does " + s)
  }
}

object Main {
  def main(args: Array[String]) = {
    import Bar._
    val f = new Foo
    f.baz("nothing")
  }
}
But using self-types in methods? That might be pushing it, since it widens the concept of self-types far beyond what the current definition implies. Also, the method self-type declaration is dangerously close to the syntax for function declarations, so certain things might clash there.
Anyways, what do you think?
David Flemström
jonathan mawson
Joined: 2010-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa

Daniel Sobral wrote:
>
> I'm pretty much with Martin on this one. Why define a new syntax whose
> only
> purpose is to tell the compiler to optimize away an object creation?
> That's
> the job of the compiler -- or even the VM --, not the programmer.
>

According to the OP, this isn't even a problem with the right VM. Why bother
doing work that will reduce in value - possibly to nothing - as more people
update their VMs? Surely it is better to invest work in features that won't
lose their value.

Regarding new syntax: I always remember what happened to C++. Additional
syntax really has to pull its weight to be worth adding.

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa
There are two topics in this thread:
  1. We want the pimp-my-library pattern to be more efficient
  2. We want syntax changes that allow for easier adding of methods to existing classes.
I'm still primarily focused on #1 since I need that for a project, so I'm asking again: can I expect an optimization to be implemented in the Scala compiler any time soon that handles the specific case of:
implicit def first(y: Z) = new { def a = y; def b = y }
implicit def second(y: Z) = new AnyRef { def c(d: Z) = d; def e(f: Z) = f }
(new Z).a.b.c((new Z).e(new Z))
...and transforms it to:
def first_a(y: Z) = y //replace "_" with the usual "$uid$" stuff
def first_b(y: Z) = y
def second_c(y: Z)(d: Z) = d
def second_e(y: Z)(f: Z) = f
second_c(first_b(first_a(new Z)))(second_e(new Z)(new Z))
...or should I redesign my API? Should I file a ticket?
About #2:
On Tue, Feb 23, 2010 at 6:49 PM, jonathan mawson <umptious [at] gmail [dot] com> wrote:
Why bother doing work that will reduce in value - possibly to nothing - as more people
update their VMs? Surely it is better to invest work in features that won't
lose their value.
The proposed syntax addition will not "lose value" over time, since it'd facilitate DSL creation and make it possible for users to extend classes externally without the very unintuitive "implicit def x(...) = new {...}" pattern. Also note that C# already supports this, and that the feature is widely used. Scala will have to become compatible with that somehow once it's fully ported to the CLI.
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: On the topic of the 'pimp-my-library' pattern and performa

On Tue, Feb 23, 2010 at 9:46 PM, David Flemström
wrote:
> There are two topics in this thread:
>
> We want the pimp-my-library pattern to be more efficient
> We want syntax changes that allow for easier adding of methods to existing
> classes.
>
> I'm still primarily focused on #1 since I need that for a project, so I'm
> asking again: can I expect an optimization to be implemented in the Scala
> compiler any time soon that handles the specific case of:
>
> implicit def first(y: Z) = new { def a = y; def b = y }
> implicit def second(y: Z) = new AnyRef { def c(d: Z) = d; def e(f: Z) = f }
> (new Z).a.b.c((new Z).e(new Z))
>
> ...and transforms it to:
>
> def first_a(y: Z) = y //replace "_" with the usual "$uid$" stuff
> def first_b(y: Z) = y
> def second_c(y: Z)(d: Z) = d
> def second_e(y: Z)(f: Z) = f
> second_c(first_b(first_a(new Z)))(second_e(new Z)(new Z))
>
> ...or should I redesign my API? Should I file a ticket?

I had originally thought that this was already in place, but it seems
to be harder than I thought. It's definitely something we want, but
due to lack of resources I can't attach a definite timeline to it. It
might be that Iulian manages to do this before he finishes with his
thesis here, or that he gets to do it afterwards, but nobody can
guarantee it at this stage. Filing a ticket would be definitely
worthwhile.

> The proposed syntax addition will not "lose value" over time, since it'd
> facilitate DSL creation and make it possible for users to extend classes
> externally without the very unintuitive "implicit def x(...) = new {...}"
> pattern. Also note that C# already supports this, and that the feature is
> widely used. Scala will have to become compatible with that somehow once
> it's fully ported to the CLI.

I do not think new syntax is any less heavy just because some other
language has the same.

Cheers

Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa

I added two proposals, how inliner and dce could be improved to make
the pimp-my-library pattern optimize away in more cases:

https://lampsvn.epfl.ch/trac/scala/ticket/3099
https://lampsvn.epfl.ch/trac/scala/ticket/3100

Unfortunately, for the case using structural subtyping, I'm afraid the
solution will have to be more sophisticated because IMO reflective
call code generation is done too early (cleanup phase) and thus
reflective calls can't be inlined at all (correct me if I'm wrong). In
the middle term, I would tend to propose rewriting the reflective call
codegen machinery to be part of the actual code generation phase (e.g.
jvm) instead of being performed even before icode generation. Also, at
that point it would be easier to use features of the target platform
(like invoke-dynamic or method handles) to implement the calls.

However, I know, that probably is a major effort...

Johannes

On Tue, Feb 23, 2010 at 10:09 PM, martin odersky wrote:
> On Tue, Feb 23, 2010 at 9:46 PM, David Flemström
> wrote:
>> There are two topics in this thread:
>>
>> We want the pimp-my-library pattern to be more efficient
>> We want syntax changes that allow for easier adding of methods to existing
>> classes.
>>
>> I'm still primarily focused on #1 since I need that for a project, so I'm
>> asking again: can I expect an optimization to be implemented in the Scala
>> compiler any time soon that handles the specific case of:
>>
>> implicit def first(y: Z) = new { def a = y; def b = y }
>> implicit def second(y: Z) = new AnyRef { def c(d: Z) = d; def e(f: Z) = f }
>> (new Z).a.b.c((new Z).e(new Z))
>>
>> ...and transforms it to:
>>
>> def first_a(y: Z) = y //replace "_" with the usual "$uid$" stuff
>> def first_b(y: Z) = y
>> def second_c(y: Z)(d: Z) = d
>> def second_e(y: Z)(f: Z) = f
>> second_c(first_b(first_a(new Z)))(second_e(new Z)(new Z))
>>
>> ...or should I redesign my API? Should I file a ticket?
>
> I had originally thought that this was already in place, but it seems
> to be harder than I thought. It's definitely something we want, but
> due to lack of resources I can't attach a definite timeline to it. It
> might be that Iulian manages to do this before he finishes with his
> thesis here, or that he gets to do it afterwards, but nobody can
> guarantee it at this stage. Filing a ticket would be definitely
> worthwhile.
>
>> The proposed syntax addition will not "lose value" over time, since it'd
>> facilitate DSL creation and make it possible for users to extend classes
>> externally without the very unintuitive "implicit def x(...) = new {...}"
>> pattern. Also note that C# already supports this, and that the feature is
>> widely used. Scala will have to become compatible with that somehow once
>> it's fully ported to the CLI.
>
> I do not think new syntax is any less heavy just because some other
> language has the same.
>
> Cheers
>
>  -- Martin
>

jonathan mawson
Joined: 2010-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: On the topic of the 'pimp-my-library' pattern and performa

David Flemström wrote:
>
>> Why bother
>> doing work that will reduce in value - possibly to nothing - as more
>> people
>> update their VMs? Surely it is better to invest work in features that
>> won't
>> lose their value.
>
> The proposed syntax addition will not "lose value" over time, since it'd
> facilitate DSL creation and make it possible for users to extend classes
> externally without the very unintuitive "implicit def x(...) = new {...}"
> pattern.
>
>

I can't say anything about creating DSLs in Scala, but I've only just
learned the language - and I didn't find "implicit def x(...) = new {...}"
at all unintuitive. It's simple and its availability is easy to control.
With any language feature some people will have an alternative they prefer
and which seems more natural - to them.

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