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

Scala varargs to Java varargs interop problem

5 replies
nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
I'm on 2.7.4 and tried this:

class TestVarArgs {
   
    def printIt(string: String, parms: Any*) {
        java.lang.System.out.printf(string, parms);
    }
   
    def main(args: Array[String]) {
        val test = new TestVarArgs
        test.printIt("%d, %d, %d", 1, 2, 3)
    }
}

Got this:

Exception in thread "main" java.util.IllegalFormatConversionException: d != scala.runtime.BoxedObjectArray
    at java.util.Formatter$FormatSpecifier.failConversion(Unknown Source)
    at java.util.Formatter$FormatSpecifier.printInteger(Unknown Source)
    at java.util.Formatter$FormatSpecifier.print(Unknown Source)
    at java.util.Formatter.format(Unknown Source)
    at java.io.PrintStream.format(Unknown Source)
    at java.io.PrintStream.printf(Unknown Source)
    at bla.TestApply.printIt(TestApply.scala:5)
    at bla.App$.main(TestApply.scala:12)
    at bla.App.main(TestApply.scala)

Seems like the parms Seq is passed to the Java method as a parm itself, not a parm array.
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Scala varargs to Java varargs interop problem

On Tue, Apr 28, 2009 at 10:36:13AM -0500, Nils Kilden-Pedersen wrote:
> class TestVarArgs {
>
> def printIt(string: String, parms: Any*) {
> java.lang.System.out.printf(string, parms);
> }
>
> def main(args: Array[String]) {
> val test = new TestVarArgs
> test.printIt("%d, %d, %d", 1, 2, 3)
> }
> }

The parms arrives as a Seq, it doesn't keep acting "varargy" when you
pass it along. What you would want is:

def printIt(string: String, parms: Any*) {
java.lang.System.out.printf(string, parms: _*);
}

However this doesn't work since you're passing Anys and they're not
boxed, so I had to do this:

def printIt(string: String, parms: Any*) {
java.lang.System.out.printf(string,
parms.map(_.asInstanceOf[AnyRef]) : _*);
}

Not too pretty but I don't know a cleaner way at present.

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala varargs to Java varargs interop problem
On Tue, Apr 28, 2009 at 12:07 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
The parms arrives as a Seq, it doesn't keep acting "varargy" when you
pass it along.  What you would want is:

   def printIt(string: String, parms: Any*) {
       java.lang.System.out.printf(string, parms: _*);
   }

However this doesn't work since you're passing Anys and they're not
boxed, so I had to do this:

   def printIt(string: String, parms: Any*) {
       java.lang.System.out.printf(string,
         parms.map(_.asInstanceOf[AnyRef]) : _*);
   }

Not too pretty but I don't know a cleaner way at present.

Are there any plans for Scala to support seamless interoperability with Java varargs? Or am doing something wrong?
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Scala varargs to Java varargs interop problem

On Fri, May 1, 2009 at 6:37 AM, Nils Kilden-Pedersen wrote:
> On Tue, Apr 28, 2009 at 12:07 PM, Paul Phillips wrote:
>>
>> The parms arrives as a Seq, it doesn't keep acting "varargy" when you
>> pass it along.  What you would want is:
>>
>>    def printIt(string: String, parms: Any*) {
>>        java.lang.System.out.printf(string, parms: _*);
>>    }
>>
>> However this doesn't work since you're passing Anys and they're not
>> boxed, so I had to do this:
>>
>>    def printIt(string: String, parms: Any*) {
>>        java.lang.System.out.printf(string,
>>          parms.map(_.asInstanceOf[AnyRef]) : _*);
>>    }
>>
>> Not too pretty but I don't know a cleaner way at present.
>
> Are there any plans for Scala to support seamless interoperability with Java
> varargs? Or am doing something wrong?
>
It's on our to-do list for 2.8. We could not change it before, because
such a change will break binary compatibility.

Cheers

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala varargs to Java varargs interop problem
On Fri, May 1, 2009 at 5:38 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:
It's on our to-do list for 2.8. We could not change it before, because
such a change will break binary compatibility.

Fantastic. Thank you Martin.
David Brown
Joined: 2009-04-26,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala varargs to Java varargs interop problem

On Fri, May 01, 2009 at 12:38:40PM +0200, martin odersky wrote:

>> Are there any plans for Scala to support seamless interoperability with Java
>> varargs? Or am doing something wrong?
>>
>It's on our to-do list for 2.8. We could not change it before, because
>such a change will break binary compatibility.

RichString's format, although kind of ugly, seems to work reasonably
well, for formatting operations.

"%d, %d, %d".format(1,2,3)

or

"%d, %d, %d" format (1,2,3)

And, building upon that, things such as printf are fairly easy:

def printf(text: String, args: Any*) { print(text format (args : _*)) }

which is already defined in Predef (but not quite this way).

Calling the Java varargs ones is harder, because of the ambiguous
boxing. But, with some help it works, although annoying:

String.format("%d, %d", int2Integer(1), int2Integer(2))

David

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