Java 9: JShell, a Read-Eval-Print Loop (REPL)

What’s a REPL?

A Read-Evaluate-Print-Loop, or, REPL, is a command line interface for interacting with a programming language. In the words of JEP 222, the new Java REPL (JShell) is to “provide an interactive tool to evaluate expressions of the Java programming language, together with an API so that other applications can leverage this functionality.”

Why Does Java Need This?

According to JEP 222: JShell, “The number one reason schools cite for moving away from Java as a teaching language is that other languages have a ‘REPL’ and have far lower bars to an initial ‘Hello, world!’ program.” If we want Java to have a bright future (and don’t we all?) then Java has to compete with other languages (Scala, Groovy, Clojure, Python, Ruby, Haskell…) in academia that have REPL’s and a low barrier to entry.

The REPL is a good feature for students, but what about professional developers? Ask a professional Scala developer, and it becomes clear that the REPL is an iterative development tool with even faster feedback than TDD. Additionally it lets us experiment with third-party libraries with less ceremony than setting up a new project. Finally, it allows us to execute arbitrary Java code from the command line, bringing Java much closer in usability to a scripting language. So at a professional level, the REPL aims to make us more productive in a very direct way.

What Features Does It Have?

JShell maintains history, has a built-in editor, has tab-completion, saves and loads code, and has automatic addition of semicolons. It has forward references (except in method signatures) so we can reference a variable or method before it’s defined. To see everything it can do, call jshell -help from the command line, or /help from within jshell.

How Else Can I Use It?

JShell is pretty flexible and has an API, so people are likely to come up with creative uses for it.

People may use it like a Java oriented shell for doing regular work like we do with the bash shell right now. I can imagine Java moving at least partially into the scripting space, so people have another language at their disposal to work from the command line with files and data, connect to servers or databases, retrieve and manipulate data, etc.

The fact that JShell includes an API means we are likely to see this included with IDE’s, providing a Java “scratch pad” for our daily work. The API also means it could potentially integrate with build tools and increase the flexibility of build scripts.

Personally I would like to see a Github Gist browser and downloader so it’s easy to experiment with other people’s ideas!

Example: Try A Library

We can load jars or classes to try them out in JShell, just specify a jar file when calling jshell –class-path from the command line, or call /classpath from within the shell.

To try out a library like Google Guava, call this from the command line:

wget http://central.maven.org/maven2/com/google/guava/guava/19.0/guava-19.0.jar
jshell --class-path guava-19.0.jar 

then inside jshell, we can type in some code like this:

import com.google.common.base.Optional;
Optional b =  Optional.of(new Integer(10));
b.get()

// java 8's Optional has .ofNullable()
Optional a = Optional.fromNullable(null);
a.or(5);

Example: Pretend Java Is A Scripting Language

I think .jsh makes a good file extension for Java snippets intended for use with JShell. Let’s put this in a file called hello.jsh:

System.out.println("hello world!")
/exit

Then from the command line

jshell hello.jsh

Yay, a compiled language that runs like a script!

Example: Load Code At Startup

What if we wanted Linux bash shell-like capabilities inside JShell? We could write code to accomplish that capability, and have that code loaded at startup time.

Let’s put this code in a file called bash.jsh

// a startup file completely replaces the default
// so need to bring in the default imports yourself

import java.util.*
import java.io.*
import java.math.*
import java.net.*
import java.util.concurrent.*
import java.util.prefs.*
import java.util.regex.*

void ls() {
  File cur = new File(".");
  for(String s : cur.list())
    System.out.println(s);
}

Then from the command line:

jshell --startup bash.jsh

Now when we type “ls()” from within jshell we get the file listing of the current directory. It would probably be a bit of work, but in theory we could replicate a complete shell environment. But, you know, we already have a shell. 🙂 What we will see in practice is more likely to be freely available snippets for working with data and code at a higher level.

Conclusion

JShell has a lot of potential to change the way we learn and use Java. I have high hopes for its expanded use in Java 9!

How will you use JShell?

Advertisements

Leave a comment

Filed under Java 9

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s