Re: [scala-user] Problem with default arguments and multiple method signatures

View: New views
5 Messages — Rating Filter:   Alert me  

Parent Message unknown Re: [scala-user] Problem with default arguments and multiple method signatures

by James Iry-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Would it be feasible to mangle the getter's name using the parameter types of the overloaded methods? 

def foo(x : T1 = xdef, y : T2 = ydef)
def foo(z : T3 = zdef, zz : T4 = zzdef)

def foo$T1$T2$defaul1 = xdef
def foo$T1$T2$defaul2 = ydef
def foo$T3$T4$default1 = zdef
def foo$T3$T4$default2 = zzdef


On Mon, Jun 1, 2009 at 11:12 PM, Lukas Rytz <lukas.rytz@...> wrote:
Hi Sciss,

If you overload a method, only one alternative is allowed to specify
default arguments; you should see an error message telling you
exactly that.

The fact that the "... is defined twice" error messages are printed is
a flaw of the current implementation and we're trying to fix that.


The reason for the above restriction: we want to have deterministic
names for the default getters (methods computing the defaults), so
that when you re-compile a single file, you get the same bytecode.
If we allowed multiple alternative to have defaults, we'd need to
add some numbering to the default getters, which would break
this stability.


Cheers: Lukas




On Tue, Jun 2, 2009 at 06:26, Sciss <contact@...> wrote:
hi,

i am integrating the great new default arguments feature of scala 2.8. unfortunately i run into problems... in the following code, i get

method apply$default$2 is defined twice
method apply$default$3 is defined twice

...

object OSCReceiver {
       @throws( classOf[ IOException ])
       def apply( protocol: Symbol, port: Int = 0, loopBack: Boolean = false, c: OSCPacketCodec = OSCPacketCodec.getDefaultCodec ) : OSCReceiver = {
               val localAddress = new InetSocketAddress( if( loopBack ) "127.0.0.1" else "0.0.0.0", port )
               apply( protocol, localAddress, c )
       }

       @throws( classOf[ IOException ])
       def apply( protocol: Symbol, localAddress: InetSocketAddress, c: OSCPacketCodec = OSCPacketCodec.getDefaultCodec ) : OSCReceiver = {
               if( protocol == 'udp ) {
                       new UDPOSCReceiver( localAddress, c )
                       
               } else if( protocol == 'tcp ) {
                       new TCPOSCReceiver( localAddress, c )
                       
               } else {
                       throw new IllegalArgumentException( ScalaOSC.getResourceString( "errUnknownProtocol" ) + protocol )
               }
       }

       @throws( classOf[ IOException ])
       def apply( dch: DatagramChannel, c: OSCPacketCodec = OSCPacketCodec.getDefaultCodec ) : OSCReceiver = {
               new UDPOSCReceiver( dch, c )
       }

       // [...]
}

i understand, i could rename the second method to applyWithAddress and the third to applyWithChannel but that destroys the beauty of the OSCReceiver( ... ) constructors. is there any trick to solve this problem?

ciao, -sciss-




Re: [scala-user] Problem with default arguments and multiple method signatures

by Lukas Rytz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Tue, Jun 2, 2009 at 14:43, James Iry <jamesiry@...> wrote:
Would it be feasible to mangle the getter's name using the parameter types of the overloaded methods? 

def foo(x : T1 = xdef, y : T2 = ydef)
def foo(z : T3 = zdef, zz : T4 = zzdef)

def foo$T1$T2$defaul1 = xdef
def foo$T1$T2$defaul2 = ydef
def foo$T3$T4$default1 = zdef
def foo$T3$T4$default2 = zzdef


That would probably work, except that for some types it's not obvious
how to convert them into a name:

   def foo(x: { def bar(): Int } = new { def bar() = 1 })
   def foo(x: String = "uh")


What do people think, is it too much limitation if we restrict defaults
to one overloaded alternative? After all, defaults often allow you to get
rid of overloads.

Lukas


Re: Re: [scala-user] Problem with default arguments and multiple method signatures

by David MacIver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/6/2 Lukas Rytz <lukas.rytz@...>:

