Tuesday, May 26, 2015

Tetris Written in Go

I implemented a console-based version of Tetris in Go.

In general, it was a pleasant experience. I made use of the termbox-go library for console graphics, and it was enjoyable as well.

I've been reading a lot of blog posts recently about Go, and I think this blog post is the one that captures my opinions best. It's also a treasure trove of useful links to various other blog posts and tidbits.

Anyway, as I said, it was a fun experience :)

Saturday, May 16, 2015

Go: A Surprising Edge Case Concerning append and Slice Aliasing

In Go, the append function reallocates the underlying array if there's no more room. Hence, if you have two slices that point to the same array, after you append to one of the slices, the other slice may or may not point to the same array. This can lead to some unexpected behavior:

package main

import "fmt"

func main() {
 // Create a slice of length 1 and capacity 2.
 a := make([]int, 1, 2)

 // b "aliases" a
 b := a

 // If I set something in a, you see it in b.
 a[0] = 1
 fmt.Println(a[0], b[0]) // Prints 1 1; they're equal.

 // append returns a new slice, but with the same array.
 // Hence, if I set something in a, you still see it in b.
 a = append(a, 2)
 a[0] = 2
 fmt.Println(a[0], b[0]) // Prints 2 2; they're equal.

 // I'm doing the same thing as last time. However, this time,
 // append has to allocate a new array because there's not enough
 // space. Hence, if I set something in a, you don't see it in b.
 a = append(a, 3)
 a[0] = 3
 fmt.Println(a[0], b[0]) // Prints 3 2; they're *not* equal.

Having multiple aliases to the same mutable data can lead to some subtle behavior and lots of bugs if you're not careful. It's perhaps even more surprising to the naive reader since a and b don't look like pointers. In fact, they're not. They're slices which are a value type that have a pointer within them.

Immutable data structures (like lists in Lisp) don't have these issues. However, you lose some of the performance that a raw array can provide.

Saturday, May 02, 2015

Books: Getting More: How You Can Negotiate to Succeed in Work and Life

I finally finished Getting More: How to Negotiate to Achieve Your Goals in the Real World. It was one of the most influential books I've ever read. It has impacted every area of my life!

Saturday, November 29, 2014

Monday, November 10, 2014

Play Framework Essentials, Learning Scala, and Functional Programming Principles in Scala

I've been really busy over the last six months or so:

First, I was a technical editor for Play Framework Essentials. It's a fun book because every example is first shown in Scala and then in Java, which makes it kind of a Rosetta Stone for the two languages.

Then, I was a technical editor for Learning Scala. That was a great book! Jason did a great job making a really complex language very approachable. This wasn't the first book I've read on Scala, but it's certainly one of my favorites!

Finally, I took Martin Odersky's class on Coursera, Functional Programming Principles in Scala. I really liked that as well because it gave me a much stronger grasp of functional programming fundamentals. Furthermore, I participated in a study group at Twitter, which made the whole experience much more rewarding.

My hope is that I'll get to the point where I can teach a few Scala classes at work. Hence, I've been working my butt off two hours a day on BART and a couple hours on Saturdays in order to get up to speed with Scala. I still haven't written anything large, but at least I'm feeling a lot more comfortable with it these days.

Wednesday, June 11, 2014

Python: Custom App Labels in Django

Django has had a long-standing missing feature that made it impossible to give your apps friendly names. See #3591 and #14251. Thankfully, this will be fixed in Django 1.7, but switching to the latest version of Django is not an option for me right now. This was making my admin look really ugly because I have app names such as "mps" and "budget_cost_data". Those would show up in random places in the admin as "Mps", "Budget_cost_data", "Budget cost data", etc. What I wanted was "MPS" and "Budget Cost Data".

There are many ways to try to solve this problem. You may be able to switch to Django Suit or Grappelli and then use localization to fix it. However, when I tried that approach with Django Suit, the breadcrumbs were still broken.

I finally found this snippet which got me started down a viable path. I grabbed a copy of the Django egg I was using, unzipped it, and copied django/contrib/admin/templates/admin to my project's templates directory. Then I started hacking. I created two filters:

def custom_app_label(value):
  """This is used to change the Django app labels.

  See: https://snipt.net/chrisdpratt/overriding-app_label-in-django-admin/

  return settings.CUSTOM_APP_LABELS.get(value.lower(), value)

def custom_title(value):
  """This is used to change the <h1> in admin/base.html."""
  if value == "Site administration":
    return "Site Admin"
  if value.endswith(" administration"):
      app, administration = value.split()
      app = custom_app_label(app.lower())
      return "%s Admin" % app
    except ValueError:
  return value

Then, I applied one of those two filters everywhere in the admin templates that I needed to. Make sure you remember to load your filter library at the top of each template you modify.

You may want to give your models friendly names as well, such as:

class PlatformBudgetCostData(models.Model):
  class Meta(object):
    verbose_name = "Platform Budget Cost Data"
    verbose_name_plural = verbose_name

At the end of the day, I got something that wasn't as beautiful as, say, Django Suit, but at least the app names, titles, capitalization, etc. looked right.

Friday, June 06, 2014

A Blog Post on Excel, 4x4s, Moonshots, and General Purpose Software

Using Excel is like driving a 4x4. Writing custom software is like building an interstate freeway.

With a modest amount of training, you can do amazing things with a 4x4. You can go to places where there are no roads. If you don't like where you are, you can just as easily drive somewhere new. The downside is that when you're driving off-road, you generally have to drive pretty slowly, and you have to bring your own gas.

You do have to be a specialist to build an interstate freeway. In fact, it requires an amazing amount of work from a large number of people. Yet, once it's built, a 100,000 people a day can fly by at 70mph. It offers them tremendous convenience; they don't even need to bring their own gas! On the other hand, a freeway is only useful if it goes in the direction you need to go.

Hence, Excel offers tremendous flexibility, whereas custom software offers tremendous convenience. Excel is easy to get started with, but grows unwieldy as you scale the size of your models and teams. Custom software is fairly difficult to get started with but is easier to scale in terms of size and usage.

I have to interact with Excel a lot, and yet I've spent most of my career writing custom software. What amazes me about Excel (or, rather, spreadsheets in general) is that it's so amazingly general purpose. Think of how useful spreadsheets are to businesses all over the world. There are few pieces of software that are as general purpose or as widely useful as spreadsheets are.

To some degree, it seems to me that Silicon Valley is drunk with the power of being able to write custom software. Pretty much my whole career has been spent writing it. But what about writing new general purpose software like Excel? As far as I can tell, not many people get to work on general purpose software, and even fewer people get to create new types of general purpose software.

The first commercial spreadsheet was VisiCalc. What an amazing invention! Although VisiCalc was used by far fewer people than, say, Excel, it's notable because it represented a new "type" of general purpose software; it changed the world.

Now, think about all the other types of general purpose software. Most of it was invented a long time ago. Word processors, operating systems, web servers, databases, ERP systems, etc. were all first created decades ago. That's ancient history as far as computing goes! (Although, to be fair, all of these things are incredibly recent in terms of the history of civilization or the history of mankind.)

So, where are the new types of general purpose software? It's actually kind of hard to recognize them because they haven't been around long enough or copied enough times to be recognized as a "type" of software. However, I think that we're far enough along to recognize Facebook is an instance of the type "social network." Similarly, Twitter is a "microblog" (among other things). Both of these things have had a fairly worldwide impact.

Facebook and Twitter also illustrate another thing. You could say that both of them are really just custom software, whereas the truly general pieces of software that they're built on are web browsers, web servers, databases, programming languages, and operating systems. On the other hand, as I said above, they're also instances of new types of software: social networks and microblogs. Innovation is like that. An instance of one type of thing can become its own new type of thing. Innovation is always pushing toward greater specialization.

Now consider programming languages. We've seen a lot of evolutionary improvement, but a lot of the revolutionary ideas first happened decades ago. Think of subroutines, OOP, exceptions, processes, threads, coroutines, types, recursion, closures, compilers, interpreters, virtual machines, etc. These concepts have been around for decades. Sure, we have new programming languages that each have a different philosophy on how these things should work, but most of the really big ideas happened decades ago. I thought software transactional memory might be a counterexample since it seems fairly recent, but even that started about two decades ago.

Imagine, if you were to invent a fundamentally new replacement for subroutines, create a new way to package data and/or code together, or create a new form of concurrency, what would it look like?

Of course the flip side is that it's really hard to get people to understand and accept fundamentally new ideas. It took at least a decade or two before OOP was generally considered a useful technique, and that's still not universally accepted ;) The same is happening now for functional programming. And who knows where we'll go with concurrency in the future!

Truly new ideas just don't come along that often. It takes a while for a new instance of a thing to be recognized as a new type of thing. There aren't that many "moon shots" as Google likes to put it. And when they do come along, they often take a really long time before they gain widespread acceptance. Furthermore, the first mover often isn't the one who reaps the greatest rewards. Excel wasn't the first spreadsheet. Google wasn't the first search engine. Facebook wasn't the first social network.

I'm not really saying anything new. Kevin Kelly did a much better job explaining all of this in his wonderful book, What Technology Wants, but I'll leave you with a quote from another excellent book, The Myths of Innovation, Don't worry about people stealing your ideas. If they're any good, you're going to have to cram them down people's throats!