Hacker News new | past | comments | ask | show | jobs | submit login
Java to Scala converter (javatoscala.com)
110 points by lukax on Sept 27, 2013 | hide | past | favorite | 87 comments



This is just a simple front-end/demo. The real work is being done by a separate project at 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.


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 :)


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.


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.


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.


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.


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?


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.


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


This is completely untrue.

Every single Java developer that I introduce to Scala-- every single one-- six months later, they tell me "please don't make me go back to Java".

The "disenchanted" piece, I think, comes from the fact that if you're just writing Java-OO-style in Scala, you're losing almost all the benefits. Once you start working with the FP style, understanding Options, working with fold, list comprehensions, and the resulting massive reduction in lines of code, you start seeing how FP Scala code becomes the last refactoring you'll ever need to do, because it's so concise.


Depends on how "clever" the people using Scala were trying to be. obligatory: http://parleys.com/play/51c1ffe7e4b0d38b54f46231


Wow, I had no idea that Scala is already ten years old.


I have some guys you might want to teach.

Given the skills we get on some of our teams, I fear they won't even manage to move to Java 8!


>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.


-- 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.


>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.

You do realize that concurrency and parallelization are very different topics right? One is a necessary property, the other is one of oppurtunity. It makes sense that collections designed for concurrency would suck at parallelism.


Here is the magic of Scala.

A collection designed for concurrency:

val users = List("seanmcdirmid", "mark242").reverse

That same collection, designed for parallelism and concurrency:

val users = List("seanmcdirmid", "mark242").par.reverse


The APIs are equivalent and safe, but parallelism is a feature of opportunity. The overhead of using an immutable collection is often not overcome by the use of parallel threads, making the tradeoff not worth it. Even CUDA has brought mutability back to GPUs for performance reasons.


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?


> 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?

Depends on the nature of the modification; to choose the right immutable data structure, you want to choose the one that has the best behavior under your expected use.

Pushing something on to the head of an immutable list doesn't require a copy, the new list has the new object as the head and the old list (not a copy) as the tail. Similarly, removing the head doesn't require a copy, it just returns the tail of the existing list. If you want to replace something in the middle of the list, you'll need to copy everything closer to the head than the modified item.

Different immutable collections have different "cheap" access patterns.


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.


> 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.


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))


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.


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.


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.


It's actually all just pointers to data, so when you change something it makes a new node and copies a few new pointers so the new tree is still correct. All of the old data and pointers that aren't changed stay exactly where they are.


> Let me introduce you to my friend, Mister ConcurrentModificationException.

Thanks for reminding me of him. I have never seen him during my last five years of programming in Java. I hope he's alive and well.


> Scala sits on top of Java

That's not true. Scala sits on the JVM, and has some accommodations to facilitate interoperation with code written in Java, but it does not "sit on top of Java" as a language. You don't need to know Java to write Scala.


Forgive my imprecision.

>You don't need to know Java to write Scala

Is this actually true in practice? Are there tutorials or books that don't assume knowledge of Java? In any case, if you want to use anything in the Java standard library (I assume they haven't converted the entire thing to Scala), then you'll still need to understand Java documentation which requires some knowledge of Java.


> Is this actually true in practice?

Seems to be.

> Are there tutorials or books that don't assume knowledge of Java?

Tutorials, books, and a Coursera course taught by Martin Odersky. Among other things.

