90 Days

90 days and two re-send requests, and the Texas DPS still hasn’t managed to get me my drivers license.

I think I also have a dysnumeric mail man, though. So maybe the DPS mailed it, but someone else received it.

Update

The Public Information Office of the Texas DPS actually read my halfhearted complaint and got in touch with me. I had already been talking to someone in the Drivers License Office for weeks, so I’m grateful for this gesture. Maybe this get me my license a bit faster.

Update

I finally received my drivers license. Thanks for everyone at the Texas DPS who helped tracking it down.

Renewed Texas Drivers License, Received after 91 Days

Renewed Texas Drivers License, Received after 91 Days

Share
Posted in Pictures, Ramblings | Leave a comment

Print This Post Print This Post  

24 Hour Fitness “Personal Fitness Consultation”

I signed up for a membership at 24 Hour Fitness. The free neighborhood pools in Houston are closed now that the summer is over, and I wanted to continue being able to swim. Two of the gyms nearby have swimming pools, and when I found out they also had a sauna, I just had to try it out.

Today was my free “personal fitness consultation”. I expected to be shown around in the gym, maybe to have a few of the machines demonstrated to me, depending on my fitness goals (which really are just to have fun and stay active and healthy). Nope, it was a high pressure sales pitch to buy personal training.

According to my consultant, there are five components to being healthy:

  1. Nutrition, and I eat healthy
  2. Cardio, which I already do
  3. Strength, which I don’t really do, so he wanted to focus on that

So far, so good. The last two where the kicker, though:

  1. Instruction, which I could pay for… from him, right here and right now!
  2. Supplements, which I could also buy… right here and right now!

I’m sure I could learn a lot, but I just don’t believe that I can’t be healthy without his instructions and supplements. I dove in the swimming pool instead.

Share
Posted in Ramblings | Leave a comment

Print This Post Print This Post  

COMP 410 Customer Meeting

I had my first meeting as “customer” with this semester’s COMP 410 class today. It was a lot of fun for me. From the class website:

COMP 410 is a unique experience in learning fundamental principles of software engineering. As a pure “discovery-process” learning environment, students are placed into a realistic software development scenario and are given the freedom to explore and develop their own interpretations of the guiding ideas and skills behind successful software development.

I requested a system that represents a marriage of technology and art, a way to turn real time data into collaborative, interactive graphical displays.

Share
Posted in Teaching | 2 Comments

Print This Post Print This Post  

New DrJava Stable Release: drjava-stable-20100913-r5387

We have made an updated stable version available: drjava-stable-20100913-r5387. You can download it from the DrJava website or from SourceForge.

Available for download at http://drjava.org .

DrJava is a lightweight programming environment for Java designed to
foster test-driven software development. It includes an intelligent
program editor, an interactions pane for evaluating program text, a
source level debugger, and a unit testing tool.

This stable release represents an update to the previous stable
release, providing a bug fix for three issues that proved to be
inconvenient for users.

Note: Java 1.4 compatibility has been dropped. To use DrJava, you will
need Java 5 or newer.

Bug fixes since last stable release:

  • The “Smart Run” feature properly runs a main method in a class
    first, and it does not attempt to call a zero-parameter constructor
    of a class if it does not exist.
  • The Apple Java 6 Developer Preview 6 (javase6release1dp6.dmg) is
    excluded as Java 6 JDK, as it does not contain a Java 6-compatible
    compiler. This caused NullPointerExceptions in rare cases.
  • On Linux systems with Java 5 or older, Metal is the default
    look-and-feel again. The system look-and-feel turned out to be
    awful.

Note: These patches were applied to the previous stable release
in a branch. Even though this release has revision 5387, other
features, like Habanero Java integration, are not yet included.
They will be contained in an upcoming development release.

Share
Posted in DrJava | Leave a comment

Print This Post Print This Post  

Is iConcept Press a Vanity Press?

I received an email from iConcept Press this morning:

Based on your paper: Test-first Java concurrency for the classroom (2010), we would like to invite you to submit a chapter to our book project under the working title: Java in Academic and Research. The editor of this book is [redacted].

We are especially interested in the motivation of your problem and why you model your problem in such way. We would like you to expand the paper and contribute to our book. Please note that we are not asking to republish the mentioned paper.

All our books are published as hard copy with ISBN and as open access. Each corresponding author will receive one copy of the book free of charge. The publishing fee (for each paper) is USD$38/page for the first 16 pages and USD$18/page thereafter. Each chapter normally has 16 – 25 pages.

About $600 for a book chapter, that sounds like a vanity press to me. iConcept Press claims to do peer review, but I don’t exactly trust that claim:

Is it that I simply pay money and my article can be printed in your book?

No. We go through several review processes. If your article is not up to our standards or is not what we require, we will not publish your article, even if you pay us.

Who are the reviewers? Who are the other authors who contribute? The editor of the book was given, but he seems to be rather unknown. The books that have been published by iConcept Press don’t seem to be complete garbage, judging by a quick glance at bioinformatics material, for example, from an outsider’s perspective, but I’m in no position to really make that determination.

I think if it weren’t for the publishing fee, I might roll with it. But I’m not going to spend $600 to have something published that might end up being a diamond in a turd.

Share
Posted in Ramblings | 10 Comments

Print This Post Print This Post  

Auto-Refresh Project: A Forgotten DrJava Feature

I just used a DrJava feature that I pretty much forgot about: Auto-Refresh Project. It scans the project root for new source files and adds them to the project. It works really well.

DrJava: Auto-Refresh Project Feature

The feature was implemented under my supervision. How come I can’t find any reference to it in the DrJava documentation?

Share
Posted in DrJava | Leave a comment

Print This Post Print This Post  

Having a Good Time

I attended the wedding of two of my friends in San Antonio this past weekend. I had a good time.

At the wedding of two of my friends, September 3, 2010.

Really. This is what me having a good time looks like. And that’s not jealousy on my face.

Share
Posted in Pictures | Leave a comment

Print This Post Print This Post  

DrJava/HJ Born

I have been able to merge Vincent’s and Jarred’s changes into the DrJava trunk to create a version of DrJava/HJ that can compile and run Habanero Java (HJ) programs. Most importantly, there is a version where both HJ and DrJava are in one 20 MB file. Please try it out: drjava-hj.jar

DrJava/HJ Logo

I have identified a change that needs to be made to the HJ Runtime in order to integrate it with DrJava. It is small and does not affect the performance or execution of HJ when it is run independently from DrJava.

The class loader that HJ uses to find classes it is running has to be changed. DrJava has a dynamic class path, depending on the files that are open, the configuration of the project, and the global preferences. If HJ is to find the classes that DrJava has compiled, HJ needs to use the class loader DrJava provides. DrJava passes this class loader to its runtimes as “thread context class loader”, which “provides a way to pass an ‘intended classloader parent’ into a framework without explicitly needing to pass it.” [source]

The thread context class loader can be queried using [cci lang=”java”]Thread.currentThread().getContextClassLoader()[/cci] and needs to be passed wherever a user class is loaded using [cci lang=”java”]Class.forName[/cci]. I found four such calls to [cci lang=”java”]Class.forName[/cci] in the HJ runtime. The nice thing about the thread context class loaders is that, unless they are set, they default to the system class loader. As a result, unless DrJava (or some other application using the HJ runtime) set the thread context class loader to tell HJ “use this class loader to find my classes”, everything is just as before.

Share
Posted in DrJava, Research | 1 Comment

Print This Post Print This Post  

Mint on the Mac

I guess I’m a bit behind the technology curve. The MacBook that I’m using as one of my development machines is one of the original white Intel MacBooks with a Core Duo CPU (not Core 2 Duo). It’s a 32-bit machine, and Apple doesn’t offer Java 6 for 32-bit computers.

Mint, however, requires a version of Java 6, which is why we recommended using SoyLatte to run Mint. That comes with all kinds of inconveniences because SoyLatte uses X11 for its GUIs, which means DrJava needs to run under X11.

Yesterday I tested Mint and DrJava with Mint using Apple’s Java SE 6.0 Release 1 Developer Preview 6 (file name: javase6release1dp6.dmg), which I still had floating around and which is the last version of Apple’s Java 6 that still runs on 32-bit Macs. It works! SoyLatte is only required if you don’t have a version of Java 6 (either Apple’s official version on 64-bit Macs, or Apple’s Java SE 6.0 Release 1 Developer Preview 6 on 32-bit Macs) on your Mac.

I have updated the instructions on how to install Java Mint on the Mac and how to run DrJava with Mint accordingly.

(Re-posted from The Java Mint Blog.)

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

Reflection-Based S-Expression Parser

I’m really quite proud of this little reflection-based S-expression parser that I wrote for our GPCE Mint tutorial.

We wanted to have a parser so we don’t have to construct our ASTs using Java code. The problem was that we’ll probably have ten different mini-languages, and we didn’t want to write a parser for each language. Reflection was the answer, of course.

For this parser to work, you need to define the base class of the class hierarchy (e.g. [cci lang=”java”]Exp[/cci]) and the subclasses as static nested classes inside the same outer class (e.g. all inside [cci lang=”java”]UnstagedLint[/cci]).

You then simply specify the base class, and the parser will search for the subclasses. The names of the S-expressions are the simple names of the subclasses (e.g. Add and Int if there are [cci lang=”java”]Add[/cci] and [cci lang=”java”]Int[/cci] subclasses).

When encountering an S-expression, the parser will try all of the constructors of the corresponding class. As arguments for a constructor, the parser can process all primitive types, the boxed types, strings, recursive occurrences of the base class (e.g. [cci lang=”java”]Add[/cci] containing two [cci lang=”java”]Exp[/cci] instances), as well as other class hierarchies, which are parsed using subparsers.

These subparsers work the same way the main parser works. For example, if a [cci lang=”java”]Val[/cci] constructor needs a [cci lang=”java”]Value[/cci] argument, and there is a subparser registered for the [cci lang=”java”]Val[/cci] hierarchy, the main parser will delegate to that subparser. Here’s an example:

[cc lang=”java”]DataTypes.Exp e =
new LintParser(DataTypes.Exp.class)
.addSubParser(new LintParser(DataTypes.Value.class))
.parse(“(Add (Val (IntValue 1)) (Val (IntValue 2)))”);[/cc]

This creates a parser for expressions of class [cci lang=”java”]DataTypes.Exp[/cci], and it registers a subparser for expressions of class [cci lang=”java”]DataTypes.Value[/cci]. Then it parses the string [cci](Add (Val (IntValue 1)) (Val (IntValue 2)))[/cci]. The [cci](IntValue 1)[/cci] and [cci](IntValue 2)[/cci] substrings are parsed using the subparser.

It’s really quite elegant. Especially the ease of integrating the subparsers surprised me. Here’s the parser in full.

[cc lang=”java” lines=”20″]package parser;

import java.lang.reflect.*;
import java.util.*;

/**
* A reflection-based S-expression parser returning an expression of type E.
* Written by Mathias Ricken and Edwin Westbrook.
*/
public class LintParser {
/** Convenience method to parse string s into an expression of class c,
* using the specified subparsers as help, if the parser encounters non-primitive,
* non-string arguments to S-expressions not within the class hierarcy under class c.
* @param c class of the expression
* @param s string to parse
* @param subParsers subparsers for non-primitive, no-string values
* @return expression of class c */
public static T parse(Class c, String s, LintParser… subParsers) {
LintParser p = new LintParser(c);
for(LintParser sp: subParsers) {
p.addSubParser(sp);
}
return p.parse(s);
}

/** Exception being thrown if the string cannot be parsed. */
public static class ParseException extends RuntimeException { }

/** The class of the expression (e.g. lint1_arithmetic.UnstagedLint.Exp). */
private Class _expClass;

/** The class enclosing the expression classes (e.g. lint1_arithmetic.UnstagedLint). */
private Class _enclosingClass;

/** A map from S-expression names to classes (e.g. Int -> lint1_arithmetic.UnstagedLint.Int). */
private HashMap> _classes =
new HashMap>();

/** A map from classes for which subparsers have been registered to the subparsers. */
private HashMap,LintParser> _subParsers =
new HashMap,LintParser>();

/** Create a new parser for expressions of class expClass.
* @param expClass the class of the expressions to be parsed */
public LintParser(Class expClass) {
_expClass = expClass;
_enclosingClass = _expClass.getEnclosingClass();
// find all concrete, static subclasses of expClass contained in the same enclosing class
for(Class c: _enclosingClass.getDeclaredClasses()) {
if (((c.getModifiers() & Modifier.ABSTRACT)==0) &&
((c.getModifiers() & Modifier.STATIC)!=0)) {
try {
Class contained = c.asSubclass(_expClass);
_classes.put(contained.getSimpleName(), (Class)contained);
println(contained.getSimpleName());
}
catch(ClassCastException cce) { /* skip */ }
}
}
}

/** Add a subparser for expressions of type S. Return this parser (not the subparser!)
* for method chaining.
* @param p subparser for expressions of type S
* @return this parser (for expressions of type E) */
public LintParser addSubParser(LintParser p) {
_subParsers.put(p._expClass, p);
return this;
}

/** Parse the string.
* @param s the string to be parsed
* @return the expression of type E */
public E parse(String s) {
println(“parse ‘”+s+”‘”);
RestoreStringTokenizer st = new RestoreStringTokenizer(s.trim());
return parse(st);
}

/** Parse the tokens in the tokenizer.
* @param s the tokenizer with the tokens
* @return the expression of type E */
protected E parse(RestoreStringTokenizer s) {
// position to restore everything
final int sPos = s.getPosition();

// read (
parseWhitespace(s);
String word = s.nextToken();
println(“word: ‘”+word+”‘”);
if (!word.equals(“(“)) {
s.restorePosition(sPos);
throw new ParseException();
}

// read S-expression name
parseWhitespace(s);
word = s.nextToken();
println(“word: ‘”+word+”‘”);
if (!_classes.containsKey(word)) {
// don’t know what that is, restore
s.restorePosition(sPos);
throw new ParseException();
}

// known subclass of E
Class c = _classes.get(word);
println(“Class: “+c.getSimpleName());
parseWhitespace(s);

// position to restore after trying out a constructor
final int sTryCtorPos = s.getPosition();

Constructor ctor;
for(Constructor ctor2: c.getDeclaredConstructors()) {
println(“\ttrying ctor “+ctor2);

// this is necessary since c.getDeclaredConstructors() returns Constructor
// but we want Constructor
try { ctor = c.getConstructor(ctor2.getParameterTypes()); }
catch(NoSuchMethodException nsme) { throw new AssertionError(“Should never happen.”); }

// try to parse the arguments for this constructor
Object[] args = new Object[ctor.getParameterTypes().length];
int argIndex = 0;
try {
for(Class paramC: ctor.getParameterTypes()) {
// primitive types and their boxed types
if ((paramC==int.class) || (paramC==Integer.class)) {
args[argIndex] = parseLeaf(s,Integer.class);
}
else if ((paramC==boolean.class) || (paramC==Boolean.class)) {
args[argIndex] = parseLeaf(s,Boolean.class);
}
else if ((paramC==long.class) || (paramC==Long.class)) {
args[argIndex] = parseLeaf(s,Long.class);
}
else if ((paramC==double.class) || (paramC==Double.class)) {
args[argIndex] = parseLeaf(s,Double.class);
}
else if ((paramC==float.class) || (paramC==Float.class)) {
args[argIndex] = parseLeaf(s,Float.class);
}
else if ((paramC==byte.class) || (paramC==Byte.class)) {
args[argIndex] = parseLeaf(s,Byte.class);
}
else if ((paramC==short.class) || (paramC==Short.class)) {
args[argIndex] = parseLeaf(s,Short.class);
}
// char or Character
else if ((paramC==char.class) || (paramC==Character.class)) {
// parse as string
Object temp = parseLeaf(s,String.class);
// must be exactly one character
if (temp.toString().length()!=1) throw new ParseException();
args[argIndex] = new Character(temp.toString().charAt(0));
}
// strings
else if (paramC==String.class) {
args[argIndex] = parseLeaf(s,String.class);
}
// recursively parse expressions of type E
else if (_expClass.equals(paramC)) {
args[argIndex] = parse(s);
}
// try to use a subparser
else if (_subParsers.containsKey(paramC)) {
// try one of the subparsers
args[argIndex] = _subParsers.get(paramC).parse(s);
}
else {
// don’t know what that is
// restore happens below
throw new ParseException();
}
++argIndex;
}
}
catch(ParseException pe) {
// this constructor didn’t work out, we need to restore and try another constructor
s.restorePosition(sTryCtorPos);
// continue with next constructor
continue;
}
try {
// we read all values required for this constructor
// make sure that the next token is )
parseWhitespace(s);
word = s.nextToken();
println(“word: ‘”+word+”‘”);
if (!word.equals(“)”)) {
// it wasn’t ), we need to restore and try another constructor
s.restorePosition(sTryCtorPos);
// continue with next constructor
continue;
}
parseWhitespace(s);

// successfully used this constructor
println(“new “+ctor.getDeclaringClass().getSimpleName()+” “+
java.util.Arrays.toString(args));
E e = (E)ctor.newInstance(args);
return e;
}
catch(Exception e) {
// something went wrong using this constructor, we need to restore and try another
s.restorePosition(sTryCtorPos);
// continue with next constructor
continue;
}
}

s.restorePosition(sPos);
throw new ParseException();
}

/** Parse a leaf of class c, which must have a unary constructor taking a String, from
* the tokenizer s.
* @param s tokenizer from which to parse
* @param c the class, which has a unary constructor taking a String, for that we want to create a value
* @return parsed value of class c */
protected Object parseLeaf(RestoreStringTokenizer s, Class c) {
// position so we can undo this attempt to parse
final int sPos = s.getPosition();

String word = null;
try {
// get the unary constructor taking String
Constructor ctor = c.getDeclaredConstructor(String.class);

// skip whitespace, get the string, skip whitespace
parseWhitespace(s);
word = s.nextToken();
println(“word: ‘”+word+”‘”);
Object o = ctor.newInstance(word);
parseWhitespace(s);

return o;
}
catch(NoSuchMethodException nsme) {
// something went wrong, restore and abort
s.restorePosition(sPos);
throw new ParseException();
}
catch(InstantiationException ie) {
// something went wrong, restore and abort
s.restorePosition(sPos);
throw new ParseException();
}
catch(IllegalAccessException iae) {
// something went wrong, restore and abort
s.restorePosition(sPos);
throw new ParseException();
}
catch(InvocationTargetException ite) {
// something went wrong, restore and abort
s.restorePosition(sPos);
throw new ParseException();
}
}

/** Parse whitespace. Stop before the next non-whitespace token, or when there are no
* more tokens.
* @param s tokenizer from which to parse whitespace */
protected void parseWhitespace(RestoreStringTokenizer s) {
String word;
int sPrevPos;
while(s.hasMoreTokens()) {
sPrevPos = s.getPosition();
word = s.nextToken();
if (!word.trim().equals(“”)) {
s.restorePosition(sPrevPos);
break;
}
}
}

/** Debug method to print, comment System.out.println call out to disable debug printing */
public static void println(Object o) {
// System.out.println(o.toString());
}

/** This tokenizer stores all read tokens in a stack so they can easily be
* restored. This isn’t as memory as it could be, but it’s good enough for
* small examples. */
public static class RestoreStringTokenizer extends StringTokenizer {
/** Stack of read tokens. */
private Stack _read = new Stack();
/** Stack of restored tokens. */
private Stack _restored = new Stack();
/** Create a new string tokenizer that can restore positions. */
public RestoreStringTokenizer(String s) { super(s,” ()”,true); }
/** Return the current position. */
public int getPosition() { return _read.size(); }
/** Rewind to a previous position. This only goes backward, not forward. */
public void restorePosition(int pos) {
while(_read.size()>pos) {
_restored.push(_read.pop());
}
}
// overridden methods from StringTokenizer
public int countTokens() { return _restored.size() + super.countTokens(); }
public boolean hasMoreTokens() { return (_restored.size()>0) || super.hasMoreTokens(); }
public boolean hasMoreElements() { return hasMoreTokens(); }
public String nextToken() {
String token = (_restored.size()>0) ? _restored.pop() : super.nextToken();
_read.push(token);
return token;
}
public Object nextElement() { return nextToken(); }
public String nextToken(String delim) {
if (_restored.size()>0) return _restored.pop();
return super.nextToken(delim);
}
}

public static void main(String[] args) {
lint2_cond.UnstagedLint.Exp e = parse
(lint2_cond.UnstagedLint.Exp.class,”(Ifz (Int 1) (Int 10) (Mul(Int 3)(Add(Int 5)(Int 10))))”);
System.out.println(new lint2_cond.UnstagedLint.Program(e).peval(lint2_cond.UnstagedLint.env0));

lint.DataTypes.Value v = parse(lint.DataTypes.Value.class, “(IntValue 1)”);
System.out.println(v);

lint.DataTypes.Exp e2 =
new LintParser(lint.DataTypes.Exp.class)
.addSubParser(new LintParser(lint.DataTypes.Value.class))
.parse(“(Add (Val (IntValue 1)) (Val (IntValue 2)))”);
System.out.println(new lint.DataTypes.Program(e2).peval(lint.DataTypes.env0, lint.DataTypes.fenv0));

lint.DataTypes.Exp e3 =
LintParser.parse(lint.DataTypes.Exp.class, “(Add (Val (IntValue 1)) (Val (IntValue 2)))”,
new LintParser(lint.DataTypes.Value.class));
System.out.println(new lint.DataTypes.Program(e3).peval(lint.DataTypes.env0, lint.DataTypes.fenv0));

}
}[/cc]

Here is the definition of a simple language for arithmetic expressions that uses the parser:

[cc lang=”java” lines=”20″]package lint1_arithmetic;

public class UnstagedLint {

/*
type exp = Int of int
| Var of string
| Add of exp * exp
| Sub of exp * exp
| Mul of exp * exp
| Div of exp * exp
type def = Definition of string * int
type prog = Program of def list * exp
*/

public static interface Exp {
public int eval(Env e);
}

public static class Int implements Exp {
private int _value;
public Int(int value) {
_value = value;
}
public int eval(Env e) {
return _value;
}
}

public static class Var implements Exp {
private String _s;
public Var(String s) {
_s = s;
}
public int eval(Env e) {
return e.get(_s);
}
}

public static abstract class BinOp implements Exp {
protected Exp _left, _right;
public BinOp(Exp left, Exp right) {
_left = left;
_right = right;
}
}

public static class Add extends BinOp {
public Add(Exp left, Exp right) {
super(left, right);
}
public int eval(Env e) {
return _left.eval(e) + _right.eval(e);
}
}

public static class Sub extends BinOp {
public Sub(Exp left, Exp right) {
super(left, right);
}
public int eval(Env e) {
return _left.eval(e) – _right.eval(e);
}
}

public static class Mul extends BinOp {
public Mul(Exp left, Exp right) {
super(left, right);
}
public int eval(Env e) {
return _left.eval(e) * _right.eval(e);
}
}

public static class Div extends BinOp {
public Div(Exp left, Exp right) {
super(left, right);
}
public int eval(Env e) {
return _left.eval(e) / _right.eval(e);
}
}

/*
exception EnvironmentException
let env0 = fun x -> raise EnvironmentException
let fenv0 = env0
let ext env x v = fun y -> if x=y then v else env y
*/

public static class EnvironmentException extends RuntimeException { }

// environment; implemented as a function object from String to Exp
public static interface Env {
public int get(String y);
}
public static final Env env0 = new Env() {
public int get(String s) { throw new EnvironmentException(); }
};

public static Env ext(final Env env, final String x, final int v) {
return new Env() {
public int get(String y) {
if (x.equals(y)) return v; else return env.get(y);
}
};
}

public static class Definition {
private String _name;
private int _v;
public Definition(String name, int v) {
_name = name;
_v = v;
}
public String name() { return _name; }
public int value() { return _v; }
}

public static class Program {
public Definition[] _defs;
public Exp _body;
public Program(Exp body, Definition… defs) {
_defs = defs;
_body = body;
}

public int peval(Env env) {
return peval(env,0);
}

private int peval(final Env env, int defIndex) {
// match p with
if (_defs.length<=defIndex) { // Program ([],e) -> eval e env
return _body.eval(env);
}
else {
// |Program (Definition (n,v)::tl,e) -> peval (Program(tl,e)) (ext env n v)
final Definition d = _defs[defIndex];
return peval(ext(env, d.name(), d.value()),defIndex+1);
}
}
}

/*
let rec eval e env fenv =
match e with
Int i -> i
| Var s -> env s
| Add (e1,e2) -> (eval e1 env fenv)+(eval e2 env fenv)
| Sub (e1,e2) -> (eval e1 env fenv)-(eval e2 env fenv)
| Mul (e1,e2) -> (eval e1 env fenv)*(eval e2 env fenv)
| Div (e1,e2) -> (eval e1 env fenv)/(eval e2 env fenv)

let rec peval p env =
match p with
Program ([],e) -> eval e env
|Program (Definition (s1,i1)::tl,e) -> peval (Program(tl,e)) (ext env s1 i1)

*/

public static Program term10times20plus30 = new Program
(new Add(new Mul(new Var(“x”), new Var(“y”)), new Int(30)),
new Definition(“x”, 10),
new Definition(“y”, 20));

public static Program parsedTerm10times20plus30 = new Program
(parser.LintParser.parse(Exp.class, “(Add (Mul (Var x) (Var y)) (Int 30))”),
new Definition(“x”, 10),
new Definition(“y”, 20));

public static Program termWhatX = new Program
(new Var(“x”));

public static Program parsedTermWhatX = new Program
(parser.LintParser.parse(Exp.class, “(Var x)”));

public static void main(String[] args) {
int i = term10times20plus30.peval(env0);
System.out.println(“term10times20plus30 = “+i);

i = parsedTerm10times20plus30.peval(env0);
System.out.println(“parsedTerm10times20plus30 = “+i);

try {
i = termWhatX.peval(env0);
System.out.println(“termWhatX = “+i);
throw new AssertionError(“This should throw an EnvironmentException”);
}
catch(EnvironmentException ee) { System.out.println(“termWhatX threw “+ee); /* expected */ }

try {
i = parsedTermWhatX.peval(env0);
System.out.println(“parsedTermWhatX = “+i);
throw new AssertionError(“This should throw an EnvironmentException”);
}
catch(EnvironmentException ee) { System.out.println(“parsedTermWhatX threw “+ee); /* expected */ }
}
}[/cc]

Share
Posted in Mint | 1 Comment

Print This Post Print This Post  

Bookmark Google Calendar Searches

I think I have finally figured out how how to bookmark Google Calendar searches. The problem was that the search parameters did not seem to be passed using URL “get” parameters. The Google Calendar URL was always just

https://www.google.com/calendar/render

and the search parameters never made it into a bookmark.

I just experimented a bit by passing q=blabla arguments, and doing that seems to work. I can specify to just search my calendar using src=username%40gmail.com. For example, this URL can be bookmarked to search my calendar for “opera OR symphony OR concert OR theater OR theatre”:

[cc]https://www.google.com/calendar/render?src=username%40gmail.com&q=opera%20OR%20concert%20OR%20symphony%20OR%20theater%20OR%20theatre[/cc]

Replace username%40gmail.com with your GMail address. Use %40 instead of the “at” sign (@) and %20 instead of a space.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

String Pool Interning Saves the Weakly Separable Day

I just took a swim in the string pool. Who would have thought that interning strings would be so useful for weak separability in Mint?

I knew before that we had some problems calling [cci lang=”java”]String.equals[/cci] in a separable method, like the [cci lang=”java”]Env.get(String y)[/cci] method that does an environment look-up, because [cci lang=”java”]String.equals[/cci] wasn’t declared separable itself. That’s why I used the [cci lang=”java”]==[/cci] operator in the initial Lint interpreter I wrote for the PLDI 2010 paper:

[cc lang=”java”]public static separable Env ext(final Env env,
final String x,
final Code v) {
return new Env() {
public separable Code get(String y) {
// error: if (x.equals(y))
if (x==y)
return v;
else
return env.get(y);
}
};
} [/cc]

This wasn’t a problem because we didn’t have a parser and were creating our ASTs using hand-written Java code. The variable names are string constants, which are always interned:

[cc lang=”java”]public static Program term10times20plus30 = new Program
(new Add(new Mul(new Var(“x”), new Var(“y”)), new Int(30)),
new Definition(“x”, <|10|>),
new Definition(“y”, <|20|>));[/cc]

Tonight, I wrote a reflection-based S-expression parser, and now the variable names are substrings of a longer string:

[cc lang=”java”]public static Program parsedTerm10times20plus30 = new Program
(parser.LintParser.parse(Exp.class, “(Add (Mul (Var x) (Var y)) (Int 30))”),
new Definition(“x”, <|10|>),
new Definition(“y”, <|20|>));[/cc]

Substrings aren’t interned automatically, and the comparison using [cci lang=”java”]==[/cci] fails. Fortunately, I can simply intern the strings when I create the [cci lang=”java”]Var[/cci] AST nodes and the [cci lang=”java”]Definition[/cci] variable bindings:

[cc lang=”java”]public static class Var implements Exp {
private String _s;
public Var(String s) {
_s = s.intern(); // must intern here, so we can use == in the ext method below
}
public separable Code eval(Env e) {
return e.get(_s);
}
}
public static class Definition {
private String _name;
private Code _v;
public Definition(String name, Code v) {
_name = name.intern(); // must intern here, so we can use == in the ext method above
_v = v;
}
public separable String name() { return _name; }
public separable Code value() { return _v; }
}[/cc]

This was a whole lot simpler and cleaner than making some kind of exception for [cci lang=”java”]String.equals[/cci].

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

New Mint Release: r15716

As mentioned before, Eddy and I discovered a problem with type variables in code generated by the Mint compiler. We have now fixed this problem in the new release of Mint and DrJava with Mint: August 30, 2010 (r15716). The latest release is, as always, available from the Mint implementation page:

The problem occurred when the programmer used a type variable inside a bracket. An example of this would be a generic method like this:

[cc lang=”java”]public separable Code fun(Code c1, Code c2) {
return <| ( `(lfTest.eval(e,f).booleanCodeValue()) ? `c2 : `c1 ) |>;
}[/cc]

This caused Mint to generate 2nd stage code that contained the type variable [cci lang=”java”]X[/cci] unbound. Unfortunately, the types are erased, and there is no way to find out what type [cci lang=”java”]X[/cci] actually refers to at runtime, e.g. by writing something like [cci lang=”java”]X.class[/cci] (this generates the Java compiler error “cannot select from a type variable”).

To get around this problem, we now require a final instance of type [cci lang=”java”]Class[/cci] to be in scope for every type variable [cci lang=”java”]X[/cci]. For example, in the generic method above, there is a type variable [cci lang=”java”]X[/cci] that is being used in the bracket. Therefore, we now have to have a final instance of [cci lang=”java”]Class[/cci] somewhere in scope, for example as a method parameter.

[cc lang=”java”]public separable Code fun(Code c1, Code c2,
final Class xc) {
return <| ( `(lfTest.eval(e,f).booleanCodeValue()) ? `c2 : `c1 ) |>;
}[/cc]

That’s all that is necessary. The variable [cci lang=”java”]xc[/cci] is not actually used in the code, it just needs to be in scope.

(Re-posted from The Java Mint Blog.)

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

Passing a Class<T> for Every Type Variable T

When working on our GPCE Mint tutorial, Eddy and I realized that there is a problem when programmers use type variables inside brackets. A method like

