typelead / eta

The Eta Programming Language, a dialect of Haskell on the JVM
https://eta-lang.org
BSD 3-Clause "New" or "Revised" License
2.61k stars 141 forks source link

Tool to convert Java code to Eta code #869

Open Jyothsnasrinivas opened 6 years ago

Jyothsnasrinivas commented 6 years ago

Recently, I've been trying to implement Eta examples for various Java frameworks. And I found a repetitive pattern while converting the Java examples to Eta. I was wondering if we could automate this with a tool to make it easy to copy paste Java code samples and directly convert it to Eta code.

Let's see a simple Web Server in Java and Eta:

When implemented in Java

public class SimpleHttpServer {

  public static void main(String[] args) throws Exception {
    InetSocketAddress address = new InetSocketAddress(8000);
    HttpServer server = HttpServer.create(address, 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();
  }

  static class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {
      byte [] response = "Hello Eta from the Java world!".getBytes();
      t.sendResponseHeaders(200, response.length);
      OutputStream os = t.getResponseBody();
      os.write(response);
      os.close();
    }
  }
}

When implemented in Eta

main :: IO ()
main = java $ do
  address <- newInetSocketAddress 8000
  server <- create address 0
  server <.> createContext "/test" (httpHandle handler)
  server <.> setExecutor Nothing
  server <.> start

  where handler t = do
          response <- "Hello Eta from the Java world!" <.> getBytes
          rlength <- response <.> alength
          t <.> sendResponseHeaders 200 (fromIntegral rlength)
          os <- t <.> getResponseBody
          os <.> write response
          os <.> close

From the above example we can infer the following:

A good starting point can be to take a look at Java to Kotlin Converter which has done a great job and many companies are using it to migrate their Java codebase to Kotlin.

This might be tricky for Data Processing/Streaming frameworks where the APIs are tricky with Generic Subtyping, F-Bounded Polymorphism, etc, but it would be great to push this as far as we can.

gregnwosu commented 6 years ago

I'm new to this but doesnt the fact that java classes contain state make this impossible? I think this would naively convert the code , but it is quite possible that any of the calls have side effects that could change the state of the object invisibly. Then factor things in like AOP or spring dynamic proxies and I would suggest that the translation should be only one way.

neko-kai commented 6 years ago

I'm new to this but doesnt the fact that java classes contain state make this impossible?

Oh, but the proposal is to just 1-to-1 convert imperative calls to Java monad calls, not try to convert java code to idiomatic haskell.

Then factor things in like AOP or spring dynamic proxies and I would suggest that the translation should be only one way.

Bytecode-level AOP will probably still work, as the java method calls remain there.

MyriaCore commented 5 years ago

I feel like you could do this with grammars / parsing. I'm not super familiar with traditional grammar parsers like ANTLR, I typically float around prolog and DCG's a bit more, but with prolog you can pretty easily equate two parts of two different AST's and convert between two gramar-based langs that way.