go.talks: add "Go for Javaneros"

LGTM=adg
R=adg, jacek.masiulaniec, campoy, dan.kortschak, nightlyone, jscrockett01
CC=golang-codereviews
https://golang.org/cl/111050043
diff --git a/2014/go4java.slide b/2014/go4java.slide
new file mode 100644
index 0000000..3025c62
--- /dev/null
+++ b/2014/go4java.slide
@@ -0,0 +1,667 @@
+Go for Javaneros (Javaïstes?)
+ #go4java
+
+Francesc Campoy
+Gopher and Developer Advocate
+Google
+@francesc
+campoy@golang.org
+
+* What is Go?
+
+Go is an open-source programming language
+
+- created at Google,
+- to solve Google-scale problems.
+
+.image go4java/img/gopher.jpg 450 _
+
+* Who uses Go?
+
+Google:
+
+- YouTube
+- dl.google.com
+
+Others:
+
+- dotCloud (Docker)
+- SoundCloud
+- Canonical
+- CloudFlare
+- Mozilla
+- ...
+
+[[http://golang.org/wiki/GoUsers][golang.org/wiki/GoUsers]]
+
+* Who uses Go?
+
+.image go4java/img/trends.png _ 800
+
+.caption Google Trends for [[http://www.google.com/trends/explore#q=golang][golang]]
+
+* Why Go?
+
+* Simplicity
+
+Minimal design
+
+.image go4java/img/perfection.jpg
+
+* Consistency
+
+Orthogonal features
+
+.image go4java/img/lego.jpg 400 _
+
+.caption By Kenny Louie from Vancouver, Canada [[http://creativecommons.org/licenses/by/2.0][CC-BY-2.0]], via Wikimedia Commons
+
+* Readability
+
+“The ratio of time spent reading (code) versus writing is well over 10 to 1 ... (therefore) making it easy to read makes it easier to write.”
+― Robert C. Martin
+
+.image go4java/img/piet.png 500 600 
+
+* Safety
+
+Type safety, no buffer overflows, no pointer arithmetic.
+
+.image go4java/img/baby.jpg 500 500
+
+* Built-in concurrency features
+
+“In a concurrent world, imperative is the wrong default!” - Tim Sweeney
+
+Communicating Sequential Processes - Hoare (1978)
+
+.image go4java/img/conc.jpg _ 1000
+
+* Speed
+
+.image go4java/img/fast.jpg 500 _
+
+* Let's dive in
+
+* Go and Java common aspects
+
+Go and Java are
+
+- object oriented
+
+- garbage collected
+
+- statically typed
+
+- part of the C family
+
+* Object oriented flavors
+
+Go is Object Oriented, but doesn't have the keywords:
+
+- `class`,
+- `extends`, or
+- `implements`.
+
+* All types are created equal
+
+* Go types
+
+- primitive types
+
+	int, uint, int8, uint8, ...
+	bool, string
+	float32, float64
+	complex64, complex128
+
+- structs
+
+	struct {
+		Name string
+		Age  int
+	}
+
+- slices and arrays
+	
+	[]int, [3]string, []struct{ Name string }
+
+- maps
+
+	map[string]int
+
+* Kinds of types (continued)
+
+- pointers
+
+	*int, *Person
+
+- functions
+
+	func(int, int) int
+
+- channels
+
+	chan bool
+
+- interfaces
+
+	interface {
+		Start()
+		Stop()
+	}
+
+* Type declarations
+
+	type [name] [specification]
+
+`Person` is a `struct` type.
+
+	type Person struct {
+		name string
+		age  int
+	}
+
+`Celsius` is a `float64` type.
+
+	type Celsius float64
+
+* Function declarations
+
+	func [name] ([params]) [return value]
+	func [name] ([params]) ([return values])
+
+A sum function:
+
+	func sum(a int, b int) int {
+		return a + b
+	}
+
+A function with multiple returned values:
+
+	func div(a, b int) (int, int)
+		return a / b, a % b
+	}
+
+Made clearer by naming the return values:
+
+	func div(den, div int) (q, rem int)
+		return a / b, a % b
+	}
+
+* Method declarations
+
+	func ([receiver]) [name] ([params]) ([return values])
+
+A method on a struct:
+
+	func (p Person) Major() bool {
+		return p.age >= 18
+	}
+
+But also a method on a `float64`:
+
+	func (c Celsius) Freezing() bool {
+		return c <= 0
+	}
+
+_Constraint:_ Methods can be defined *only* on types declared in the same package.
+
+	// This won't compile
+	func (s string) Length() int { return len(s) }
+
+* Wait, pointers?
+
+Use `&` to obtain the address of a variable.
+
+	a := "hello"
+	p := &a
+
+Use `*` to dereference the pointer.
+
+	fmt.Print(*p + ", world")
+
+No pointer arithmetic, no pointers to unsafe memory.
+
+	a := "hello"
+	p := &a
+
+	p += 4  // no, you can't
+
+* Why pointers?
+
+Control what you pass to functions.
+
+- passing values, no side-effects:
+
+	func double(x int) {
+		x *= 2
+	}
+
+- passing pointers: side-effects possible:
+
+	func double(x *int) {
+		*x *= 2
+	}
+
+Control your memory layout.
+
+- compare []Person and []*Person
+
+* Method declarations on pointers
+
+Receivers behave like any other argument.
+
+Pointers allow modifying the pointed receiver:
+
+	func (p *Person) IncAge() {
+		p.age++
+	}
+
+The method receiver is a copy of a pointer (pointing to the same address).
+
+Method calls on nil receivers are perfectly valid (and useulf!).
+
+	func (p *Person) Name() string {
+		if p == nil {
+			return "anonymous"
+		}
+		return p.name
+	}
+
+* Interfaces
+
+* Interfaces
+
+An interface is a set of methods.
+
+In Java:
+
+	interface Switch {
+		void open();
+		void close();
+	}
+
+In Go:
+
+	type OpenCloser interface {
+		Open()
+		Close()
+	}
+
+* It's all about satisfaction
+
+Java interfaces are satisfied *explicitly*.
+
+Go interfaces are satisfied *implicitly*.
+
+.image //upload.wikimedia.org/wikipedia/commons/thumb/2/29/Rolling_Stones_09.jpg/512px-Rolling_Stones_09.jpg _ 512
+
+.caption Picture by Gorupdebesanez [[http://creativecommons.org/licenses/by-sa/3.0][CC-BY-SA-3.0]], via [[http://commons.wikimedia.org/wiki/File%3ARolling_Stones_09.jpg][Wikimedia Commons]]
+
+* Go: implicit satisfaction
+
+_If_a_type_defines_all_the_methods_of_an_interface,_the_type_satisfies_that_interface._
+
+Benefits:
+
+- fewer dependencies
+- no type hierarchy
+- organic composition
+
+* Structural subtyping
+
+Think static duck typing, verified at compile time.
+
+.image go4java/img/duck.jpg 500 500
+
+* FuncDraw: an example on interfaces
+
+.image go4java/img/funcdraw.png 500 700
+
+* FuncDraw: package parser
+
+Package `parse` provides a parser of strings into functions.
+
+	func Parse(text string) (*Func, error) { ... }
+
+`Func` is a struct type, with an `Eval` method.
+
+	type Func struct { ... }
+
+	func (p *Func) Eval(x float64) float64 { ... }
+
+* FuncDraw: package draw
+
+Package draw generates images given a function.
+
+	func Draw(f *parser.Func) image.Image {
+		for x := start; x < end; x += inc {
+			y := f.Eval(x)
+			...
+		}
+	}
+
+`draw` depends on `parser`
+
+- makes testing hard
+
+Let's use an interface instead
+
+	type Evaluable interface {
+		Eval(float64) float64
+	}
+
+	func Draw(f Evaluable) image.Image { ... }
+
+* Inheritance vs composition
+
+* Inheritance vs composition
+
+Lots of articles have been written about the topic.
+
+In general, composition is preferred to inheritance.
+
+Lets see why.
+
+* Runner
+
+.code go4java/BadInheritance.java /START_RUNNER/,/END_RUNNER/
+
+* RunCounter is-a Runner that counts
+
+.code go4java/BadInheritance.java /START_COUNTING/,/END_COUNTING/
+
+* Let's run and count
+
+What will this code print?
+
+.code go4java/BadInheritance.java /START_MAIN/,/END_MAIN/
+
+Of course, this prints:
+
+	running one
+	running two
+	running three
+	my runner ran 6 tasks
+
+Wait! How many?
+
+* My runner ran 6 tasks? Six?
+
+Inheritance causes:
+
+- weak encapsulation,
+- tight coupling,
+- surprising bugs.
+
+.image go4java/img/badinheritance.png
+
+* Solution: use composition
+
+.code go4java/Composition.java /START_COUNTING/,/BREAK_COUNTING/
+
+* Solution: use composition (continued)
+
+.code go4java/Composition.java /BREAK_COUNTING/,/END_COUNTING/
+
+* Solution: use composition (continued)
+
+*Pros*
+
+- The bug is gone!
+- `Runner` is completely independent of `RunCounter`.
+- The creation of the `Runner` can be delayed until (and if) needed.
+
+*Cons*
+
+- We need to explicitly define the `Runner` methods on `RunCounter`:
+
+	public String getName() { return runner.getName(); }
+
+- This can cause lots of repetition, and eventually bugs.
+
+* There's no inheritance in Go
+
+* There's no inheritance in Go
+
+Let's use composition directly:
+
+# .code go4java/runner/runner.go /type Task/,/END_TASK/
+
+.code go4java/runner/runner.go /type Runner/,/END_RUNNER/
+
+All very similar to the Java version.
+
+* RunCounter
+
+`RunCounter` has a `Runner` field.
+
+.code go4java/runner/runner.go /type RunCounter/,
+
+* Composition in Go
+
+Same pros and cons as the composition version in Java.
+
+We also have the boilerplate to proxy methods from `Runner`.
+
+.code go4java/runner/runner.go /runner.Name/
+
+But we can remove it!
+
+* Struct embedding
+
+Expressed in Go as unnamed fields in a struct.
+
+It is still *composition*.
+
+The fields and methods of the embedded type are defined on the embedding type.
+
+Similar to inheritance, but the embedded type doesn't know it's embedded.
+
+* Example of struct embedding
+
+Given a type `Person`:
+
+.code go4java/embedsample.go /Person/,/Hi/
+
+We can define a type `Employee` embedding `Person`:
+
+.code go4java/embedsample.go /Employee/,/}/
+
+All fields and methods from `Person` are available on `Employee`:
+
+.code go4java/embedsample.go /var/,/Introduce/
+
+* Struct embedding
+
+.code go4java/runner/embed.go /type RunCounter2/,
+
+* Is struct embedding like inheritance?
+
+No, it is better!
+
+It is composition.
+
+- You can't reach into another type and change the way it works.
+
+- Method dispatching is explicit.
+
+It is more general.
+
+- Struct embedding of interfaces.
+
+* Is struct embedding like inheritance?
+
+Struct embedding is selective.
+
+.code go4java/writecounter.go /WriteCounter/,/MAIN/
+
+WriteCounter can be used with any `io.ReadWriter`.
+
+.play go4java/writecounter.go /func main/,/^}/
+
+* Easy mocking
+
+What if we wanted to fake a part of a `net.Conn`?
+
+	type Conn interface {
+	        Read(b []byte) (n int, err error)
+	        Write(b []byte) (n int, err error)
+	        Close() error
+	        LocalAddr() Addr
+	        RemoteAddr() Addr
+	        SetDeadline(t time.Time) error
+	        SetReadDeadline(t time.Time) error
+	        SetWriteDeadline(t time.Time) error
+	}
+
+I want to test `handleCon`:
+
+.code go4java/loopback.go /handleCon/
+
+- We could create a `fakeConn` and define all the methods of `Conn` on it.
+
+- But that's a lot of boring code.
+
+* Struct embedding of interfaces
+
+_WARNING_:_Cool_stuff_
+
+If a type T has an embedded field of a type E, all the methods of E will be defined on T.
+
+Therefore, if E is an interface T satisfies E.
+
+* Struct embedding of interfaces (continued)
+
+We can test `handleCon` with the `loopBack` type.
+
+.code go4java/loopback.go /loopBack/,/^}/
+
+Any calls to the methods of `net.Conn` will fail, since the field is nil.
+
+We redefine the operations we support:
+
+.code go4java/loopback.go /Read/,
+
+* Concurrency
+
+* Concurrency
+
+It is part of the language, not a library.
+
+Based on two concepts:
+
+- goroutines: lightweight threads
+- channels: typed pipes used to communicate and synchronize between goroutines
+
+So cheap you can use them whenever you want.
+
+.image go4java/img/funnelin.jpg 300 700
+
+* Sleep and talk
+
+.code go4java/conc1.go /sleepAndTalk/,/^}/
+
+We want a message per second.
+
+.play go4java/conc1.go /func main/,/^}/
+
+What if we started all the `sleepAndTalk` concurrently?
+
+Just add `go`!
+
+* Concurrent sleep and talk
+
+.play go4java/conc2.go /func main/,/^}/
+
+That was fast ...
+
+When the `main` goroutine ends, the program ends.
+
+* Concurrent sleep and talk with more sleeping
+
+.play go4java/conc3.go /func main/,/^}/
+
+But synchronizing with `Sleep` is a bad idea.
+
+* Communicating through channels
+
+`sleepAndTalk` sends the string into the channel instead of printing it.
+
+.code go4java/chan.go /sleepAndTalk/,/^}/
+
+We create the channel and pass it to `sleepAndTalk`, then wait for the values to be sent.
+
+.play go4java/chan.go /func main/,/^}/
+
+* Let's count on the web
+
+We receive the next id from a channel.
+
+.code go4java/goodcounter.go /nextID/,/^}/
+
+We need a goroutine sending ids into the channel.
+
+.play go4java/goodcounter.go /func main/,/^}/
+
+[[http://localhost:8080/next]]
+
+* Let's fight!
+
+`select` allows us to chose among multiple channel operations.
+
+.play go4java/battle.go /battle/,/^}/
+
+Go - [[http://localhost:8080/fight?usr=go]]
+Java - [[http://localhost:8080/fight?usr=java]]
+
+* Chain of gophers
+
+.image go4java/img/chain.jpg
+
+Ok, I'm just bragging here
+
+* Chain of gophers
+
+.play go4java/goroutines.go /func f/,
+
+* Concurrency is very powerful
+
+And there's lots to learn!
+
+- [[http://talks.golang.org/2012/concurrency.slide#1][Go Concurrency Patterns]], by Rob Pike
+- [[http://talks.golang.org/2013/advconc.slide#1][Advanced Concurrency Patterns]], by Sameer Ajmani
+- [[http://talks.golang.org/2012/waza.slide#1][Concurrency is not Parellelism]], by Rob Pike
+
+.image go4java/img/busy.jpg
+
+* In conclusion
+
+Go is simple, consistent, readable, and fun.
+
+All types are equal
+
+- methods on any type
+
+Implicit interfaces
+
+- Structural typing
+- Less dependencies
+- Code testable and reusable
+
+Use composition instead of inheritance
+
+- Struct embedding to remove boilerplate.
+- Struct embedding of interfaces to satisfy them fast.
+
+Concurrency is awesome, and you should check it out.
+
+* What to do next?
+
+Learn Go on your browser with [[http://tour.golang.org][tour.golang.org]]
+
+Find more about Go on [[http://golang.org][golang.org]]
+
+Join the community at [[https://groups.google.com/forum/#!forum/Golang-nuts][golang-nuts]]
+
+Link to the slides [[http://talks.golang.org/2014/go4java.slide]]
diff --git a/2014/go4java/BadInheritance.java b/2014/go4java/BadInheritance.java
new file mode 100644
index 0000000..8388418
--- /dev/null
+++ b/2014/go4java/BadInheritance.java
@@ -0,0 +1,82 @@
+import java.util.Collection;
+import java.util.ArrayList;
+
+class BadInheritance {
+    // START_TASK OMIT
+    class Task {
+        private String message;
+
+        public Task(String message) {
+            this.message = message;
+        }
+
+        public void run() {
+            System.out.println("running " + this.message);
+        }
+    }
+    // END_TASK OMIT
+
+    // START_RUNNER OMIT
+    class Runner {
+        private String name;
+
+        public Runner(String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return this.name;
+        }
+
+        public void run(Task task) { // HL
+            task.run();
+        }
+
+        public void runAll(Task[] tasks) { // HL
+            for (Task task : tasks) {
+                run(task);
+            }
+        }
+    }
+    // END_RUNNER OMIT
+
+    // START_COUNTING OMIT
+    class RunCounter extends Runner {
+        private int count;
+
+        public RunCounter(String message) {
+            super(message);
+            this.count = 0;
+        }
+
+        @Override public void run(Task task) {
+            count++; // HL
+            super.run(task);
+        }
+
+        @Override public void runAll(Task[] tasks) {
+            count += tasks.length; // HL
+            super.runAll(tasks);
+        }
+
+        public int getCount() {
+            return count;
+        }
+    }
+    // END_COUNTING OMIT
+
+    public void test() {
+        // START_MAIN OMIT
+        RunCounter runner = new RunCounter("my runner");
+
+        Task[] tasks = { new Task("one"), new Task("two"), new Task("three")};
+        runner.runAll(tasks);
+
+        System.out.printf("%s ran %d tasks\n", runner.getName(), runner.getCount());
+        // END_MAIN OMIT
+    }
+
+    public static void main(String[] args) {
+        new BadInheritance().test();
+    }
+}
\ No newline at end of file
diff --git a/2014/go4java/Composition.java b/2014/go4java/Composition.java
new file mode 100644
index 0000000..345450a
--- /dev/null
+++ b/2014/go4java/Composition.java
@@ -0,0 +1,86 @@
+import java.util.Collection;
+import java.util.ArrayList;
+
+class Composition {
+    class Task {
+        private String message;
+
+        public Task(String message) {
+            this.message = message;
+        }
+
+        public void run() {
+            System.out.println("running " + this.message);
+        }
+    }
+
+    class Runner {
+        private String name;
+
+        public Runner(String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return this.name;
+        }
+
+        public void run(Task task) {
+            task.run();
+        }
+
+        public void runAll(Task[] tasks) {
+            for (Task task : tasks) {
+                run(task);
+            }
+        }
+    }
+
+    // START_COUNTING OMIT
+    class RunCounter {
+        private Runner runner; // HL
+        private int count;
+
+        public RunCounter(String message) {
+            this.runner = new Runner(message);
+            this.count = 0;
+        }
+
+        public void run(Task task) {
+            count++;
+            runner.run(task);
+        }
+
+        public void runAll(Task[] tasks) {
+            count += tasks.length;
+            runner.runAll(tasks);
+        }
+
+        // continued on next slide ...
+
+        // BREAK_COUNTING OMIT
+        public int getCount() {
+            return count;
+        }
+
+        public String getName() {
+            return runner.getName();
+        }
+    }
+    // END_COUNTING OMIT
+
+    public void test() {
+        // START_MAIN OMIT
+        RunCounter runner = new RunCounter("my runner");
+
+        Task[] tasks = { new Task("one"), new Task("two"), new Task("three")};
+        runner.runAll(tasks);
+
+        System.out.printf("%s ran %d tasks\n", runner.getName(), runner.getCount());
+        // END_MAIN OMIT
+    }
+
+    public static void main(String[] args) {
+        new Composition().test();
+    }
+}
diff --git a/2014/go4java/battle.go b/2014/go4java/battle.go
new file mode 100644
index 0000000..0036f16
--- /dev/null
+++ b/2014/go4java/battle.go
@@ -0,0 +1,22 @@
+package main
+
+import (
+	"fmt"
+	"net/http"
+)
+
+var battle = make(chan string)
+
+func handler(w http.ResponseWriter, q *http.Request) {
+	select {
+	case battle <- q.FormValue("usr"):
+		fmt.Fprintf(w, "You won!")
+	case won := <-battle:
+		fmt.Fprintf(w, "You lost, %v is better than you", won)
+	}
+}
+
+func main() {
+	http.HandleFunc("/fight", handler)
+	http.ListenAndServe("localhost:8080", nil)
+}
diff --git a/2014/go4java/chan.go b/2014/go4java/chan.go
new file mode 100644
index 0000000..791a8ad
--- /dev/null
+++ b/2014/go4java/chan.go
@@ -0,0 +1,24 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func sleepAndTalk(secs time.Duration, msg string, c chan string) {
+	time.Sleep(secs * time.Second)
+	c <- msg
+}
+
+func main() {
+	c := make(chan string)
+
+	go sleepAndTalk(0, "Hello", c)
+	go sleepAndTalk(1, "Gophers!", c)
+	go sleepAndTalk(2, "What's", c)
+	go sleepAndTalk(3, "up?", c)
+
+	for i := 0; i < 4; i++ {
+		fmt.Printf("%v ", <-c)
+	}
+}
diff --git a/2014/go4java/conc1.go b/2014/go4java/conc1.go
new file mode 100644
index 0000000..947ef7e
--- /dev/null
+++ b/2014/go4java/conc1.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func sleepAndTalk(t time.Duration, msg string) {
+	time.Sleep(t)
+	fmt.Printf("%v ", msg)
+}
+
+func main() {
+	sleepAndTalk(0*time.Second, "Hello")
+	sleepAndTalk(1*time.Second, "Gophers!")
+	sleepAndTalk(2*time.Second, "What's")
+	sleepAndTalk(3*time.Second, "up?")
+}
diff --git a/2014/go4java/conc2.go b/2014/go4java/conc2.go
new file mode 100644
index 0000000..407bcfc
--- /dev/null
+++ b/2014/go4java/conc2.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func sleepAndTalk(t time.Duration, msg string) {
+	time.Sleep(t)
+	fmt.Printf("%v ", msg)
+}
+
+func main() {
+	go sleepAndTalk(0*time.Second, "Hello")
+	go sleepAndTalk(1*time.Second, "Gophers!")
+	go sleepAndTalk(2*time.Second, "What's")
+	go sleepAndTalk(3*time.Second, "up?")
+}
diff --git a/2014/go4java/conc3.go b/2014/go4java/conc3.go
new file mode 100644
index 0000000..bd2c423
--- /dev/null
+++ b/2014/go4java/conc3.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func sleepAndTalk(t time.Duration, msg string) {
+	time.Sleep(t)
+	fmt.Printf("%v ", msg)
+}
+
+func main() {
+	go sleepAndTalk(0*time.Second, "Hello")
+	go sleepAndTalk(1*time.Second, "Gophers!")
+	go sleepAndTalk(2*time.Second, "What's")
+	go sleepAndTalk(3*time.Second, "up?")
+	time.Sleep(4 * time.Second)
+}
diff --git a/2014/go4java/embedsample.go b/2014/go4java/embedsample.go
new file mode 100644
index 0000000..d475b18
--- /dev/null
+++ b/2014/go4java/embedsample.go
@@ -0,0 +1,20 @@
+package main
+
+import "fmt"
+
+type Person struct{ Name string }
+
+func (p Person) Introduce() { fmt.Println("Hi, I'm", p.Name) }
+
+type Employee struct {
+	Person
+	EmployeeID int
+}
+
+func ExampleEmployee() {
+	var e Employee
+	e.Name = "Peter"
+	e.EmployeeID = 1234
+
+	e.Introduce()
+}
diff --git a/2014/go4java/goodcounter.go b/2014/go4java/goodcounter.go
new file mode 100644
index 0000000..8cfca48
--- /dev/null
+++ b/2014/go4java/goodcounter.go
@@ -0,0 +1,22 @@
+package main
+
+import (
+	"fmt"
+	"net/http"
+)
+
+var nextID = make(chan int)
+
+func handler(w http.ResponseWriter, q *http.Request) {
+	fmt.Fprintf(w, "<h1>You got %v<h1>", <-nextID)
+}
+
+func main() {
+	http.HandleFunc("/next", handler)
+	go func() {
+		for i := 0; ; i++ {
+			nextID <- i
+		}
+	}()
+	http.ListenAndServe("localhost:8080", nil)
+}
diff --git a/2014/go4java/goroutines.go b/2014/go4java/goroutines.go
new file mode 100644
index 0000000..57bc8fd
--- /dev/null
+++ b/2014/go4java/goroutines.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+	"fmt"
+	"time"
+)
+
+func f(left, right chan int) {
+	left <- 1 + <-right
+}
+
+func main() {
+	start := time.Now()
+	const n = 1000
+	leftmost := make(chan int)
+
+	right := leftmost
+	left := leftmost
+	for i := 0; i < n; i++ {
+		right = make(chan int)
+		go f(left, right)
+		left = right
+	}
+
+	go func(c chan int) { c <- 0 }(right)
+
+	fmt.Println(<-leftmost, time.Since(start))
+}
diff --git a/2014/go4java/img/baby.jpg b/2014/go4java/img/baby.jpg
new file mode 100644
index 0000000..2f32877
--- /dev/null
+++ b/2014/go4java/img/baby.jpg
Binary files differ
diff --git a/2014/go4java/img/badinheritance.png b/2014/go4java/img/badinheritance.png
new file mode 100644
index 0000000..91e4070
--- /dev/null
+++ b/2014/go4java/img/badinheritance.png
Binary files differ
diff --git a/2014/go4java/img/busy.jpg b/2014/go4java/img/busy.jpg
new file mode 100644
index 0000000..35ce9f4
--- /dev/null
+++ b/2014/go4java/img/busy.jpg
Binary files differ
diff --git a/2014/go4java/img/chain.jpg b/2014/go4java/img/chain.jpg
new file mode 100644
index 0000000..87f8571
--- /dev/null
+++ b/2014/go4java/img/chain.jpg
Binary files differ
diff --git a/2014/go4java/img/conc.jpg b/2014/go4java/img/conc.jpg
new file mode 100644
index 0000000..5813956
--- /dev/null
+++ b/2014/go4java/img/conc.jpg
Binary files differ
diff --git a/2014/go4java/img/duck.jpg b/2014/go4java/img/duck.jpg
new file mode 100644
index 0000000..344b31e
--- /dev/null
+++ b/2014/go4java/img/duck.jpg
Binary files differ
diff --git a/2014/go4java/img/fast.jpg b/2014/go4java/img/fast.jpg
new file mode 100644
index 0000000..9b56e23
--- /dev/null
+++ b/2014/go4java/img/fast.jpg
Binary files differ
diff --git a/2014/go4java/img/funcdraw.png b/2014/go4java/img/funcdraw.png
new file mode 100644
index 0000000..374ea2e
--- /dev/null
+++ b/2014/go4java/img/funcdraw.png
Binary files differ
diff --git a/2014/go4java/img/funnelin.jpg b/2014/go4java/img/funnelin.jpg
new file mode 100644
index 0000000..2bf6873
--- /dev/null
+++ b/2014/go4java/img/funnelin.jpg
Binary files differ
diff --git a/2014/go4java/img/gopher.jpg b/2014/go4java/img/gopher.jpg
new file mode 100644
index 0000000..68795a9
--- /dev/null
+++ b/2014/go4java/img/gopher.jpg
Binary files differ
diff --git a/2014/go4java/img/lego.jpg b/2014/go4java/img/lego.jpg
new file mode 100644
index 0000000..7c77051
--- /dev/null
+++ b/2014/go4java/img/lego.jpg
Binary files differ
diff --git a/2014/go4java/img/perfection.jpg b/2014/go4java/img/perfection.jpg
new file mode 100644
index 0000000..ba57eea
--- /dev/null
+++ b/2014/go4java/img/perfection.jpg
Binary files differ
diff --git a/2014/go4java/img/piet.png b/2014/go4java/img/piet.png
new file mode 100644
index 0000000..f4856e1
--- /dev/null
+++ b/2014/go4java/img/piet.png
Binary files differ
diff --git a/2014/go4java/img/trends.png b/2014/go4java/img/trends.png
new file mode 100644
index 0000000..08dc1cf
--- /dev/null
+++ b/2014/go4java/img/trends.png
Binary files differ
diff --git a/2014/go4java/loopback.go b/2014/go4java/loopback.go
new file mode 100644
index 0000000..4574bc7
--- /dev/null
+++ b/2014/go4java/loopback.go
@@ -0,0 +1,23 @@
+package main
+
+import (
+	"bytes"
+	"net"
+)
+
+func handleConn(conn net.Conn) {
+	// does something that should be tested.
+}
+
+type loopBack struct {
+	net.Conn
+	buf bytes.Buffer
+}
+
+func (c *loopBack) Read(b []byte) (int, error) {
+	return c.buf.Read(b)
+}
+
+func (c *loopBack) Write(b []byte) (int, error) {
+	return c.buf.Write(b)
+}
diff --git a/2014/go4java/runner/embed.go b/2014/go4java/runner/embed.go
new file mode 100644
index 0000000..aef71d7
--- /dev/null
+++ b/2014/go4java/runner/embed.go
@@ -0,0 +1,25 @@
+package runner
+
+// RunCounter2 is completely equivalent to RunCounter,
+// but uses struct embedding to avoid the boilerplate of redeclaring
+// the Name method.
+type RunCounter2 struct {
+	Runner // HL
+	count  int
+}
+
+func NewRunCounter2(name string) *RunCounter2 {
+	return &RunCounter2{Runner{name}, 0}
+}
+
+func (r *RunCounter2) Run(t Task) {
+	r.count++
+	r.Runner.Run(t) // HL
+}
+
+func (r *RunCounter2) RunAll(ts []Task) {
+	r.count += len(ts)
+	r.Runner.RunAll(ts) // HL
+}
+
+func (r *RunCounter2) Count() int { return r.count }
diff --git a/2014/go4java/runner/runner.go b/2014/go4java/runner/runner.go
new file mode 100644
index 0000000..1d01467
--- /dev/null
+++ b/2014/go4java/runner/runner.go
@@ -0,0 +1,55 @@
+// Package runner provides a Runner type that is used to define both RunCounter
+// and EmbeddedRunCounter to show examples of how to use composition in Go.
+package runner
+
+import "fmt"
+
+// A Task is a simple task that prints a message when run.
+type Task struct{ Msg string }
+
+func (t Task) Run() {
+	fmt.Println("running", t.Msg)
+}
+
+// END_TASK OMIT
+
+// A Runner provides a way of running tasks.
+type Runner struct{ name string }
+
+func (r *Runner) Name() string { return r.name }
+
+func (r *Runner) Run(t Task) {
+	t.Run()
+}
+
+func (r *Runner) RunAll(ts []Task) {
+	for _, t := range ts {
+		r.Run(t)
+	}
+}
+
+// END_RUNNER OMIT
+
+// A RunCounter is a Runner that keeps a counter of the run tasks.
+type RunCounter struct {
+	runner Runner // HL
+	count  int
+}
+
+func NewRunCounter(name string) *RunCounter {
+	return &RunCounter{runner: Runner{name}}
+}
+
+func (r *RunCounter) Run(t Task) {
+	r.count++
+	r.runner.Run(t) // HL
+}
+
+func (r *RunCounter) RunAll(ts []Task) {
+	r.count += len(ts)
+	r.runner.RunAll(ts) // HL
+}
+
+func (r *RunCounter) Count() int { return r.count }
+
+func (r *RunCounter) Name() string { return r.runner.Name() }
diff --git a/2014/go4java/writecounter.go b/2014/go4java/writecounter.go
new file mode 100644
index 0000000..9fc9647
--- /dev/null
+++ b/2014/go4java/writecounter.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+)
+
+var (
+	_ = bytes.Buffer{}
+	_ = os.Stdout
+)
+
+// WriteCounter counts how many times `Write` is called
+type WriteCounter struct {
+	io.ReadWriter
+	count int
+}
+
+func (w *WriteCounter) Write(b []byte) (int, error) {
+	w.count += len(b)
+	return w.ReadWriter.Write(b)
+}
+
+// MAIN OMIT
+func main() {
+	buf := &bytes.Buffer{}
+	w := &WriteCounter{ReadWriter: buf}
+
+	fmt.Fprintf(w, "Hello, gophers!\n")
+	fmt.Printf("Printed %v bytes", w.count)
+}