Rick

Rick
Rick

Thursday, June 7, 2012

Added some more generics support to functional programming parts

Added improved Generics support so it can be more verbose, but it is better. Also improved organization and class hierarchy. Got rid of some evolutionary dead ends.

Example

package com.examples;

import static com.easyjava.EasyJava.*;
import java.util.*;



public class Example {


    @SuppressWarnings({"unchecked", "unused"})
    public static void main(String [] args) {
        Map<String, Integer> tel;

        //tel = {'jack': 4098, 'sape': 4139}
        tel = mp("jack", 4098, "sape", 4139);

        //tel['guido'] = 4127
        tel.put("guido", 4127);

        //print (tel)
        print(tel);
        //Output {'sape': 4139, 'guido': 4127, 'jack': 4098}

        // print (tel['jack'])
        print(tel.get("jack"));
        //Output 4098

        // del tel['sape']
        tel.remove("sape");


        // tel['irv'] = 4127
        tel.put("irv", 4127);


//      print(tel)
        print(tel);
//      Output {'guido': 4127, 'irv': 4127, 'jack': 4098}

//      print(tel.keys())
        print (tel.keySet());
//      Output ['guido', 'irv', 'jack']


//      'guido' in tel
        print (tel.containsKey("guido"));
//      Output True


//      tel = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
        tel = dict(kv("sape", 4139), kv("guido", 4127), kv("jack", 4098)); //get unchecked exception for Java 6 but not Java 7
//      print (tel)
        print(tel);
//      Output {'sape': 4139, 'jack': 4098, 'guido': 4127}


        //List Comprehension
         Class <?> c = Example.class;


//      print( dict([(x, x**2) for x in (2, 4, 6)]) )     # use a list comprehension
//      Output {2: 4, 4: 16, 6: 36}
        print (map(fn(c, "pow2"), list(2, 4, 6)));

//      >>> for i, v in enumerate(['tic', 'tac', 'toe']):
//          ...     print i, v
//          ...
//          0 tic
//          1 tac
//          2 toe
        enumerate(fn(c, s.printItem), list("tic", "tac", "toe"));

        //You can also declare functions on the fly like so
        class Foo {
            void printItem(int i, String v) {
                print("foo", i , v);
            }           
        }
        enumerate(fn(new Foo(), s.printItem), list("tic", "tac", "toe"));

//      >>> def f(x): return x % 2 != 0 and x % 3 != 0
//              ...
//      >>> filter(f, range(2, 25))
//          [5, 7, 11, 13, 17, 19, 23]      

        class Filter {
            boolean f(int x) {
                return x % 2 != 0 && x % 3 != 0;
            }           
        }
        print (filter(f(new Filter()), range(2, 25)));

        Collection<?> objitems = filter(f(new Filter()), range(2, 25));
        Collection<Integer> myitems = gfilter(f(new Filter()), range(2, 25));

        print (myitems, objitems);

//      >>> def cube(x): return x*x*x
//              ...
//      >>> map(cube, range(1, 11))
//      [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

        print (map(fn(c, s.cube), range(1,11)));
        List<?> list = map(fn(c, s.cube), range(1,11));
        List<String> gmap = gmap(fn(String.class, c, s.stringize), range(1,11));
        print (list, gmap);

//      >>> def add(x,y): return x+y
//              ...
//      >>>      reduce(add, range(1, 11))
//      55

        print ( reduce(fn(c,s.add), range(1,11)) );
        Object object = reduce(fn(c,s.add), range(1,11));
        int greduce = greduce(fn(Integer.class, c,s.add), range(1,11));
        int greduce2 = greduce(fn(c,s.add), range(1,11));
        print(object, greduce, greduce2);
    }

    static int add(int x, int y) {
        return x + y;
    }

    static int cube(int i) {
        return i * i * i;
    }

    static int pow2(int i) {
        return i * i;
    }

    static String stringize(int i) {
        switch (i) {
        case 1:
            return "one";
        case 2:
            return "two";
        case 3:
            return "three";
        default:
            return "" +i;
        }
    }

    static void printItem(int i, String v) {
        print(i , v);
    }