> In any case, if you want to use anything in the Java standard library (I assume they haven't converted the entire thing to Scala), then you'll still need to understand Java documentation which requires some knowledge of Java

Sure, if you want to use something in a Java library (standard library or not) for which no one has written Scala-focussed documentation, its likely you'll need to understand Javadocs; that's not a "need to know to use Scala", that's a "need to know to effectively interface with existing Java library code", which applies just as much when leveraging Java libraries from any other language.

OTOH, the structure of Scala makes this fairly straightforward, and its probably a lower barrier if you know Scala but not Java than almost any other non-Java language from which you might call Java.


If you want to use Scala without ever calling or being called from Java, you probably picked the wrong FP language. If you want to use Scala to call and be called by Java, you will need to know Java to debug anything.


I am also posting to disagree. In general, I have been pretty rough on Scala, but the long and short of it is something like this: Scala trades being a usable FP language for being good at Java interop. Everything you could want to do in Java (except for enums) is possible and usually significantly easier and more succinct in Scala. Everything you would want to do in OCaml, Haskell, or Scheme, is possible and usually extraordinarily difficult in Scala.

> -- 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.

Imperative Scala is both performant and readable. For the application I work on, in many places it is the only style that is sufficiently performant.

> -- 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.

This is pretty much true. Good IDE support and #scala@freenode help.

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

You can use whatever data structures you want, including the ones in java.util. If immutable data structures are appropriate for your application (for instance, because you want nondeterminism based on Scala's delimited continuations, and repeated invocations of the same continuation should of course see the same data, or because you want to pass a lasting view of the current state of your collection to another thread), then you can use 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.

This is an objection to a particular way of structuring applications, rather than to a language.

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

This is also not a Scala thing. My insignificant industry experience indicates that it is true. More importantly, John Carmack seems to think so: https://news.ycombinator.com/item?id=6278047

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

Yeah. I would be okay with this if I got the GLORIOUS TYPE SAFETY from it, but Scala does not really deliver on this front.

> then you need to know all of Scala's features as well.

This is a big burden, to be sure, and Scala introduces some unreasonable gotcha's along the way. Having already learned Scala, though, there's no reason I would sit down and write Java. Unless I wanted an enum.


I don't think this is true at all. There was the one team at Yammer, but overall, it seems as if Netflix and LinkedIn are pushing forward with Scala adoption, and Twitter, FourSquare, Tumblr, Klout, Gravity, and many others are already committed scala shops.


As an early adopter, I don't feel disenchanted. Do you have references to back your claim?


Based on what? I have yet to meet a Scala developer who wants to go back to Java, but know many Java developers who are moving in the other direction.


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.


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.


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.


You can use Java and Scala in the same project.


I'm plenty aware. I just want to migrate my whole codebase to scala. I like the JVM itself, but would like some of the features of scala. My main point is I've been procrastinating, but this could be a great motivator.

I've also worked with intermixing the different JVM languages including clojure, working with SBT, etc.

Good points have been raised that it wouldn't be idiomatic scala though.


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."


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


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


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)


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.


> 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.


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?


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.


Speed and size would be the two biggest.

The start up time of the JVM and the size of the generated executables ( jar files ) make scala not terribly useful for those small programming tasks ( scripting and such )


It is a matter of using the right JVM for the job.

Many do allow for AOT compilation, or caching the generated JIT code between invocations. IBM J9 is one of them, for example.


My understanding is that the bulk of JVM startup time is NOT compiling or loading the actual application code, but loading the classpath.


As I said, not all JVMs are made alike, don't confuse Java virtual machines, with Oracle's or OpenJDK implementation.

JVMs that cache JITed code don't spend time loading the classpath if the cache is still valid.


You misunderstand me...it has to read and decompress (jars are basically zip files) those 50MB are so (just for the system jars) on every startup before it can even think about validating the cache


Sure, however you are still speaking of a specific implementation.


And which implementation that you seem to imply exists DOESN'T suffer from this seemingly fundamental issue? You built this strawman, now defend it or stop waving your hands.


Just read my OP carefully and you will find you answer.


No, read MINE carefully. Even loading cached data isn't free.


Of course not, all the code and data that go into the processor needs to go through the processor cache first.

My OP comment has an example of a JVM that doesn't read jar files as you mentioned, while executing native code stored in a JIT cache present in the hard disk, between invocations.

Google is your friend if you look for the respective documentation. Or, who knows, you could even download it and play around with it.

I'm out, please turn the lights off on the way out.


- llvm backend project (tho mail list is pretty quiet): http://greedy.github.io/scala-llvm/

- compiler backend page (info about CLR: http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded...

- scala to JS (one of multiple projects): http://www.infoq.com/news/2013/06/scalajs

- akka is (i think) tightly bound to Oracle JVM/openJDK, https://groups.google.com/forum/#!msg/akka-user/0Z-9_Bmt8p4/...


llvm backend, seems very sleepy if not dead. I thought it was a cool project.


Huge amounts. Practical scala apps leverage huge parts of the Java infrastructure. The Scala types are often thin wrappers over the Java types, JDBC, NIO, etc. It'd be a bit like trying to write a C++ app without access to, say, the STL, or Boost.


Right but if i can convert the java types to be scala code I can use the scala compiler to compile to whatever my target is.


The point is that currently the Scala compiler provides one target - the JVM. Support for .NET was officially dropped last year, and nobody seems to care.

Scala and the JVM are very tightly coupled - targeting LLVM or something should be possible, but getting that to run with high performance would be very difficult.


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


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...)


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


Or just use both at what they are best at.


Exactly. My poke was meant to highlight the fact that a language is more than just syntax. I'm assuming this is intended more as a tool for helping start a transition into Scala, with a heavy amount of refactoring afterwards to convert it to idiomatic Scala.


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.


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.


And vice versa.


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.


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


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.


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


Cool, has anyone made something similar for Clojure?


Unlike Scala, having Java-style code in Clojure yields no advantages. You just end up with something like Java, but with less type safety and more parentheses. It also makes a lousy start for refactoring since effective Clojure is so much about figuring out how to shape your code into nested S-Expressions, so you'll end up nuking most of your auto-converted Java "statements".


Clojure doesn't lend itself to doing that. Perhaps the easiest (albeit simplistic) way to describe the difference between Clojure and Scala -- Scala supports OOP and FP, and Clojure supports FP only as part of a holistic (and refreshing) vision of how high-level programming is done.

Even if it were possible to do so in Clojure, you probably wouldn't want to. There are usually ways to do the same things in Clojure that makes your code simpler, and as a result, in much less code.

Part of the Clojure philosophy is to make things simpler, even if it isn't always 'easy' at first relative to the individual talking. Even though using a code translation tool is easy, figuring out how to use functions and macros to abstract away repetitious code blocks and patterns from your code is well worth it in the medium- and long-term.


Clojure has OO faculties too, just not in one big tangled ball of mud like Scala and Java.


you're right, and Clojure extends the power/flexibility of certain constructs in OOP world, like making dynamic dispatch based on arbitrary types (not just the name of a concrete subclass of a polymorphic superclass)


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


So is scala, and scala already interoperates with java code. But it's still nice to be able to turn your legacy java code into scala and have all your code in a single language.


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


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


enums are converted into code that does not compile.


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,




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: