1) Have you heard of functional languages? 2) Any example? 3) Can you give examples of high-order functions in SML: map (fn x => x + 1) [1, 2, 3, 4]; map (fn x => x mod 2 = 0) [1, 2, 3, 4]; map ~ [1,2,3,4]; map (op +) [(1,2),(3,4),(5,6)]; fun asc s = map ord (explode s); foldr (op +) 0 [1,2,3,4] ; foldr (op * ) 1 [1,2,3,4] ; foldr (op ^) "" ["abc","def","ghi"] ; foldr (op ::) [5] [1,2,3,4] ; 4) How could we implement a mapper in Java? public abstract class Mapper { public abstract B apply(A e); public final List map(final List l) { List retList = new LinkedList(); Iterator it = l.iterator(); while (it.hasNext()) { retList.add(apply(it.next())); } return retList; } } 5) Can you implement a mapper that maps x:int -> y:int, where y = x + 1? public class Incrementer extends Mapper { @Override public Integer apply(Integer e) { return e + 1; } } 6) How to test it? public void testIncrementer() throws Exception { List l0 = new LinkedList(); for (int i = 0; i < 16384; i++) { l0.add(i); } Mapper m = new Incrementer(); List l1 = m.map(l0); assertEquals(l0.size(), l1.size()); for (int i = 0; i < l1.size(); i++) { assertEquals((int) l1.get(i), i + 1); } } 7) Map a list of strings to a list of the sizes of these strings: public void testGetSize() throws Exception { List l0 = new LinkedList(); for (int i = 0; i < 16384; i++) { l0.add("AAA"); } Mapper m = new Mapper() { public Integer apply(String e) { return e.length(); }; }; List l1 = m.map(l0); assertEquals(l0.size(), l1.size()); for (int i = 0; i < l1.size(); i++) { assertEquals((int) l1.get(i), 3); } } 8) Map a list os strings to a list with the first character of each string: public void testToFirstChar() throws Exception { List l0 = new LinkedList(); for (int i = 0; i < 16384; i++) { l0.add("A"); } Mapper m = new Mapper() { public Character apply(String e) { if (e.length() > 0) return e.charAt(0); else return new Character('\0'); }; }; List l1 = m.map(l0); assertEquals(l0.size(), l1.size()); for (int i = 0; i < l1.size(); i++) { assertEquals((char) l1.get(i), 'A'); } } 9) What about the reduction pattern? Can you implement it in Java? public abstract class Reducer { public abstract B binOp(A elem, B acc); public final B reduce(final List l, B acc) { Iterator it = l.iterator(); while (it.hasNext()) { acc = binOp(it.next(), acc); } return acc; } } 10) How is a reducer that sums up the numbers in a list of integers? 10.1) What is the generic types of this reducer? 10.2) How to test it? public void testSum() throws Exception { List l0 = new LinkedList(); for (int i = 0; i < 16384; i++) { l0.add(i); } Reducer r = new Reducer() { @Override public Integer binOp(Integer e, Integer acc) { return e + acc; } }; Integer i1 = r.reduce(l0, 0); assertEquals((int)i1, 16383 * (16384 / 2)); } 11) Implement a reducer that builds up a histogram with the number of characters that appear in a list of strings: 11.1) What is the type of this reducer? 11.2) How to test it? public void testCountChar() throws Exception { List l0 = new LinkedList(); for (int i = 0; i < 1024; i++) { l0.add("aba"); } Reducer r = new Reducer() { @Override public char[] binOp(String e, char[] acc) { for (int i = 0; i < e.length(); i++) { acc[e.charAt(i)]++; } return acc; } }; char acc[] = new char[128]; char res[] = r.reduce(l0, acc); assertEquals(res.length, 128); assertEquals(res['a'], 2048); assertEquals(res['b'], 1024); assertEquals(res['A'], 0); } 12) How to use the Template design pattern to increase the reuse in sorting functions? public abstract class Sorter { private int[] numbers; public Sorter(int[] values) { this.numbers = values; } public void sort() { quicksort(0, numbers.length - 1); } private void quicksort(int low, int high) { int i = low, j = high; int pivot = numbers[(low + high) / 2]; while (i <= j) { while (lt(numbers[i], pivot)) { i++; } while (gt(numbers[j], pivot)) { j--; } if (i <= j) { exchange(i, j); i++; j--; } } if (low < j) quicksort(low, j); if (i < high) quicksort(i, high); } private void exchange(int i, int j) { int temp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = temp; } abstract boolean lt(int i, int j); abstract boolean gt(int i, int j); } 13) What would be different sorting operators? public class AscendingSorter extends Sorter { public AscendingSorter(int[] values) { super(values); } @Override boolean lt(int i, int j) { return i < j; } @Override boolean gt(int i, int j) { return i > j; } } -- and -- public class DescendingSorter extends Sorter { public DescendingSorter(int[] values) { super(values); } @Override boolean lt(int i, int j) { return i > j; } @Override boolean gt(int i, int j) { return i < j; } } 14) And, after all, how to code our frequency builder? package edu.lesson23; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public final class FrequencyReader { private static final int NUM_CHAR = 127; private FrequencyReader() { } public static void main(final String[] args) { if (args.length != 1) { System.out.println("Syntax: java FrequencyReader file"); } else { List words = readFile(args[0]); for (String s : words) { System.out.println(s); } int[] res = computeHistogram(words); printResults(res); } } private static void printResults(int[] res) { for (byte b = 0; b < res.length; b++) { System.out.format("%3c: %3d", b, res[b]); if (b % 4 == 0) { System.out.println(); } } } private static int[] computeHistogram(List words) { Reducer r = new Reducer() { @Override public int[] binOp(final String e, final int[] acc) { for (int i = 0; i < e.length(); i++) { acc[e.charAt(i)]++; } return acc; } }; int[] acc = new int[NUM_CHAR]; return r.reduce(words, acc); } private static List readFile(final String fileName) { List words = new ArrayList(); Scanner nameScanner; try { nameScanner = new Scanner(new File(fileName)); while (nameScanner.hasNext()) { String name = nameScanner.next(); words.add(name); } } catch (FileNotFoundException e) { System.out.println("Could not open the file " + fileName); System.exit(1); } return words; } }