    static enum s {printItem, cube, add, stringize};


}

Implementation

package com.easyjava;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

public class EasyJava {
    private static Logger log = Logger.getLogger(EasyJava.class.getName());

    // HELPER
    // HELPER

    // HELPER
    // HELPER
    private static Class<?> clazz(Object that) {
        if (that instanceof Class) {
            return (Class<?>) that;
        } else {
            return that.getClass();
        }
    }

    public static void print (Object... items) {
        StringBuilder builder = new StringBuilder(256);
        for (Object item : items) {
            builder.append(item);
            builder.append(' ');
        }
        System.out.println(builder);
    }

    @SuppressWarnings("serial")
    public static class AssertionException extends RuntimeException {

        public AssertionException() {
            super();
        }

        public AssertionException(String message, Throwable cause) {
            super(message, cause);
        }

        public AssertionException(String message) {
            super(message);
        }

        public AssertionException(Throwable cause) {
            super(cause);
        }       
    }

    @SuppressWarnings("serial")
    public static class ReflectionException extends RuntimeException {

        public ReflectionException() {
            super();
        }

        public ReflectionException(String message, Throwable cause) {
            super(message, cause);
        }

        public ReflectionException(String message) {
            super(message);
        }

        public ReflectionException(Throwable cause) {
            super(cause);
        }       
    }

    public static void die(boolean condition, String message) {
        if (condition) {
            throw new AssertionException(message);
        }
    }
    public static void die(String message) {
        throw new AssertionException(message);
    }

    public static void die(String message, Object... args) {
        throw new AssertionException(String.format(message, args));
    }



    // CREATIONAL
    // CREATIONAL

    // CREATIONAL
    // CREATIONAL   
    public static interface Entry<K,V> {
        K key();
        V value();
    }

    private static class EntryImpl<K, V> implements Entry<K, V>{
        EntryImpl(K k, V v) {this.k=k; this.v=v;}
        K k;
        V v;
        @Override
        public K key() {
            return k;
        }
        @Override
        public V value() {
            return v;
        }
    }

    public static <K, V> Entry<K, V> kv (final K k, final V v) {
        return new EntryImpl<K,V>(k, v);
    }

    public static <K, V> Entry <K, V> entry (final K k, final V v) {
        return new EntryImpl<K,V>(k,v);
    }

    public static <V> List<V> list(final V... array) {
        return Arrays.asList(array);
    }

    public static <V> Set<V> set(final V... array) {
        return new HashSet<V>(list(array));
    }

    public static List<Integer> range(int stop) {
        return range(0, stop);
    }

    public static List<Integer> range(int start, int stop) {
        ArrayList<Integer> range = new ArrayList<Integer>(stop-start);
        for (int index=start; index<stop; index++) {
            range.add(index);
        }
        return range;
    }

