Monday, September 28, 2009

DrJava with Mint Released

The latest releases of DrJava contains a compiler adapter for Mint. That means it is possible to conveniently compile Mint programs in the DrJava IDE.

To experiment with Mint and DrJava, please do the following:
  1. Download DrJava with Mint from the JavaMint implementation page. The file will be named drjava-rxxxx-mint-ryyyyy.jar, where xxxx indicates the version of DrJava and yyyyy the version of Java Mint.

  2. MacOS only: Java Mint requires Java 6. If you have a 32-bit Mac for which Apple does not offer Java 6, you can use Soylatte, but that means DrJava needs to be run under Soylatte as well. Soylatte requires X11 to display graphical user interfaces (GUIs).

    1. Change your PATH environment variable so that Soylatte's java and javac commands are found first. Edit your .bash_profile or .bashrc file and add the following line at the end of the file:
      export PATH=/usr/local/soylatte/bin:$PATH
    2. Install Apple's X11. You can find it on your MacOS X installation DVD (preferred!). Here are also some links where you may download X11 (not checked by us -- if you try any of these, please let us know!):

    3. Start the X11 application. A terminal window should open. Put the cursor in that terminal window -- you will start DrJava from there.

  3. Start DrJava using
    java -jar drjava-rxxxx-mint-ryyyyy.jar
    (in the terminal window on MacOS and Linux; on Windows, you can double-click on the drjava-rxxxx-mint-ryyyyy.jar file)

  4. Look at the right side of the in the "Compiler Output" pane. There is a drop-down box labeled "Compiler": Select "Mint 6.0_16-Mint" (or something similar). If you don't see it in the list, DrJava could not find Mint. Check that you are running DrJava with Java 6.

  5. Open a Mint program ("File/Open" menu or "Open" button)

  6. Compile it ("Tools/Compile All" menu or "Compile" button)

  7. Run it ("Tools/Run Document's Main Method" menu or "Run" button). The output will be displayed in the "Interactions" pane.

Note that the interpreter in the Interactions pane does not understand Mint. It is just a Java interpreter. Brackets and escapes are only recognized in programs in the Definitions pane (source editor).

Thursday, September 24, 2009

Installing JavaMint on Linux

Here are some quick instructions on how to download and install Java Mint.

MacOS

  1. You need Sun's JDK 5 or 6 installed.
  2. Download the "binaries only" Java Mint zip file from the Java Mint implementation page. In this example, I have saved the file in my home directory, i.e. at /home/mgricken.
  3. Open a console.
  4. Change into the /usr/local directory:
    cd /usr/local
  5. Unzip it as root. This means you have to type in your password:
    sudo unzip /home/mgricken/JavaMint-r13871-binaries.zip
  6. Set the MINT_HOME and PATH environment variables:
    export MINT_HOME=/usr/local/JavaMint
    export PATH=$PATH:$MINT_HOME/langtools/bin
  7. To make this permanent, edit your .bash_profile or .bashrc file and put the two lines from step 6 line at the end of the file.
Now you can compile programs using mintc and run them using mint.

mintc Power.java

mint Power


There are samples in the /usr/local/JavaMint/langtools/mintTest directory. You cannot compile them there, however, because the directory is read-only unless you are the root user. So unzip the Java Mint implementation zip file somewhere else, e.g. in /home/mgricken/JavaMint.

Monday, September 14, 2009

Higher Order Functions in Java

In order to understand future examples, we first have to discuss how to use higher-order functions in Java, and how to write anonymous inner classes. This post will have nothing to do with multi-stage programming.

Let's write a program that can print out data tables for different mathematical functions. For example, for a function that multiplies by two, f(x) = 2x, we want to print something like this:

x                      f(x)
-5.0000000000 -10.0000000000
-4.0000000000 -8.0000000000
-3.0000000000 -6.0000000000
-2.0000000000 -4.0000000000
-1.0000000000 -2.0000000000
0.0000000000 0.0000000000
1.0000000000 2.0000000000
2.0000000000 4.0000000000
3.0000000000 6.0000000000
4.0000000000 8.0000000000
5.0000000000 10.0000000000


We can write a function like this:

    public static void printTableTimesTwo(double x1,
double x2,
int n) {
assert n>1;

double x = x1;
double delta = (x2-x1)/(double)(n-1);
System.out.println("x f(x)");
System.out.printf("%20.10f %20.10f\n", x, x*2);
for(int i=0; i<(n-1); ++i) {
x += delta;
System.out.printf("%20.10f %20.10f\n", x, x*2);
}
}


The parameter x1 determines the lower end of the interval, x2 the upper end, and n determines how many values should be printed. n needs to be at least 2 to print out the values at x1 and x2. We can generate the table above with this call:

        printTableTimesTwo(-5, 5, 11);


What if we want to print out the values of a different function, for example f(x) = x + 4? We can write a new function:

    public static void printTablePlusFour(double x1,
double x2,
int n) {
assert n>1;

double x = x1;
double delta = (x2-x1)/(double)(n-1);
System.out.println("x f(x)");
System.out.printf("%20.10f %20.10f\n", x, x+4);
for(int i=0; i<(n-1); ++i) {
x += delta;
System.out.printf("%20.10f %20.10f\n", x, x+4);
}
}


This involves a lot of code duplication, though. The only parts that actually differ are the two occurrences of x*2 and x+4. How can we factor that difference out?

Let's write an interface that we can use for any kind of function that takes in one parameter and returns one parameter f(x) = y is an example of such a function.

public interface ILambda<R,P> {
public R apply(P param);
}


This interface is called ILambda and it has one method, apply. We used Java generics and didn't specify the return type and the type of the parameter; instead, we just called them R and P, respectively. A function that takes in a Double and that returns a Double, like f(x) = y, can be expressed using a ILambda<Double,Double>. A function taking a String and returning an Integer would use ILambda<String,Integer>.

Now we can write our f(x) = 2x and f(x) = x + 4 functions using ILambda:

    public class TimesTwo implements ILambda<Double,Double> {
public Double apply(Double param) { return param*2; }
}
public class PlusFour implements ILambda<Double,Double> {
public Double apply(Double param) { return param+4; }
}


Now we can write one printTable method that takes in an ILambda<Double,Double> called f representing the function, in addition to the parameters x1, x2 and n, as before:

    public static void printTable(ILambda<Double,Double> f,
double x1,
double x2,
int n) {
assert n>1;

double x = x1;
double delta = (x2-x1)/(double)(n-1);

// f.apply(x) just means what f(x) means in math!
double y = f.apply(x);
System.out.println("x f(x)");
System.out.printf("%20.10f %20.10f\n", x, y);
for(int i=0; i<(n-1); ++i) {
x += delta;
y = f.apply(x);
System.out.printf("%20.10f %20.10f\n", x, y);
}
}


Note that when we want to print out the y-value, we just write f.apply(x), which looks very similar to f(x) in mathematics. It means exactly the same.

We can print out the tables for our two functions using:

        printTable(new TimesTwo(), -5, 5, 11);
printTable(new PlusFour(), -5, 5, 11);


We have to create new objects for the functions: The first time we call printTable we pass a new TimesTwo object; the second time, we pass a new PlusFour object.

We can now define as many functions as we like without having to rewrite the printTable function. For example, we can easily write a square root function and use it very easily:

    public class SquareRoot implements ILambda<Double,Double> {
public Double apply(Double param) {
return Math.sqrt(param);
}
}

// ...

printTable(new SquareRoot(), -5, 5, 11);


The really neat thing is that we can even define a new function on-the-fly, without having to give it a name. We do that using anonymous inner classes in Java. Here, we call printTable and pass it a new object that implements ILambda<Double,Double>.

        printTable(new ILambda<Double,Double>() {
public Double apply(Double param) {
return param*param;
}
}, -5, 5, 11);


We define a new ILambda from Double to Double without giving it a name. When we use anonymous inner classes, we need to fill in all the methods that are still abstract. Here, it is just the apply method.

The method printTable is now a "higher order function", because conceptually it is a function that takes another function as input.

Questions:

  1. What does the anonymous ILambda<Double,Double> in the example above compute? What's the mathematical function it represents?

  2. How would you print a table for the function f(x) = x2 + 2x?



You can download the complete source code for the examples here:

Wednesday, September 9, 2009

Power Using a for Loop

Soon it will be possible to compile and run Mint programs in
DrJava. I just haven't had time to finish this. In the meantime, here is a program that you can analyze. It is another program that calculates the power x^n.

import edu.rice.cs.mint.runtime.Code;


public class Power_For {
public static void main(String[] args) {
final double x = 2;
int n = 17;

Code<Double> c = <| 1.0 |>;
for(int i=0; i<n; ++i) {
c = <| `c * x |>;
}

System.out.println(c.run());
}
}


This time it uses a for loop. I don't know if you have seen for loops, but the part

for(int i=0; i<17; ++i) { /* something here */ }

sets a variable i to 0, and repeats the part /* something here */ as long as i<n. Each time the loop is done with /* something here */, it will execute ++i, which will increase i by 1. So eventually i will be 17, and since n is 17, i is not < n anymore, and the loop exits.

We have a Code<Double> c that starts out with the code for 1.0:

Code<Double> c = <| 1.0 |>;

Then we have the aforementioned for loop. The code that gets executed
over and over in the loop body is

c = <| `c * x |>;

We are creating a new code value, and inside the code value, we're splicing in c (initially 1.0) and multiplying it with x. Then we assign the new code value back to c. That means after the first
iteration of the loop, c will be the following:

<| 1.0 * x |>

After the second iteration, c will be

<| 1.0 * x * x |>

And so on. After the 17th iteration, it will contain the code

<| 1.0 * x * x * x * x * x * x * x * x * x * x * x * x * x
* x * x * x * x |>


When we run c with c.run() and print out the value, we will get 131072.0, which is 2 to the power of 17, as expected.

You can download the complete source code for the example here:

Friday, September 4, 2009

Installing JavaMint on Windows

Here are some quick instructions on how to download and install Java Mint.

Windows

  1. You need Sun's JDK 6 installed.
  2. Download the "binaries only" Java Mint zip file from the Java Mint implementation page. In this example, I have saved the file on my desktop, i.e. at C:\Program Files.
  3. Open an Explorer Window and find the zip file you saved in step 2.
  4. Right-click on the zip file and choose "Extract All..." and unpack all files in C:\Program Files. This will create a C:\Program Files\JavaMint directory. If you don't see an "Extract All..." option in your context menu, you may need to download a program such as WinZip or WinRar first.
  5. Right-click on "My Computer" and select "Properties". Go to the "Advanced" tab and press the "Environment Variables" button.
  6. Click on the “New” button in the “System variables” box.
  7. Enter as variable name: MINT_HOME
    and as variable value: C:\Program Files\JavaMint
  8. Find the Path variable in the "System variables" box, select it and click "Edit".
  9. Go to the end of the text entered for "Variable value", and add the following text:
    ;%MINT_HOME%\langtools\bin
    Be sure to enter the semicolon at the beginning of the added text.
  10. Press "OK" three times to close all three opened dialogs. Now you have added JavaMint to your path.
Now you can compile programs using mintc and run them using mint. Open a Command Prompt by clicking on the "Start" button, selecting "Run" and entering cmd and pressing "OK" (or search for the "Command Prompt" program in your Start Menu).

mintc Power.java

mint Power


There are samples in the C:\Program Files\JavaMint\langtools\mintTest directory.

Installing JavaMint on MacOS

Here are some quick instructions on how to download and install Java Mint.

MacOS

  1. You need to have Java 6 installed.

    Note: If you have a 32-bit Mac that does not have an Apple version of Java 6, you can use SoyLatte. Please install it in /usr/local/soylatte, i.e. the Java compiler should be /usr/local/soylatte/bin/javac.

  2. Download the "binaries only" Java Mint zip file from the Java Mint implementation page. In this example, I have saved the file on my desktop, i.e. at /Users/mgricken/Desktop.
  3. Open a console.
  4. Change into the /usr/local directory:
    cd /usr/local
  5. Unzip it as root. This means you have to type in your password:
    sudo unzip /Users/mgricken/Desktop/JavaMint-r13871-binaries.zip
  6. Set the MINT_HOME and PATH environment variables:
    export MINT_HOME=/usr/local/JavaMint
    export PATH=$PATH:$MINT_HOME/langtools/bin
  7. To make this permanent, edit your .bash_profile or .bashrc file and put the two lines from step 6 line at the end of the file.
Now you can compile programs using mintc and run them using mint.

mintc Power.java

mint Power


There are samples in the /usr/local/JavaMint/langtools/mintTest directory. You cannot compile them there, however, because the directory is read-only unless you are the root user. So unzip the Java Mint implementation zip file somewhere else, e.g. in your Documents directory.

The easiest way to experiment with Mint is to download DrJava with Mint. Here are more instructions on how to run DrJava with Mint.

Note: If you are using SoyLatte as your Java 6, please start DrJava with Mint from inside an X11 terminal window.

Welcome!

You've found the Java Mint Blog!

Despite all of our efforts not to use the name MetaJava for Java Mint, the domain JavaMint was already taken. So, the name MetaJava will live on! :)

This blog will be used to post announcements and useful materials relating to MetaJava, and to follow up on comments from readers.