
Java to Scala converter - lukax
http://javatoscala.com
======
scottjad
This is just a simple front-end/demo. The real work is being done by a
separate project at
[https://github.com/mysema/scalagen](https://github.com/mysema/scalagen).

I kind of wished this site was written in Java and run through scalagen with
the output being run as an additional meta-demonstration.

------
ben0x539
I don't know scala so maybe I'm missing something, but does this just break
with functions that start with a switch statement? eg.

    
    
            public static void main(String[] args) {
                switch (42) {}
                System.out.println("Hello World!");
            }
    

converts to

    
    
        def main(args: Array[String]) 42 match {
        }
    

dropping the println.

Edit: It also seems to be dropping autoincrement/decrement, and random other
blocks of code I've looked at, so I guess it's still in a fairly early stage.

Definitely a cool project though :)

~~~
tommorris
Yes. The problem with the switch is that in Scala, 'match' actually requires
you to have at least one pattern matching rule.

The closest I'd wrote in Scala to your example is something like this:

    
    
        def main(args: Array[String]) = {
            42 match {case i: Any => None}
            println("Hello World!")
        }
    

Ideally, the switch (42) {} should be removed as it's not doing anything.

~~~
ben0x539
Sorry, maybe I minimized my example too eagerly.

    
    
        class HelloWorldApp {
            public static void main(String[] args) {
                switch (args.length) {
                  case 0:  System.out.println("No args!"); break;
                  case 1:  System.out.println("One arg!"); break;
                  default: System.out.println("Multiple args!"); break;
                }
        
                System.out.println("Hello World!");
            }
        }
    

This also seems to not emit the "Hello World" println.

------
adandy
I also noticed this in IntelliJ when I went to copy some Java into a Scala
project. As I began converting the Java code to Scala after the copy I was
extremely confused when I found that the pasted code was already converted for
me.

~~~
Xorlev
That being said, it doesn't work very well in many circumstances. I'm not sure
if they're using Scalagen under the hood or their own home-baked stuff. It's
impressive as-is, regardless of the issues.

------
unclebucknasty
Earnest question: who is the target audience here? If Java and Scala can be
intermixed in the JVM, and the generated Scala code is not very idiomatic,
then how would this be used?

~~~
lukax
Just a few examples:

1\. Someone still learning Scala syntax (and already knows Java)

2\. Let's say you already have an existing Scala code base and you want to try
out some new Java library which has examples in Java but you want to use it in
your Scala code.

------
ExpiredLink
A Scala to Java converter would be needed more. Early adopters are
disenchanted with Scala.

~~~
quacker
> _Early adopters are disenchanted with Scala._

Since everyone else seems to disagree, I'll explain why I agree:

\-- Scala advocates a completely different style of programming. You have to
rethink how you code to match Scala's functional style. This is not a trivial
thing if you have a bunch of Java developers you need to convert.

\-- I find the Scala documentation is less readable than Java's docs. They are
cluttered with type conversion functions and unreadable operator overloads
(the filtering helps a bit here, but it's extra work). Documentation is also
split between the object/class/trait pages.

\-- There's a whole class of immutable data structures whose performance
characteristics I need to learn, since I'm supposed to be using them.

\-- I'm not convinced that the overhead of copying immutable data doesn't
outweigh the benefits of the ability to trivially parallelize the code.

\-- I'm not convinced that a project preferring only immutable data is easier
to maintain.

\-- Programs seem to take longer to compile (sbt is especially slow).

Now that I think about it, Scala in relation to Java is a lot like C++ in
relation to C. Scala sits on top of Java, so you need to know Java, and then
you need to know all of Scala's features as well. However, (as someone who
knows Java) I think C++ adds useful abstractions that are non-existant in C
(templating, inheritance), whereas most of Scala's features are just
syntactical changes of what already exists in Java.

~~~
mark242
_\-- I 'm not convinced that the overhead of copying immutable data doesn't
outweigh the benefits of the ability to trivially parallelize the code._

Let me introduce you to my friend, Mister ConcurrentModificationException.
He's a wily fellow-- he rarely pops up when you're doing local development,
but he has this nasty habit of showing up in production whenever you start
hitting a decent load. He's like Keyser Soze. You see him, then you try to
debug the place he shows up, and _poof_ he's gone, back into the shadows from
whence he came, only to reappear when you try to iterate over that singleton
java.util.ArrayList once more.

Now, let me introduce you to my other friend, Miss
scala.collection.immutable.List. She's a superheroine. You can run code using
her on one thread, or ten threads, or ten thousand threads, she doesn't care,
you're always going to get the same iterator back when you call List.foreach.
For the very small price of a little bit of garbage (which Mister ParallelGC
takes care of very readily), Miss immutable.List will return that filtered
list the exact same way, every single time you run the filter method with
those parameters you set. You can run code with her in development, staging,
production, she's always ready to go, and you'll never run into Mister
ConcurrentModificationException when you're dealing with Miss immutable.List.

 _\-- I 'm not convinced that a project_

