Wednesday, May 2, 2018

My Travel Tips from Recent Business Trip to San Francisco

  • Prefer Lyft to Uber (do not rent a car!)
    • A number of Uber drivers canceled my ride when they discovered that it was a short trip
    • Lyft driver allowed me to store my bike in their trunk when he saw my knee injury
    • SFO tickets and tows autos aggressively

Guess how much it cost to park between the motorcycle and auto?

  • Avoid AirBNB (use a hotel, tripadvisor.com, or rent directly from property owner)
    • AirBNB customer service makes Comcast support look like the concierge at the Ritz-Carlton
    • Find a place with a fridge to store milk for cereal, etc.

  • Make time to exercise
    • San Francisco is a great place to bike!

  • Setup Business Profile where possible (for receipts ex: Lyft, Workshop Cafe)
    • That makes it easy to get receipts for expense reporting after your trip

Friday, December 15, 2017

Learn Functional Programming in Go by Lex Sheehan



Purchase book here.

My publisher just shared the following with me about a week after it was released:
The book ... has been performing good on all our channels and until yesterday we had sold 130 copies. ... It was great news for me and thought of sharing it with you :)  
I deeply appreciate everyone's affirmation (purchase).
I am honored to be a conduit of deep truths of the universe, expressed in diagrams, code examples and prose.
Sincerely,
Lex Sheehan

Thursday, November 30, 2017

Getting Our Go Apps Up & Running on an MS Windows Workstation

The instructions in the book are geared towards a Mac workstation.

This article is written specifically for readers that use an MS Windows workstation.

Install Go

If you don't already have Go installed, install it.  Here's how:

1. Open your web browser and go to https://golang.org/dl/

2. Click the link for go<VER>.windows-amd64.msi
Note: You may need to run the  go<VER>.windows-386.msi binary if you're running a 32bit Windows system.



3. Install Go

Find the setup program that you downloaded and run it (either double click or right-click | Open).
Click <Run> if you're asked if its' okay to run this software.
Click <Yes> if you're asked if it's okay to allow this software to make changes to your computer.

Click <Next>



Leave the default value (C:\Go\) for Go's installation path.

Click <Next>
Click <Next>
Click <Install>
Click <Finish>

Install Cygwin

If you don't already have Cygwin installed, install it.  Here's how:

1. Open your web browser and go to https://cygwin.com/install.html

2. Click the link for setup-x86_64.exe to install
Note: You may need to run the  setup-x86_64.exe binary if you're running a 32bit Windows system.

3. Install Cygwin

Find the setup program that you downloaded and run it (either double click or right-click | Open).
Click <Run> if you're asked if its' okay to run this software.
Click <Yes> if you're asked if it's okay to allow this software to make changes to your computer.

Click <Next>
Choose "Install from Internet"



Leave default value (C:\cygwin) in Root Directory field
Click <Next>
Leave default value in Local Package Directory (Mine is C:\Users\lex\Downloads)
Click <Next>
Click <Next>
Choose a Download Site  (I chose http://mirror.cs.vt.edu)
Click <Next>
If you see a warning about the current ini file, Click <OK>
If it asks to upgrade, Click <OK>
Install git package  (the version for me was 2.15.0-1)

HEY! Did you follow every one of the 4 steps above?  If not, when you try to run the "git clone" command below it will not work.  1) select "Full" view  2) type git in the Search field  3) click where it says "Skip" on the git: Distributed version control system line.  (it should now say something like "2.15.0-1").  4) click <Next>