[cc lang=”java”]public separable Code fun(Code c1, Code c2) {
return <| ( `(lfTest.eval(e,f).booleanCodeValue()) ? `c2 : `c1 ) |>;
}[/cc]

causes Mint to generate code containing the free type variable [cci lang=”java”]X[/cci]. There is no way to get any type information from a type variable at runtime, e.g. by doing [cci lang=”java”]X.class[/cci], so instead we decided to require the user to have a final instance of [cci lang=”java”]Class[/cci] in scope somewhere.

This was a pragmatic solution that seems to work pretty well. The method above can be rewritten as

[cc lang=”java”]public separable Code fun(Code c1, Code c2,
final Class xc) {
return <| ( `(lfTest.eval(e,f).booleanCodeValue()) ? `c2 : `c1 ) |>;
}[/cc]

To implement this, we had to find all variables of type [cci lang=”java”]Class[/cci] that were in scope at the time a bracket was generated. This was surprisingly confusing to do with the javac environment and scope classes. In the end, I decided to adapt the [cci lang=”java”]Resolver.findVar[/cci] and [cci lang=”java”]Resolver.findField[/cci] methods.

[cc lang=”java”] /** This method returns a list of all VarSymbols of type Class in scope where X is a type variable. */
List getClassVarsInScope() {
// System.out.println(“env = “+env);
List ret = List.nil();
Scope current = env.info.scope;
// System.out.println(“Scope: “+current);
while(current != null) { // also go into the outer (enclosing) scopes
// for(Symbol s: current.elems) {
for (Scope.Entry e = current.elems; e != null; e = e.sibling) {
ret = processPotentialClassVarInScope(e.sym, ret);
}
current = current.next;
}
// System.out.println(“Asking for vars in “+env.enclClass.sym);
ret = _getClassVarsInScope(env, ret);
return ret.reverse();
}

List processPotentialClassVarInScope(Symbol s, List ret) {
// System.out.println(“in scope: “+s+” : “+s.getClass().getSimpleName());
if (s instanceof VarSymbol) {
VarSymbol vs = (VarSymbol)s;
if ((vs.type.tsym == syms.classType.tsym) &&
((vs.flags() & FINAL) != 0) &&
(vs.type.getTypeArguments().nonEmpty()) &&
(vs.type.getTypeArguments().head instanceof TypeVar)) {
// vs is of type Class where X is a type variable
ret = ret.prepend(vs);
}
}
return ret;
}

List _getClassVarsInScope(Env env, List ret) {
Env env1 = env;
boolean staticOnly = false;
while (env1.outer != null) {
if (rs.isStatic(env1)) staticOnly = true;
Scope.Entry e = env1.info.scope.elems;
while (e != null) {
Symbol sym = e.sym;
if (!(staticOnly &&
sym.kind == VAR &&
sym.owner.kind == TYP &&
(sym.flags() & STATIC) == 0)) {
ret = processPotentialClassVarInScope(sym, ret);
}
ret = _getClassFieldsInScope(env1, env1.enclClass.sym.type, env1.enclClass.sym, ret);

e = e.sibling;
}
ret = _getClassFieldsInScope(env1, env1.enclClass.sym.type, env1.enclClass.sym, ret);

if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
env1 = env1.outer;
}

ret = _getClassFieldsInScope(env, syms.predefClass.type, syms.predefClass, ret);

return ret;
}

List _getClassFieldsInScope(Env env,
Type site,
TypeSymbol c,
List ret) {
while (c.type.tag == TYPEVAR)
c = c.type.getUpperBound().tsym;
Scope.Entry e = c.members().elems;
while (e != null) {
if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
if (rs.isAccessible(env, site, e.sym)) {
ret = processPotentialClassVarInScope(e.sym, ret);
}
}
e = e.sibling;
}
Type st = types.supertype(c.type);
if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
ret = _getClassFieldsInScope(env, site, st.tsym, ret);
}
for (Type it: types.interfaces(c.type)) {
ret = _getClassFieldsInScope(env, site, it.tsym, ret);
}
return ret;
}[/cc]

A new Mint release can be expected shortly.

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

New Mint Release: r15707

When working on our GPCE tutorial, Eddy and I discovered a small bug in the Mint compiler which I have now fixed in the new release of Mint and DrJava with Mint: August 24, 2010 (r15707). The latest release is, as always, available from the Mint implementation page:

The only change I made was to fix the let expression pretty printer when the expression contained more than one declaration.

The problem never came up before because we only had one declaration per let expression, and it was always possible to rewrite

[cc lang=”java”]let int x = 1, y = 2; x+y[/cc]

as

[cc lang=”java”]let int x = 1; let int y = 2; x+y[/cc]

We are pushing the Mint compiler more, and we have discovered another problem with generic methods. Currently, Mint generates a class extending [cci lang=”java”]Code[/cci] with [cci]X[/cci] occuring unbound when this method is called:

[cc lang=”java”]public separable abstract Code fun(Code c1, Code c2, Object… param);[/cc]

We are looking at making another bugfix soon.

(Re-posted from The Java Mint Blog.)

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

Two Pieces of Fail

I encountered two pieces of fail today already.

Fail number 1: Absolutely no place to park my bike. This has been pretty much the case ever since the undergrads have been back. Rice built two new colleges right next to the building I work in, but didn’t consider what an increased resident population would do to bike rack space: The undergrads, of course, store their bikes semi-permanently on the bike racks that we need to commute.

This is what the bike racks looked like shortly after 9 AM this morning:

Overfull Duncan Hall Bike Rack, 9:15 AM

Overfull Duncan Hall Bike Rack, 9:15 AM

I have been lobbying for more bike racks for over a year now, to no avail. I guess I’m going to be taking my bike up into my building from now on.

Fail number 2: I still don’t have my Texas drivers license, even though it has been 67 days since I renewed it. It’s even been over three weeks since I first contacted the DPS and was told the license would be remade and resent. Today I found out why it’s taking so long:

You will be mailed out a temporary permit today while you receive your license in the mail. Apparently the license was not remade when the visitor status was updated. I sincerely apologize for the inconvenience this has caused you.

In essence, they cut up my old drivers license, updated their internal database, and never mailed me a new license. Good job, Texas DPS. I’m glad I have an international drivers license as a backup.

Share
Posted in Pictures, Ramblings | Leave a comment

Print This Post Print This Post  

New Mint Release: r15700

On Friday, I created a new release of Mint and DrJava with Mint: August 20, 2010 (r15700). The latest release is, as always, available from the Mint implementation page:

The only changes that we made were a small change to the build process on Mac OS, and the addition of the Range and Lift utility classes.

The Lift class allows the user to manually lift primitive values and strings when the compiler did not do that already, for example when working with arrays.