    public static List<Integer> range(int start, int stop, int inc) {
        ArrayList<Integer> range = new ArrayList<Integer>(stop-start);
        for (int index=start; index<stop; index+=inc) {
            range.add(index);
        }
        return range;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        return map;
    }
    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        map.put(k6, v6);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        map.put(k6, v6);
        map.put(k7, v7);
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        map.put(k6, v6);
        map.put(k7, v7);
        map.put(k8, v8);        
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8,
            K k9, V v9) {
        HashMap<K, V> map = new HashMap<K, V>(10);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        map.put(k6, v6);
        map.put(k7, v7);
        map.put(k8, v8);
        map.put(k9, v9);        
        return map;
    }

    public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8,
            K k9, V v9, Entry<K,V>...entries) {
        HashMap<K, V> map = new HashMap<K, V>(10 + entries.length);
        map.put(k0, v0);
        map.put(k1, v1);
        map.put(k2, v2);
        map.put(k3, v3);
        map.put(k4, v4);
        map.put(k5, v5);
        map.put(k6, v6);
        map.put(k7, v7);
        map.put(k8, v8);
        map.put(k9, v9);        
        for (Entry<K,V> entry: entries) {
            map.put(entry.key(), entry.value());
        }
        return map;
    }

    public static <K, V> Map<K, V> dict(Entry<K,V>...entries) {
        HashMap<K, V> map = new HashMap<K, V>(5);
        for (Entry<K,V> entry: entries) {
            map.put(entry.key(), entry.value());
        }
        return map;
    }

    //
    // Functional 
    //


    //
    // Functional 
    //
    public static interface Function <T> {
        T execute(Object... params);
    }

    private static class FunctionImpl<T> implements Function<T> {
        Method method;
        Object that;

        FunctionImpl(Class<T> clazz, Method method, Object that) {
            this.method=method; 
            this.that = that;
        }


        @SuppressWarnings("unchecked")
        public T execute(Object... params) {
            try {
                return (T) method.invoke(that, params);
            } catch (Exception ex) {

            }
            return null;
        }

    }


    public static <T> Function<T> f(Class<T> returnType, Object that, Object... args) {
        try {
            return fn(returnType, that, "f", args);
        } catch (Exception e) {
            throw new ReflectionException(e);
        }
    }

    public static Function<?> f(Object that, Object... args) {
        try {
            return fn(that, "f", args);
        } catch (Exception e) {
            throw new ReflectionException(e);
        }
    }

    public static Function<?> fn(Object that, Object name, Object... args) {
        return fn(Object.class, that, name, args);
    }

    public static <T> Function<T> fn(Class<T> returnType, Object that, Object name, Object... args) {
        try {
            Method[] methods = clazz(that).getDeclaredMethods();
            for (Method m : methods) {
                if (args.length <= m.getParameterTypes().length) {
                    if (m.getName().equals(name.toString())) {
                        m.setAccessible(true);
                        if (Modifier.isStatic(m.getModifiers())) {
                            return new FunctionImpl<T>(returnType, m, null);
                        } else {
                            return new FunctionImpl<T>(returnType, m, that);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            log.log(Level.SEVERE, String.format("Unable to find function that=%s, name=%s, args=%s", that, name, list(args)), ex);
        }
        die("Unable to find function that=%s, name=%s, args=%s", that, name, list(args));
        return null;
    }

    public static void enumerate(Function<?> f, Collection<?> c) {
        int index = 0;
        for (Object o : c) {
            f.execute(index, o);
            index++;
        }
    }

    public static Collection<?> filter(Function<?> f, List<?> l) {
        return gfilter(f,l);
    }

    public static Collection<?> filter(Function<?> f, Collection<?> c) {
        return gfilter(f, c);
    }

    public static <T> Collection<T> gfilter(Function<?> f, List<T> l) {
        ListIterator<?> listIterator = l.listIterator();
        while (listIterator.hasNext()) {
            Boolean b = (Boolean) f.execute(listIterator.next());
            if (!b) {
                listIterator.remove();
            }
        }
        return l;
    }

    public static <T> Collection<T> gfilter(Function<?> f, Collection<T> c) {
        ArrayList<Object> removeList = new ArrayList<Object>(c.size());
        for (Object o : c) {
            Boolean b = (Boolean) f.execute(0);
            if (!b) {
                removeList.add(o);
            }           
        }
        for (Object o: removeList) {
            c.remove(o);
        }
        return c;
    }


    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static List<?> map(Function f, Collection<?> c) {
        return gmap(f, c);
    }

    public static <IN, OUT> List<OUT> gmap(Function<OUT> f, Collection<IN> c) {
        ArrayList<OUT> mapList = new ArrayList<OUT>(c.size());
        for (Object o : c) {
            mapList.add(f.execute(o));
        }
        return mapList;
    }

    @SuppressWarnings("rawtypes")
    public static Object reduce(Function f, Collection<?> c) {
        return greduce(f, c);
    }

    @SuppressWarnings("unchecked")
    public static <T> T greduce(Function<?> f, Collection<T> c) {
        T accumulo = null;
        int index=0;
        for (T o : c) {
            if (index==0) {
                accumulo = o;
            } else {
                accumulo = (T) f.execute(accumulo, o);
            }
            index++;
        }
        return accumulo;
    }


}

No comments:

Post a Comment

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training