Functional programming with EasyJava
EasyJava is this idea I had, whereby, you make Java as easy as you can. It does not have Map literals or List literals, but with varargs, static imports, and some imagination You can get pretty close in size and expressivness. In the last blog bost I showed some examples of this. I've started with Python and just seeing what I can implement that is close in Java. My goal is less is more.
For this to make a lot of sense you need to see the previous post on this.
There is some Java boilerplate code, but we only have to do this once.
Get the class that will hold the "functions" for this
Class <?> c = Example.class;
Python list comprehension
print( dict([(x, x**2) for x in (2, 4, 6)]) )
Easy Java equivalent
print ( dict(fn(c, "pow2"), list(2, 4, 6) ));
First thing to notice is that the Java version is about the same size as Python version, except that it is not because we have to define the function as follows.
pow2 "function"
static int pow2(int i) { return i * i; }
The pow2
funciton is static because we are using this example
code from main. If we were using pow2
from an instance method,
then it could be defined as.
pow2 "function"
int pow2(int i) { return i * i; }
The you would use it as follows from within a instacne method.
Using fn with instance methods.
print ( dict(fn(this, "pow2"), list(2, 4, 6) ));
The fn
function is defined in EasyJava
(Read first blog post).
dict( fn(this, "pow2"), list(2, 4, 6) );
The first argument to dict is the function to apply to each member
of the list. The sencond argume is the list. The funciton list
,
turns its arguments into a ArrayList<T>
where T is the type of
argument you past to list
.
Output of Python list comprehension versus EasyJava equiv
{2: 4, 4: 16, 6: 36} {2=4, 4=16, 6=36}
I've added a method called enumerate, which was inspired by
Python's enumerate
, but took a sharp 90 degree turn away.
Output of Python enumerate
>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print (i, v) ... 0 tic 1 tac 2 toe
EasyJava enumerate takes a function
enumerate(fn(c, s.printItem), list("tic", "tac", "toe"));
The enumerate
takes a funciton which is created with a fn
. The
fn
takes the a class (c
), and a name (s.printItem
). The name
can be any object as fn
just calls toString
on it. This means
you can use Java Enums as follows.
static enum s {printItem, cube, add};
This way if you use a function over and over, you don't have to worry about misspelling it, and you get code completiion.
The printItems
is defined as follows:
static void printItem(int i, String v) { print(i , v); }
Of course one could imagine it be defined like this:
void printItem(int i, String v) { print(i , v); }
The output of the Java version is as follows:
Output of enumerate example EasyJava
0 tic 1 tac 2 toe
The Java version is more verbose mostly due to the fact that there are no closures in Java yet. (There will be in Java 8.)
Python and EasyJava filter
Python filter
def f(x): return x % 2 != 0 and x % 3 != 0 print(filter(f, range(2, 25)))
Easy Java Filter
class Filter { boolean f(int x) { return x % 2 != 0 && x % 3 != 0; }} print (filter(f(new Filter()), range(2, 25)));
The output is near identical.
Notice the introduction of the f
fucntion which is like
fn
, except is always looks for a method named f.
I also added a range
function to EasyJava that is
similar to Pythons.
Python map versus EasyJava map
Python map
def cube(x): return x*x*x print( map(cube, range(1, 11)) )
Python map output
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
EasyJava map
static int cube(int x) { return x*x*x;} ... print (map(fn(c, s.cube), range(1,11)));
Java map output
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
Python reduce versus EasyMap reduce
Python reduce
def add(x,y): return x+y print ( reduce(add, range(1, 11)) )
Python reduce output
55
EasyJava reduce
static int add(int x, int y) {return x + y;} ... print ( reduce(fn(c,s.add), range(1,11)) );
EasyJava reduce output
55
Interesting post thanks.
ReplyDeletePython Online Training
Data Science Online Training