The Range class provides methods that allow many for loops to be written as foreach loops with a final loop variable that can be used across bracket boundaries immediately. Consider this example of a staged sparse matrix multiplication:

public static separable
Code smmult(final double[][] a,
Code b,
Code output,
int l, int m, int n) {
Code stats = <| { } |>;
for(final int i: range(0, l)) {
for(final int j: range(0, m)) {
Code c = <| 0.0 |>;
for(final int k: range(0, n)) {
if(a[i][k] == 0.0)
continue;
else if(a[i][k] == 1.0)
c = <| `c + (`b)[k][j] |>;
else
c = <| `c + (`(lift(a[i][k])) * (`b)[k][j]) |>;
}
stats = <| { `stats; (`output)[i][j] = `c; } |>;
}
}
return stats;
}

is a lot cleaner than

public static separable
Code smmult(final double[][] a,
Code b,
Code output,
int l, int m, int n) {
Code stats = <| { } |>;
for(int i = 0; i < l; i++) { for(int j = 0; j < m; j++) { final int ii = i; final int jj = j; Code c = <| 0.0 |>;
for(int k = 0; k < n; k++) { final int kk = k; if(a[i][k] == 0.0) continue; else if(a[i][k] == 1.0) c = <| `c + (`b)[kk][jj] |>;
else
c = <| `c + (`(lift(a[ii][kk])) * (`b)[kk][jj]) |>;
}
stats = <| { `stats; (`output)[ii][jj] = `c; } |>;
}
}
return stats;
}

The ii, jj, and kk variables aren’t necessary anymore.

(Re-posted from The Java Mint Blog.)

Share
Posted in Mint | Leave a comment

Print This Post Print This Post  

Compiled “Run” Commands in DrJava

I had mentioned a while ago that the way we put together the commands that get interpreted when the user presses the “Run” button or types in java or applet or run in the Interactions Pane is very messy.

I had told myself that I should try to rewrite this as Java code that doesn’t get interpreted in our Interactions Pane, but that actually gets statically compiled. I did that, and the code was a whole lot more maintainable. Compare this code to the previous code:

/** This method performs the "smart run". Unfortunately, we don't get the right static error messages.
* @param s full command line, i.e. "run MyClass 1 2 3"
* @param c class to be run, i.e. MyClass.class
*/
@SuppressWarnings("unchecked")
public static void runCommand(String s, Class c) throws Throwable {
if (s.endsWith(";")) s = _deleteSemiColon(s);
List tokens = ArgumentTokenizer.tokenize(s, true);
final String classNameWithQuotes = tokens.get(1); // this is "MyClass"
final String className =
classNameWithQuotes.substring(1, classNameWithQuotes.length() - 1); // removes quotes, becomes MyClass
String[] args = new String[tokens.size() - 2];
for (int i = 2; i < tokens.size(); i++) { String t = tokens.get(i); args[i - 2] = t.substring(1, t.length() - 1); } boolean isProgram = false; boolean isApplet = false; Class oldC = c; while(c != null) { if ("acm.program.Program".equals(c.getName()) || "acm.graphics.GTurtle".equals(c.getName())) { isProgram = true; break; } c = c.getSuperclass(); } c = oldC; if (!isProgram) { try { // if this doesn't throw, c is a subclass of Applet c.asSubclass(java.applet.Applet.class); isApplet = true; } catch(ClassCastException cce) { } } java.lang.reflect.Method m = null; if (isApplet) { try { m = c.getMethod("main", java.lang.String[].class); if (!m.getReturnType().equals(void.class)) { m = null; } } catch (java.lang.NoSuchMethodException e) { m = null; } if (m==null) { java.applet.Applet instance = null; if (args.length==0) { try { // try default (nullary) constructor first Constructor ctor = c.getConstructor(); instance = java.applet.Applet.class.cast(ctor.newInstance()); } catch(NoSuchMethodException nsme) { instance = null; } catch(InstantiationException ie) { instance = null; } catch(IllegalAccessException iae) { instance = null; } catch(java.lang.reflect.InvocationTargetException ite) { if (ite.getCause()!=null) { throw ite.getCause(); } else { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); } } if (instance==null) { try { // try String[] constructor next Constructor ctor = c.getConstructor(String[].class); instance = java.applet.Applet.class.cast(ctor.newInstance(new Object[] { new String[0] })); } catch(NoSuchMethodException nsme) { instance = null; } catch(InstantiationException ie) { instance = null; } catch(IllegalAccessException iae) { instance = null; } catch(java.lang.reflect.InvocationTargetException ite) { if (ite.getCause()!=null) { throw ite.getCause(); } else { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); return; } } } if (instance==null) { System.err.println("Error: This applet does not have a default constructor or a constructor "+ "accepting String[]."); return; } } else { try { // try String[] constructor Constructor ctor = c.getConstructor(String[].class); instance = java.applet.Applet.class.cast(ctor.newInstance(new Object[] { args })); } catch(NoSuchMethodException nsme) { instance = null; } catch(InstantiationException ie) { instance = null; } catch(IllegalAccessException iae) { instance = null; } catch(java.lang.reflect.InvocationTargetException ite) { if (ite.getCause()!=null) { throw ite.getCause(); } else { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); return; } } if (instance==null) { System.err.println("Error: This applet does not have a constructor accepting String[]."); return; } } edu.rice.cs.plt.swing.SwingUtil.showApplet(instance, 400, 300); } } else { try { m = c.getMethod("main", java.lang.String[].class); if (!m.getReturnType().equals(void.class)) { System.err.println("Error: This class does not have a static void main method accepting String[]."); m = null; } } catch (java.lang.NoSuchMethodException e) { System.err.println("Error: This class does not have a static void main method accepting String[]."); m = null; } } if (m != null) { if (isProgram) { String[] newArgs = new String[args.length+1]; newArgs[0] = "code="+c.getName(); System.arraycopy(args, 0, newArgs, 1, args.length); args = newArgs; } try { m.setAccessible(true); m.invoke(null, new Object[] { args }); } catch(SecurityException se) { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); } catch(IllegalAccessException iae) { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); } catch(java.lang.reflect.InvocationTargetException ite) { if (ite.getCause()!=null) { throw ite.getCause(); } else { System.err.println("Error: Please turn off 'Smart Run' or use 'java' command instead of 'run'."); } } } }

It's actual Java code that is statically compiled, not a string that is concatenated at runtime and that might be erroneous.

Unfortunately, we don't get the right static error messages. I can print something like "Static Error: Undefined class 'Foo'" as output, but it doesn't have the right font and doesn't invoke the right listeners, so the "Auto-Import" dialog doesn't show up, for example.

For now, I'm using the old string concatenation routine again.

Share
Posted in DrJava | Leave a comment

Print This Post Print This Post  

Java Versions on the Mac

Stephen had some questions about Java on the Mac. I tried to answer them.

From the DrJava site, I see notes that a JDK is already installed on OS X machines—that explains why I can’t find downloads for it.

There are some Java downloads from Apple, but they’re hard to find and
meant for developers (Apple ID required).

I have a couple of questions about it though:

Here are some answers from Apple: Mac OS X Java Frequently Asked Questions (FAQ) for developers.

a) Is it a 32-bit or a 64-bit JDK?

As far as I know, Macs have both a 32-bit and a 64-bit JDK installed. If I understand this page correctly, by default, the 32-bit JVM is running.

I don’t have a 64-bit Mac, though, so I don’t have any experience with 64-bit Mac JVMs.

b) Does the Mac run some sort of auto-updating process on it – how do you know what version it is running and how do you get a newer version if needed?

This is what the FAQ says:

Java updates usually stand alone, allowing you to choose when an update is appropriate. However, it is always recommended to check the description and release notes for all software updates to see which technologies are affected. Major upgrades such as Mac OS X Leopard typically update Java as well.

It’s been such a long time since I’ve had a Java update on my 10.4 32-bit MacBook, but I think new versions of Java appear in the “Software Update” list (see Apple menu).

The reason I ask is that for running Eclipse, one needs to know if you’re running a 32-bit or 64-bit version because not only are different plug-ins needed, but the install procedure can be different as well. Also, we need to know what version of Java people are running on their Macs.

On the command line: [cci]java -version[/cci]

The sun.arch.data.model property may also help, it should be [cci lang=”java”]”32″[/cci],
[cci lang=”java”]”64″[/cci] or [cci lang=”java”]”unknown”[/cci]. You can get the value by calling [cci lang=”java”]System.getProperty(“sun.arch.data.model”)[/cci], for example in the DrJava Interactions Pane (see Oracle FAQ entry).

Here is some more Apple-specific information about Java versions.

Hope this helps.

Update

Corky said what I had written about “by default, the 32-bit JVM is running” had confused him. He wondered: “Is a 32 bit version of Java 6 now available on Leopard?”

No, there’s still no 32-bit Java 6 from Apple for Tiger (10.4).

It seems like the -d64 switch is a mode, like -server or -client, and that on the Mac both the 32-bit and the 64-bit JVMs are rolled into one. On Windows, Linux and Solaris, there are 32-bit and 64-bit JVMs that need to be installed separately.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

GPCE’10 Tutorial Lecture: Agile and Efficient Domain-Specific Languages using Multi-stage Programming in Java Mint

Eddy, Walid, and I proposed a tutorial lecture for GPCE’10, and we’re delighted to report that it has been accepted for presentation on Sunday, October 10, 2010.

Agile and Efficient Domain-Specific Languages using Multi-stage Programming in Java Mint

Domain-specific languages (DSLs) are a powerful productivity tool
because they allow domain experts, who are not necessarily programming
experts, to quickly develop programs. DSL implementations have unique
constraints for programming languages because they must be efficient,
in order to ensure high productivity, but they must also be agile, in
order to meet the rapidly changing demands of their domains. In this
tutorial we show how multi-stage programming (MSP) can be used to
build staged interpreters, which combine the agility of interpreters
with the efficiency of compilers. The tutorial is conducted in Java
Mint, an multi-stage Java based on recent work incorporating MSP into
imperative object-oriented languages. In the first half of
the tutorial, we introduce MSP by demonstrating how to write a staged
interpreter for a number of basic language constructs, such as
recursive functions, conditionals, and let expressions. In the second
half, we extend our staged interpreter to take advantage of several
well-known compiler optimizations, including type inference, constant
folding, and static parallel loop scheduling. We highlight the opportunities
afforded by using MSP with object-oriented design to quickly create
efficient DSL implementations.

Brief Outline of Tutorial

This tutorial uses Java Mint to introduce MSP in imperative,
object-oriented languages. We will progress as follows:

  1. Introduction to MSP, the three language constructs “bracket”,
    “escape” and “run”, and their use in Java Mint.
  2. Brief overview of MSP applications other than interpreters.
  3. Development of a staged interpreter for a small DSL. We
    incrementally add:

    1. Arithmetic expressions
    2. Conditionals
    3. Recursive functions
    4. Let expressions
  4. Application of compiler optimizations in the interpreter
    for our DSL. We discuss:

    1. Extending the interpreter with multiple data types
    2. Type inference
    3. Constant folding
    4. Static parallel loop scheduling

Biographies

Mathias Ricken is a doctoral candidate in the Programming Languages
Team at Rice University and one of the principal developers of the
DrJava integrated development environment. His research interests
include concurrent programming, extending the Java language, and
computer science education. He is the developer of the Concutest
concurrent unit testing framework and has created various experimental
extensions of Java to address, for instance, programming with
meta-data. Currently, Mathias is contributing to Java Mint, a
multi-stage extension of Java that allows safe and expressive
statically typed program generation and specialization in an
imperative language setting.

Edwin Westbrook is a post-doctoral researcher at Rice University. His
primary interests are in developing techniques for implementing and
verifying properties of domain-specific languages (DSLs). He has
worked on a number of projects in this area, including: Cinic, a type
theory for building machine-checked proofs of properties of DSLs using
a new approach to higher-order abstract syntax; Java Mint, a
multi-stage version of Java used for efficient implementations of
DSLs; and Acumen, a DSL for designing cyber-physical systems.

Walid Taha is an professor at Halmstad University. His current interest is in modeling and simulation of cyberphysical systems. He was the principal investigator on a number of research awards and contracts from the National Science Foundation (NSF), Semi-conductor Research Consortium (SRC), and Texas Advanced Technology Program (ATP). He received an NSF CAREER award to develop Java Mint. He is the principle designer Java Mint, Acumen, MetaOCaml, and the Verilog Preprocessor. He founded the ACM Conference on Generative Programming and Component Engineering (GPCE), the IFIP Working Group on Program Generation (WG 2.11), and the Middle Earth Programming Languages Seminar (MEPLS). In 2009, he chaired the IFIP Working Conference on Domain Specific Languages (DSLs).

(Re-posted from The Java Mint Blog.)

Share
Posted in Mint | 3 Comments

Print This Post Print This Post