What do you mean? All I read was "I'm not convinced that a project". Someone
else must have come by and edited your post before I was able to read it.

~~~
quacker
_singleton java.util.ArrayList_

So...don't use data structures that are not thread-safe in threaded
environments? Wrap it with Collections.synchronizedCollection. Or make copies,
if you prefer.

 _For the very small price of a little bit of garbage..._

What small price? If I have millions of things stored in an immutable data
structure, do I not have to copy the entire structure (or at least some
portion of it) when I want to modify anything inside of it?

~~~
mark242
Ah, synchronizedCollection, the...

hang on...

wait a sec...

one more sec, someone's doing something...

now? no, not yet, wait...

how about... NOW! synchronizedCollection, the global lock for Java's mutable
datatypes.

Here's the fundamental difference between Java and Scala: if I say, in Scala,
val people = List[String]("quacker", "mark242") then _by default_ people is an
immutable list. I don't have to do anything special. In Java, either I'm
suddenly using the Guava libraries to get something similiar (but not the
same), or I'm doing all kinds of funky dances around list iterators, or I'm
using Arrays.copyOf, or what have you. In any case, you have all of this
extraneous code, when _it isn 't necessary_.

Quick: give me a list comprehension method in Java that takes a list of
Strings and returns that list, filtered, of Strings that are only five
characters or longer. Make it null-safe and thread-safe. This isn't
difficult-- you're thinking about 6-7 lines of Java code in your head, right?
Null check, synchronized, new ArrayList, for(s in sList), that kind of thing,
right?

In Scala, it's this. Some would argue you don't even need a separate method.

    
    
      def getFiveCharacters(s: List[String]) = s.filter(_.length >= 5)
    

_If I have millions of things stored in an immutable data structure, do I not
have to copy the entire structure when I want to modify anything within?_

Dear god, man, what are you doing wrong in your Java code? This is the exact
scenario where you _want_ an immutable list, otherwise you'll be running
synchronized code and precisely one core of your CPU will be glowing red like
lava, while your other CPU cores sit idle.

I just did this in the scala repl:

    
    
      (0 to 1000000).toList.par.filter(_ % 100 == 0)
    

What that does is grab all of the integers from 0 to 1,000,000, convert them
to an immutable List, then filter that List (yes-- an iterator! with a
filtered copy!) by only taking numbers divisible by 100. The whole thing takes
a couple hundred ms in the repl (which is fantastic, since it's _compiling
then executing the code_ ) and almost no memory overhead. For code that is
absolutely thread safe. And the ".par" makes this run in parallel on all my
CPU cores.

~~~
anonymoushn
> Null check, synchronized, new ArrayList, for(s in sList), that kind of
> thing, right?

> In Scala, it's this. Some would argue you don't even need a separate method.

It seems a bit unfair to force null checks on the Java code and then present a
Scala alternative that throws NPE in two different places.

~~~
mark242
A good Scala programmer will never write the word null in their code. Ever. If
I was overly concerned that the method was going to be called by Java code,
I'd put this:

    
    
      Option(s).getOrElse(List[String]()).filter(str => Option(str).fold(false)(_.length > 5))

~~~
anonymoushn
That should do it. I would probably go for

    
    
      def foo(s: List[String]): List[String] = s match { case l: List[String] => l.filter(_ match { case str: String => str.length > 5; case _ => false}); case _ => List[String]()}
    

It's a bit uglier, but I had to develop a habit of not spewing objects
everywhere because of the constraints of the application I work on.

You're right that this is primarily a concern if the Scala dev wants to talk
to Java. However, if the Scala dev does not want to talk to Java, perhaps a
statically typed FP language with an HM type system would be a better fit.

~~~
jebblue
I couldn't grok the original 1 liner, definitely not the second one and no way
the last one. If there is a segment of programmers who grok and like it, cool.
It still doesn't fix the performance problem of copying 1 million things
before you can act on them because the copy would still have to happen on 1
core, or 1 core at a time, unless maybe the Scala compiler optimizes the code
to divide the list among the cores available, if not though then immutability
doesn't help performance during the copy.

~~~
anonymoushn
You don't have to use immutable collections. If you want to use them, you
should probably consider the cost of the operations you are using. Which
particular operations are you worried about? Most updates to an immutable hash
table or sorted map should copy only a small part of the collection, for
instance.

------
agibsonccc
This is a neat project. I have a giant codebase I'd like to try this on.
Depending on the output, this might be the kick in the pants I need to get in
to scala full time.

~~~
lmm
Scala that's been autoconverted from Java doesn't tend to be very idiomatic
scala, and there's no way to convert back. I'd recommend writing bits of your
code (particularly code that needs to convert between datastructures, or code
where you need better control over effects) in scala first and see how you get
on with it.

