Java REPL – What is it for java developers?

Java REPL

REPL, or Read-Evaluate-Print-Loop, is a shell interface that reads each line of input, evaluates that line, and then prints the result. When you use a REPL, you are writing code interactively and executing it without delay.

The Java REPL provides a command line interface wherein you can evaluate or execute statements using Java Programming Language elements. It will be very useful for learning the Java language.

Typical Java development means writing a complete program, then compile it (fixing any errors), running it, figuring out what is wrong, editing, and repeating. With the Java REPL you can enter program elements one at a time, see the result immediately and adjust the statement accordingly.

Getting Started
Java 9 introduces Read-Eval-Print Loop (REPL) for the Java Programming Language. The REPL accepts Java programming elements such as Java statements, variables, method, and class definitions, imports, and expressions. I’ll refer to these pieces of Java code as “snippets”. You can test your code as you create it, and way before you are done with your whole project. For example, you can enter a statement at the prompt, any side-effects will take place and any output will be displayed:

-> System.out.println(“Hello World”);

Hello World

->

By default, the REPL will give you descriptive information about what you enter. Here, a variable is defined:

-> int x = 45

| Added variable x of type int with initial value 45

Note that terminating semicolons in the statement will be automatically added if missing.

When an expression is entered, a temporary variable is created so that the value can be referenced later. e.g.

-> 2 + 2

| Expression value is: 4

| assigned to temporary variable $1 of type int

Here $1 is the name of the temporary variable assigned. This variable can be used in the consecutive statements like this,

java>10+$1

| Expression value is: 14

| assigned to temporary variable $2 of type int

As you can see a new temporary variable $2 is created to hold the new result.

Define a method

You can define a method like this,

-> void fullname(String firstname, String lastname) {
>> System.out.println(firstname+” “+lastname);
>>}

| Added method fullname

You can then call the method as below,

-> fullname(“Albert”, “Einstein”);
| Expression value is: “Albert Einstein”
| assigned to temporary variable $3 of type String

 

If there is any error in the statement, it will be notified.
-> String fullname(String firstname, String lastname) { System.out.println(firstname+” “+lastname);}

ERROR: missing return statement
 String fullname(String firstname, String lastname) { System.out.println(firstname+” “+lastname);}
 ^

So you can correct the statement and write like this,

-> String fullname(String firstname, String lastname) {
>> return firstname+” “+lastname;
>>}

| Added method fullname

Define a class

The following example demonstrates how to define an entire class and then reference that class in an expression – all without leaving the REPL. The ability to dynamically create and test code frees you up to quickly experiment and iterate with new code.

Commands
The Java REPL has a number of commands for settings and to display information. They are distinguished from snippets by a leading slash. You can get information on the list of current variables, methods, and classes with the /vars, /methods, and /classes commands. You can get a list of entered snippets with the /list command. For example:

-> /vars

| int x = 45

| int $1 = 4

| int $2 = 14

| String $3 = “Albert Einstein”

-> /methods

| fullname (Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String;

| printf (Ljava/lang/String;[Ljava/lang/Object;)V

The REPL has start-up entries that are silently and automatically executed before the REPL starts, so that you can get to work quickly. Several common imports and a handy printf method are the default start-up entries. You can personalize your start-up entries with the /setstart command (whose argument is a file name to read), all subsequent invocations of the REPL will use the entries you specified. The /savestart is useful if you wish to create your file as a variant to the default startup.

Use /help for a list of commands. Note that most commands have a one character shortcut, for example “/l” for list.

Other important commands include /exit to leave the REPL, /save to save your snippets, /open to read them back in, and /classpath to add to the paths that will be searched for referenced classes.

You may have noticed that the REPL is quite chatty, you can set the amount and format of output with the /feedback command, for example “/feedback concise”. If you plan to primarily use the REPL by pasting from other windows, you may wish to toggle off the prompt with /prompt.

Changing Definitions

You can change the definition of a previously entered variable, method, or class by simply entering a new definition. For example, the method we defined above can get new new definition:

-> String fullname(String firstname, String lastname) {
>> return “Name: ” + firstname +” “+lastname;
>> }
| Modified method fullname

-> fullname(“Albert”, “Einstein”)

| Expression value is: “Name: Albert Einstein”

| assigned to temporary variable $4 of type String

Note that rather than saying “Added method”, as before, it says “Modified method” — this means that the definition was changed, but has the same signature, and thus all existing usages continue to be valid.

You may also change definitions in incompatible ways. For example:

-> String x

| Replaced variable x of type String

We have changed the type of the variable x, note that it now says “Replaced”

Forward Reference

Because a goal of the REPL is to support exploratory programming (interactively develop and debug a program without having to go through the usual constraints of the edit-compile-run-debug cycle.), the REPL allows you to define methods whose bodies reference methods, variables, or classes which are not yet defined. Let’s say you wish to define a method to find the area of circle, you can enter the formula:

-> double circlearea(double radius) {
>> return PI * radius * radius;
>> }
| Added method circlearea, however, it cannot be invoked until the variable PI is declared

The REPL allows the definition but warns of what is yet to be defined. The definition may be referenced, but if execution is attempted, it will fail:

-> circlearea(2)

| Attempted to call circlearea which cannot be invoked until the variable PI is declared.

-> double PI = 3.1415926535

| Added variable PI of type double with initial value 3.1415926535

 

| Expression value is: 12.566370614

| assigned to temporary variable $2 of type double

With the variable declared , circlearea now works.

History

The REPL maintains a history of snippets and commands. You navigate this history to re-enter or edit prior input with the up/down/left/right arrows. Entered text will be inserted. The Delete key can be used to delete text. Press the Enter key to accept the history line again (modified or not).

You can move a snippet at a time by using control-up and control-down (that is holding the control key while pressing the up or down key). REPL provides the /history command to list all of the statements and expressions evaluated in a REPL.

Tab Completion

Press the tab key to complete the current entry. For example:

circ<tab>

Will be replaced with:

circlearea(

If there is more than one completion the set of completions will be listed.

Editors

To more easily edit past entries, particularly one’s of many lines, you can invoke an editor on the snippet by providing its name or id (number in /list):

-> /edit Employee

Running this /edit command loads a simple editor where I can alter the class definition and have the class updated immediately.

To edit all snippets and to enter new ones, invoke /edit without an argument.

Exceptions

In an exception backtrace, a location within REPL entered code is displayed as the #id/linenumber, where snippet id is the number displayed in /list and linenumber is the linenumber within the snippet. So, below, the exception occurs in snippet #9 aka divide() on the second line of divide:

-> int divide(int x, int y) {
>> return x / y;
>> }
| Added method divide

-> divide(5, 0)

| java.lang.ArithmeticException thrown: / by zero

| at divide (#9:2)

| at (#10:1)

-> /list

9 : int divide(int x, int y) {

return x / y;

}

10 : divide(5, 0)

Conclusion

I don’t think that REPL will overtake traditional Java development in an IDE. Instead I feel the Java REPL will be very useful for learning Java because Java programs require so much setup that it can be challenging for developers learning the language to understand the syntax quickly.

The following two tabs change content below.
Working as a Java developer since 2010. Passionate about programming in Java. I am a part time blogger.

Add Comment

Required fields are marked *. Your email address will not be published.