Overview
This topic discusses how Common Lisp function are represented and invoked in
CLforJava.
some comments from jerry
- I like the API specification. A good example including the javadoc tags
- I don't understand the function of verifyNumArgs.
- In the MultipleValues? interface, I like the function that tells you how many values it returns. Unfortunately you may not know. See discussion.
Discussion
The checkArgs() function is to be used when the apply function is called. I plan on implementing an abstract class for us to use for coding the base functions by hand. It will implement checkArgs() by having two static variables; one for minArgs and one for maxArgs. This way, when you write a function you will be able to simply inherit from that class and call checkargs() without coding it over and over.
Spec and API
Apply is a method that takes the arguments in a Lisp list form, pulls them apart, and performs the function on them. The second apply takes care of returning multiple values. The funcall methods take the arguments already separated and performs the function on them. The checkArgs() function throws an exception when the length of the argument array is incorrect.
The Function Representation implementation consists of these 11 interfaces:
public interface Function {
/**
* @param the array of function arguments
* @return the function result object
*/
public Object apply(Object[] args);
/**
* @param the array of arguments
* @return void: throws exception if incorrect number of arguments is passed
* always call this function first in the apply function!
*/
void checkArgs(Object[] args) throws WrongNumberOfArgsException;
public interface Function0 extends Function{
public Object funcall();
}
public interface Function1 extends Function {
public Object funcall(Object arg1);
}
public interface Function2 extends Function {
public Object funcall(Object arg1, Object arg2);
}
public interface Function3 extends Function {
public Object funcall(Object arg1, Object arg2, Object arg3);
}
public interface Function4 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4);
}
public interface Function5 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5);
}
public interface Function6 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5,Object arg6);
}
public interface Function7 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5,Object arg6,Object arg7);
}
public interface Function8 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5,Object arg6,Object arg7,Object arg8);
}
public interface Function9 extends Function {
public Object funcall(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5,Object arg6,Object arg7,Object arg8,Object arg9);
}
All functions implement at least one of these. Every time a new function is defined (even for lambda's), a new class for the function is created by the compiler.
Closures for functions are kept up with as private variables within the function class. Changes to closures are implemented via get and set methods.
Two examples of handcoded Functions are availible under the sketches directory in perforce.
Notes
This API was designed with the compiler in mind. Everything here can be generated automatically.
I've decided not to go with an abstract class for function, since it would limit inheritance. I've left it up to the compiler/function writer to implement the verifyNumArgs method.
References
Implementation
Details of implementation
Discussions
Links to Blog issues
Test Suites
Links to JUnit results
--
JerryBoetje - 11 Jul 2003