~~~
agibsonccc
Yeah I looked in to the differences after I played with it a bit..generated
code is never ideal in the first place though.

I wanted to see how close it was..but the mapping just isn't what I was quite
looking for. There really is no silver bullet though.

------
yareally
Intellij IDEA has had Java to Scala conversion built into it for a while (as
well as Java to Kotlin, Jetbrain's new JVM Scala-like language). I'm not sure
how Jetbrain's tool compares to the one in the link above, but the conversion
result in Intellij varies by how complicated and dependent the code is on
other packages/libraries. Converting an entire class file tends to work out
much better than a single method.

I initially used it to convert some Android code in Java to Scala, but much of
the time you have to end up rewriting that as well, since it's generally
results in very non-idiomatic Scala code. Still useful for someone learning
Scala though as others have pointed out.

The Scala plugin is free though and comes with the community edition of
Intellij for anyone wanting to try it out. Basically you just copy/paste some
Java code from the current project into a Scala file or right click on the
Java file and select "convert."

------
zidar
This looks great. Now if only Scala would play nice with Android, there would
be no need to look back at java at all.

~~~
edofic
I made a few android apps with scala. What's not working for you?

------
dkhenry
So now I am really wondering. What is the sub java parts of the JVM that need
to be implemented to completely free Scala from the JVM ( i.e. what C
interfaces are needed to allow scalc to compile to LLVM or comparable VM)

~~~
lmm
Why would you want to? The JVM is pretty awesome. There's already a scala
implementation for .net, so it's got at least some level of VM independence,
but the JVM is the primary target and I'd expect it to remain so.

As well as the VM there's the runtime library to consider. There was a project
recently here that compiled scala to javascript to use on web pages, but
unfortunately it needed a 16mb standard library.

~~~
laureny
> There's already a scala implementation for .net,

Scala.net was abandoned a while ago. It's close to impossible to get it to run
because .Net's generics are reified.

~~~
meddlepal
I've heard this before in the context of why .NET tends to have less alternate
language implementations on it than the JVM. I don't understand why though.
Why do reified generics make it near impossible?

~~~
eeperson
My understanding is that it gives you less flexibility in how your type system
works. To a certain extant you are stuck with the C# type system no matter
what the language is because it is baked in to the VM. I assume this doesn't
apply as much to dynamic languages but still makes interoperability a pain.

------
ensmotko
Wow, this is awesome. Have you tried running it on a larger Java codebase?

~~~
lukax
This online tool was created to convert shorter Java code samples but larger
files also work (e.g.
[https://github.com/sirthias/pegdown/blob/master/src/main/jav...](https://github.com/sirthias/pegdown/blob/master/src/main/java/org/pegdown/Parser.java))

------
mark_eijsermans
Now we just need a OOP -> FP converter ;)

~~~
zeckalpha
Or just use both at what they are best at.

~~~
cgag
Unfortunately most people seem to think OO happens to be best at the things
they're already used to using OO with for historical reason.

~~~
seanmcdirmid
Unfortunately, many people seem to think FP is the hot new thing and OOP is
already over; they ignore that OOP happens to be a great way to structure code
that focuses on naturalism, while FP forces math-like structuring.

There is massive fad-like interest in FP right now, especially in academia.

~~~
zeckalpha
And vice versa.

~~~
seanmcdirmid
I don't see the vice versa in academia at all. Where is this OOP hype that you
think exists? Even OOPSLA changed its name to SPLASH to de-emphasize objects.

~~~
zeckalpha
You said _especially_ in academia. I just meant that OOP is fad-like, too.

~~~
seanmcdirmid
FP is quite useful, the fad I'm referring to is "let's make everything
immutable" and "let's just use functions to structure our code." This ignores
what FP is good at and how it doesn't really compete with OOP in terms of
problem space: OOP is basically modelling based on how we think and talk about
things (kingdom of nouns), FP works great for more abstract math-based
concepts (kingdom of verbs). Immutability solves one problem (consistency)
that has other real solutions as well (dependency propagation).

There is still a lot of work to do on objects to not make them suck, just like
there is still a lot of work to do with functions. My ax-to-grind revolves
around work on objects being neglected in favor of a fixation on functions.

------
orph
Would love the opposite, a scala -> java converter.

------
mcav
Cool, has anyone made something similar for Clojure?

~~~
zindlerb
Isn't the whole idea of clojure that it is built on JVM?

~~~
tel
I'd say it's an somewhat important side point... But Clojure already cross-
compiles to Javascript.

~~~
sreque
There have been a number of not-quite-successful attempts in the past to
compile Scala to Javascript. The latest and most promising seems to be
[https://github.com/lampepfl/scala-js](https://github.com/lampepfl/scala-js)

------
anonymoushn
enums are converted into code that does not compile.

~~~
gtani
I think you would have to check converted code for all the well documented
interop issues: annotations, static members, checked exceptions etc. The
Manning books "In Depth" and "In Action" cover these really well,