>
>
> On Tue, Jun 2, 2009 at 14:43, James Iry <jamesiry@...> wrote:
>>
>> Would it be feasible to mangle the getter's name using the parameter types
>> of the overloaded methods?
>>
>> def foo(x : T1 = xdef, y : T2 = ydef)
>> def foo(z : T3 = zdef, zz : T4 = zzdef)
>>
>> def foo$T1$T2$defaul1 = xdef
>> def foo$T1$T2$defaul2 = ydef
>> def foo$T3$T4$default1 = zdef
>> def foo$T3$T4$default2 = zzdef
>
> That would probably work, except that for some types it's not obvious
> how to convert them into a name:
>
>    def foo(x: { def bar(): Int } = new { def bar() = 1 })
>    def foo(x: String = "uh")
>
>
> What do people think, is it too much limitation if we restrict defaults
> to one overloaded alternative? After all, defaults often allow you to get
> rid of overloads.

Personally I don't have a problem with the restriction, and I find it
very convenient that the generated method names are so
straightforward. That being said, if there's a massive popular opinion
that the restriction is too onerous and it doesn't introduce weird
ambiguities to lift it, I don't care that much. :-)

Re: [scala-user] Problem with default arguments and multiple method signatures

by James Iry-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Good point.  I hadn't thought about refinement types.  I don't have a good answer short of devising an internal naming scheme for them, which might be more trouble than its worth.

I don't think the limitation is too onerous.  As you say, defaults replace a common use for overloading.  If put to a vote I wouldn't vote to hold up 2.8 over it.  It's just that limitations and irregularities driven by implementation challenges tend to have an "arbitrary" feel to users who aren't involved in the implementation and I can foresee a lot of "why doesn't this work" messages in the mailing list around this issue in the future.

On Tue, Jun 2, 2009 at 6:17 AM, Lukas Rytz <lukas.rytz@...> wrote:


On Tue, Jun 2, 2009 at 14:43, James Iry <jamesiry@...> wrote:
Would it be feasible to mangle the getter's name using the parameter types of the overloaded methods? 

def foo(x : T1 = xdef, y : T2 = ydef)
def foo(z : T3 = zdef, zz : T4 = zzdef)

def foo$T1$T2$defaul1 = xdef
def foo$T1$T2$defaul2 = ydef
def foo$T3$T4$default1 = zdef
def foo$T3$T4$default2 = zzdef


That would probably work, except that for some types it's not obvious
how to convert them into a name:

   def foo(x: { def bar(): Int } = new { def bar() = 1 })
   def foo(x: String = "uh")


What do people think, is it too much limitation if we restrict defaults
to one overloaded alternative? After all, defaults often allow you to get
rid of overloads.

Lukas



Re: Re: [scala-user] Problem with default arguments and multiple method signatures

by Martin Odersky :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Lukas and I have discussed these issues a long time. There is for me a
strong incentive to avoid further complexity, both in the compiler and
in the spec. That's why I prefer the restriction, because it
simplifies several things.

Cheers

 -- Martin

On Tue, Jun 2, 2009 at 4:46 PM, James Iry <jamesiry@...> wrote:

> Good point.  I hadn't thought about refinement types.  I don't have a good
> answer short of devising an internal naming scheme for them, which might be
> more trouble than its worth.
>
> I don't think the limitation is too onerous.  As you say, defaults replace a
> common use for overloading.  If put to a vote I wouldn't vote to hold up 2.8
> over it.  It's just that limitations and irregularities driven by
> implementation challenges tend to have an "arbitrary" feel to users who
> aren't involved in the implementation and I can foresee a lot of "why
> doesn't this work" messages in the mailing list around this issue in the
> future.
>
> On Tue, Jun 2, 2009 at 6:17 AM, Lukas Rytz <lukas.rytz@...> wrote:
>>
>>
>> On Tue, Jun 2, 2009 at 14:43, James Iry <jamesiry@...> wrote:
>>>
>>> Would it be feasible to mangle the getter's name using the parameter
>>> types of the overloaded methods?
>>>
>>> def foo(x : T1 = xdef, y : T2 = ydef)
>>> def foo(z : T3 = zdef, zz : T4 = zzdef)
>>>
>>> def foo$T1$T2$defaul1 = xdef
>>> def foo$T1$T2$defaul2 = ydef
>>> def foo$T3$T4$default1 = zdef
>>> def foo$T3$T4$default2 = zzdef
>>
>> That would probably work, except that for some types it's not obvious
>> how to convert them into a name:
>>
>>    def foo(x: { def bar(): Int } = new { def bar() = 1 })
>>    def foo(x: String = "uh")
>>
>>
>> What do people think, is it too much limitation if we restrict defaults
>> to one overloaded alternative? After all, defaults often allow you to get
>> rid of overloads.
>>
>> Lukas
>>
>
>