Click <Next>(You'll see a Progress window)
If you see "In-use file detected" then click <Stop Process> or <Kill Process>
(You may need to click <Stop Process> or <Kill Process> multiple times)
Eventually, you'll see the "Installation Status" window... Click <Finish>

Now, cygwin and git should be installed.  

Note

You can re-run the cygwin setup.exe as many times as you want to add/remove installed packages.

Get source code for book

1. Double click the Cywing Terminal icon on the Windows desktop
2. Enter the following commands to download this book's source files:

cd
mkdir dev
cd dev
git clone https://github.com/l3x/learn-fp-go


Initialize Windows 

cd
cd dev/learn-fp-go/1-functional-fundamentals/ch01-pure-fp/01_oop/
./init-windows.sh

You'll only need to initialize Windows once.  However, every time you start working on a new Go project you'll want to initialize the Go project with it's init script by typing:  . init

Initialize project and run it 

Before you run the ". init" command below, you should edit the init file.  The tenth line of the file looks like this:

#WIN_GOPATH="E:\\\alice\\\dev\\\learn-fp-go\\\1-functional-fundamentals\\\ch01-pure-fp\\\01_oop"

Edit it to look something like this:

WIN_GOPATH="E:\\\YOUR_USERNAME\\\dev\\\learn-fp-go\\\1-functional-fundamentals\\\ch01-pure-fp\\\01_oop"

If you work off your C drive and your username is bob, it might look like this:

WIN_GOPATH="C:\\\bob\\\dev\\\learn-fp-go\\\1-functional-fundamentals\\\ch01-pure-fp\\\01_oop"

For MS Windows users, for every project, you'll need to edit that line to reflect the current directory.

After you have saved the file, run the following:

. init
go-run

It should return this:  Found &{Model:Highlander}

Initializing other projects and running them

To start the second project, cd into its directory and initialize that project.

cd
cd dev/learn-fp-go/1-functional-fundamentals/ch01-pure-fp/02_fib/
. init
go-run


Glide does not work on Windows in Cygwin 

Here's what'll happen when you try to run glide:

Here's another example:


Bottom line:  If you are using MS Windows, you can run the apps that don't have vendor dependencies using Glide.  In other words, the dot glide-update command will not work for MS Windows.  You must find another way to manage your dependencies.  Probably using the standard way will work.  Here's a video that should help you get setup.


Glide Github Issue Created

I created an issue at the glide github repository.  Hopefully, this issue will be fixed by the time you need it.  For details see this issue.

Uninstall Cygwin

Once you're done working through the applications in this book and if you no longer want Go installed on your workstation, here's how to remove Cygwin.

Open a terminal window and enter the following:
takeown /f C:\cygwin /r /d y
icacls c:\cygwin /t /grant everyone:F
del c:\cygwin

Edit files in Cygwin

You can edit files using the vi editor.


Enter vi init to edit the init file.

You can use your arrow keys to navigate down to line 10 and before you get in insert mode, while the cursor is over the # character, hit the x key.  That will delete the #.  Now, you can right-arrow to move to the end of the line and press the x key to delete the 02_fib characters.  Lastly, press the i key to go into insert mode and then type 01_oop.  Press the Escape key an type :wq to save changes.




Saturday, November 18, 2017

Corrections for Learning FP in Go Book

Errors and Corrections

While I did my best to present perfect information, we're all human and make mistakes.  The topics of category theory, functional programming and Go development are extensive and in my effort to organize and condense this information I likely made a few mistakes.  I will post corrections and any other information that might clarify issues in this book here.

If you find any errors and want to share your insights regarding this book feel free to add a comment to this page.  Thanks! Lex

UPDATE:  At the last minute, the Category Theory That Applies chapter 11 was moved to the end of the book.  So, it's best that you read it after immediately after chapter 8 as the author originally intended ;-)  It covers terms like Monoid, Functor, Monad, etc. used in chapters 9 and 10.

Get latest source code here.
If you find any errors, please post a comment on here.


Chapter 1

Words in chapter do not match code

The code is correct.  The words need editing.


Wording in book:




Only the final leaf nodes of are added together to calculate the sum total of 8:

Corrected wording:

Only the final leaf nodes of are added together to calculate the sum total of 5: 


Here's the code:

1-functional-fundamentals/ch01-pure-fp/02_fib/main.go


package main
import (
    "fibonacci")
func main() {
    println(fibonacci.FibSimple(4))
    println(fibonacci.FibMemoized(5))
    println(fibonacci.FibChanneled(6))
}





1-functional-fundamentals/ch01-pure-fp/02_fib/src/fibonacci/meomoize.go 


package fibonacci

type Memoized func(int) int
var fibMem = Memoize(fib)

func Memoize(mf Memoized) Memoized {
   cache := make(map[int]int)
   return func(key int) int {
      if val, found := cache[key]; found {
         return val
      }
      temp := mf(key)
      cache[key] = temp
      return temp
   }
}

func FibMemoized(n int) int {
   return fibMem(n)
}

func fib(x int) int {
   if x == 0 {
      return 0   } else if x <= 2 {
      return 1   } else {
      return fib(x-2) + fib(x-1)
   }
}

Output





URL Missing Dash

This is the correct url: https://github.com/golang/go/wiki/SettingGOPATH

URL for github Repo

The screenshots, links and text reference the repo (this repo) as l3x/fp-go.git, whereas it's actually l3x/learn-fp-go.git.

Error running first example

The screenshot associated to "go run cars.go", shows that one should go run cars.go in the following path: ~/myprojects/fp-go/1-functional-fundamentals/ch01-pure-fp/01_oop.

There is no cars.go in that path, it's actually in ~/myprojects/fp-go/1-functional-fundamentals/ch01-pure-fp/01_oop/src/oop. And even when you do run go run cars.go from that directory, you get:
go run: cannot run non-main package
The easy solution is to use the init script found in every project.  Here's how:
(Double-click image to enlarge)
For details see the How to build and run Go project section in the appendix. 

Many Thanks to Dave for reporting those issues here.

https://github.com/l3x/learn-fp-go/issues/5

If you're an MS Windows user, you should check this out.

Chapters 1 & 5


Any reference to KISS-Glide  should say Dot Init.  They mean the same thing.  It's the bash initialization script that's explained in detail in the How to build and run Go projects section of the appendix.

Chapter 2

Page 55 has typos
The map example on Page 55 has typos that makes the code unable to be ran with the expected results
  • planets used instead of names within collection.NewFromSlice()
  • strings.Join should be strings.Join([]string{"Hey", v.(string)}, " ") or strings.Join([]string{"Hey ", v.(string)}, "")
With these typos fixed
names := []interface{}{
  "Alice",
  "Bob",
  "Cindy",
}

collection := collections.NewFromSlice(names)
collection = collection.Map(func(v interface{}) interface{} {
  return strings.Join([]string{"Hey", v.(string)}, " ")
})
println(collection) // or the use of fmt.Println(collection)

See https://github.com/l3x/learn-fp-go/issues/6

Gleam - distributed MapReduce for Golang

The LuaJit+Go approach has been ditched because of complexity to add new features to Gleam. 

Gleam is now using pure Go everywhere.


Chapter 4

In  func (t *titlizeReader) Read(p []byte) (int, error) ...

There is a typo:  't' should be 'a'

In book:

        if p[i] >= 't' && p[i] <= 'z' {
         p[i] = p[i] - 32
        }
Should be:

        if p[i] >= 'a' && p[i] <= 'z' {
         p[i] = p[i] - 32
        }

 Chapter 9


The directions of the arrows are significant 

The g(x) equation should be:  g(x) = x 2 + 1

... rather than not  g(x) = x2 + 1

Chapter 11

Towards the end of the chapter in a section entitled, Fun with Sums, Products, Exponents and Types,  we talked about looking at structures algebraically and finding matching structures.  The image below should look familiar.  It's an updated, slightly improved version of what's in the book:


Appendix

Old content is found in chapter 4.  The new content was moved to the appendix.  It's a conversation that a Java developer a Go developer and an FP developer had regarding error handling in Go.

A Java, Go and FP developer Walk into a Bar...

DeveloperSays...
Java
I do not like the way Go makes me handle errors after every function call.
I want exception handling like this:
try {
   Decrypt()
   Authenticate()
   Charge()
}
catch (Exception e) {
   // handle exception
}
but after adding all those error checks my code looks more like this:
err := Decrypt()
if err != nil {
   return err
}
err = Authenticate()
if err != nil {
   return err
}
Charge()
Go error handling looks like a bunch of scaffolding  obscuring my code's intentions.
GoAs you know, Go does not support exception handling.  Instead, you return errors to inform the calling function/method that something went wrong.  You are supposed to handle an error as soon as possible.  This is what we call the idiomatic way to handle errors.  When you throw exceptions, how far up the call stack will your handler be?  What if your exception gets handled before it reaches your global error handler?  Will it stop or be rethrown?  If rethrown, do you really want to handle your errors more than once?
Go 
Also, since an error is a value we can program it and do.  See that Scan method?  It might encounter an IO error, but it does not immediately return the error.  Instead it returns a boolean value to indicate success.  Later we can check for the error.
scanner := bufio.NewScanner(input)
for scanner.Scan() {
   token := scanner.Text()
   // process token
}
if err := scanner.Err(); err != nil {
   // process the error
}
We can also clean up the following repetitive error checking code:
_, err = fd.Write(p0[a:b])
if err != nil {
   return err
}
_, err = fd.Write(p1[c:d])
if err != nil {
   return err
}
_, err = fd.Write(p2[e:f])
if err != nil {
   return err
}
// and so on
... by writing a helper that will allow us to wait until we're done writing to handle the error. 
var err error
write := func(buf []byte) {
    if err != nil {
        return
    }
    _, err = w.Write(buf)
}
write(p0[a:b])
write(p1[c:d])
write(p2[e:f])
// and so on
if err != nil {
    return err
}

JavaThat is much better, but is that a reusable pattern?  In each of those two examples above, we had to write custom error handling code in two different places, right?  Isn't there a more generic, yet Go idiomatic way to handle errors that will eliminate that repetitive error checking code and allow me to check for errors in one place, at the end of my workflow?
FP
Yes, Java developer there is and it's called the Lexical Workflow Solution.  Read all about it in chapter 11.  If you use it, your code will look something like this:
step = Next(step, Decrypt)
step = Next(step, Authenticate)
step = Next(step, Charge)
json, err := step(nil)
if err != nil {
   // handle error
}
The Go developer's error handling code samples above came from https://blog.golang.org/errors-are-values



Monday, November 13, 2017

The Final Lap

UPDATE:  The publisher changed the book colors to ORANGE & BLUE for us!





Just got this message from my editor:

"We are all set for the final lap. Here we have all the chapters almost in the final form to go in the book."


It's been a marathon.

Cheers!
Lex


Friday, November 10, 2017

Learning Functional Programming in Go - Preface

Until recently the message has been, "Go and Functional Programming.  Don't it."

Functional Programming (FP) is a perfect fit for multi-core, parallel processing.  Go is a concurrency baller (with Goroutines, channels, etc.) and already runs on every available CPU core.

FP reduces complexity.  Simplicity is one on Go’s biggest strengths.

FP scales.  Go scales and we already covered this.  Go away.

So, what can FP bring to Go that will actually improve our software applications?
  • Composition.  FP shows us how to decompose our apps and rebuild them by reusing small building blocks.
  • Monads. Using monads, we are able to safely order our workflows into pipelines of data transformations.
  • Error handling. We can leverage monadic error handling and still maintain compatibility with idiomatic Go code.
  • Performance.  Referential transparency is where we can evaluate our function once and subsequently refer to its pre-computed value.
  • Expressive code.  FP allows us to concisely express business intent in our code. We declare what our functions do, without the clutter of error checking after every function call and without having to follow state changes (pure FP means immutable variables).
  • Simpler code. No shared data means not having to deal with semaphores, locks, race conditions  or deadlocks.
Most people have difficulty grasping functional programming.

I did, too.  When I “got it” I wrote this book.  Take this journey with me.  You’ll see hundreds of illustrations, read easy-to-understand explanations and implement FP in Go code along the way.

I enjoyed coaching soccer. The litmus test I used to determine whether I succeeded as a coach was the answer to this simple question, "Did they all register for next season and request for me to be their coach?"  Just like planning practice, I planned each chapter; Starting with simple concepts and adding to them.  Read this book.  Then you, too, will be able to say, “I got it.”

If you want to improve your FP skills this book is for you.


Coach Lex