The Benefits of Speaking

Originally posted on the MeetMe Engineering Blog.

I enjoy speaking in front of an audience. This doesn’t mean I don’t get nervous. Oh, I get nervous enough that I really do need that drink of water. I still love it – the challenge of reacting to the audience, the desire to impart what I know into something meaningful for them.

The greatest feeling I can get from a talk is someone coming up afterwards to thank me for saying what I said. For someone quoting me to me. Hell, for rephrasing what I said more eloquently. But really, it’s about connecting.

But beyond that joy, what real benefits does it give me as the speaker? And, at the same time, what benefits could it provide you?

I want to share my recent revelation with you, something I truly discovered after my most recent talk at Atlassian Summit 13. I had submitted the talk proposal four months earlier. I proposed to talk about a project I was currently on, and about the lessons we had learned in trying to do all that we would try to do. It was a lessons-learned talk, a retrospective. At the time, I had no clue as to what I would end up talking about. I just knew that between the time I proposed the talk and the time it came upon me, I would have learned a few things along the way.

Knowledge

It was because of accepting this talk that I forced myself to really explore what was going on in the project. What I mean is that while I knew there were problems, I couldn’t just point to the problems and say, “See! Don’t do that!” I had to understand why the problems existed, and more importantly, I had to offer up solutions.

I also started going around to certain individuals to try and understand their point of view. That means discussing matters with members of QA, and the other programmers on the team. From them, I not only gained better insight, but also uncovered wonderful metaphors I could use to describe the problems we were facing.

My initial slide deck was structured in the same what that a refactoring recipe is often presented: a smell, followed by why these are problems, followed by solutions. It seemed simple enough. But this was really just the first step. When I started practicing the talk, I came to the realization that while the presentation was factual, it was also fairly negative, and focused too much on the problems. I had very specific points I wanted to make, and most of these points were small bullet points in the third slide of each Smell/Problem/Solution set. I was burying my lead at every point!

The process of practicing my speech, of doing the research to put it together, of talking to individuals drove me to the point of understanding not only the problems, but also how I could properly present the solutions.

But that’s the point. By accepting my role as a speaker, by agreeing to get in front of people to speak on a topic, I need to make sure I know what I’m talking about. So that means I’m going to research the heck out of my topic of choice. That might seem backwards, but it’s not. You see, you’ll want to speak on a topic you’re already familiar with, but once you realize you need to speak on that topic, you’ll force yourself to work extra hard, understanding the additional nuts and bolts.

In the same way that teaching something requires you to learn about it, speaking on a topic means you’ll spend that extra time. And it’s also a great way to learn something. Normally, we are trying to learn something so we understand it. However, when you have to speak about a topic, you have to learn how to describe it easily. You have to impart that knowledge onto others. That means not only understanding it, but understanding it well enough that you can share that information with your audience.

Basically, giving a talk forces you to learn more than you normally would.

Confidence

Since as far back as I could remember, I’ve never had an issue being in front of people. That’s not to say I don’t get nervous, but rather that I overcome that nervousness. I’ve been in plays, I’ve given talks on topics at local events, I’ve stood alone in front of hundreds, I’ve been a member of a panel; but a talk at a national event is distinctly different. Unlike most other cases, a talk at a conference is one where you are very much aware money was involved (usually a significant amount) and people are choosing to use some of their limited time at that conference to listen to you. You are keenly aware that they did not pay to listen to you, but rather, paid the conference in the hopes that they chose correctly when allowing you to speak.

It wasn’t until I got to Atlassian Summit that I fully realized the gravity of my decision to speak. It was far larger than I’d anticipated, and the audiences in each of the tracks easily went beyond 200 people. And not only were there a lot of people, but the caliber of these people were intimidating. Lockheed Martin, NASA, Disney and LG just to name a few. I’m pretty sure I’m forgetting even larger ones. The point for me was learning this, and knowing that I had to give a talk in front of these people Thursday morning. It’s not that I didn’t think I could give the talk. Rather, it was worry that my talk might not be worth their time. Will my talk make them feel as if that hour had been a waste?

Basically, I wasn’t confident my talk was of any value to the audience I was presenting in front of. I shouldn’t have been worried. A large company is still made up of small teams, and those small teams still have the same problems other small teams have. It wasn’t until after the talk that I truly understood that. In the end, the confidence I gained from giving that talk would help me reach higher and farther than I would normally.

I’m talking about the confidence you get after a talk. That feeling you get when you finish, several people come up to you, thanking you personally and wanting to talk further about what you just spent thirty-minutes to an hour talking about already. The thrills of having someone come up and quote you to you. Reaching people.

That confidence can’t be found any other way. You can only earn that confidence after speaking. And that confidence will stay with you far longer than other kinds. And in the end, it will help you drive yourself farther along, to push yourself further.

Friends

The opportunities to speak can also help bring new friends. I’m not speaking about the act of speaking. But speaking in front of new people means you are meeting new people. You are visiting new places. And that brings you new opportunities to make new friends that you would not have made otherwise.

And beyond just making new friends, you can also learn from other people. I’ve been lucky enough to hear interesting stories from people sharing what they’ve done. Even when what they do has nothing to do with what I’m going to talk about, I’m still learning, and making new friends.

The desire to share my knowledge, the desire to speak, gave me the opportunity to make new friends. Meeting up at local user groups and offering to share my knowledge put me in the spotlight. When I moved back to the US, the first friends outside of work that I made were those I made at user groups. Being active in the user group with talks presented me with opportunities to work with them, and in the end, become friends.

You should speak

You really should. You won’t start out in front of a large crowd. You’ll do it first in front of people you know such as coworkers at your company. You’ll branch out into local meet up groups, speaking on carefully selected topics. And maybe that’s as far as you’ll ever want to go. That’s fine. But maybe you’ll want to go farther. And you’ll love it.

You really should try. It can be scary. It is a challenge. It does take work. But it can be worth it. And it can take you places you would have never gone otherwise.

Features of Leadership

Since speaking at Atlassian Summit (of which I’ll be writing and sharing more about in the coming weeks), I’ve been following up by reading more and more about the topics that I covered. Here are a few articles I’ve come across that deal with leading a technical team and the issues and decisions those leaders must face.

On technical debt, complexity and opportunity cost

This article isn’t just about technical debt, it’s offering advice on how to approach technical debt. What to do about keeping it, or removing it. The idea that when developing a new feature that integrates with older features, keeping that older feature still requires time and effort.

it’s worth challeging the idea that every old feature is going to have more business value than the new features they are competing with.

He also goes into thinking about the cost of a feature as not just the time it takes to complete it, but rather, when it’s finished, the truth time it will take to support is only just beginning.

When you release a feature it’s not the end of the job, it’s just the beginning!

Something I’ve always encouraged and pushed for is the idea a criteria for the success of a project. But I like the idea of pushing for criteria for the success of a feature. Is a specific feature worth keeping?

it’s important to define success criteria upfront. If the feature doesn’t meet the measure of success you’ve defined, remove it. And if it does, we know the debt is worth taking on.

The one cost engineers and product managers don’t consider

This is an excellent read by someone who has taken the time to be fairly introspective in his craft. It’s fairly clear when he states the reason for discussing what he does.

For years, the two things that most frustrated me to hear from product managers were “how hard would it be…” and “can’t you just…” It took me quite a while to figure out why I had such a strong, visceral reaction to these phrases. The answer seems obvious now: The work of implementing a feature initially is often a tiny fraction of the work to support that feature over the lifetime of a product [Emphasis mine]

He also goes on to make the point that even features that have no impact to the quality of the product are still negatively impacting the complexity of the software.

If you methodically test the impact of each change you make, you can discard those that are negative, but equally relevant to complexity cost, also discard those that are neutral. A change that doesn’t hurt the key performance indicators still hurts the product because it adds complexity debt that must be paid on all future projects. [Emphasis mine]

Without even realizing it, he comes up with a couple of simple rules that, if you understand, can lead to better software, and as a result, allow you to build better products.

  • Train your entire engineering department to understand complexity cost and to use data to keep it down.
  • Embrace simplicity in your product and in your code. The value is in what gets used, not what gets built.

There are no small changes

I enjoyed this article because it took us through an example of how a simple requirement can lead to a lot of extra work. The idea of now limiting a product review to 140 characters.

Sandwiching this story are two keep points:

  • There are no small changes when you’re committed to delivering quality software.
  • Scope grows in minutes, not months. Look after the minutes, and the months take care of themselves.

What CTOs fear most

I think all software developers would do well to strive to be good CTOs, whether they are CTOs or not. A CTO does more than worry about the technology. It’s a balance of meeting the needs of the business with building good software. Allen Rohner said,

if the technical solution is 100% stable and not being strained at all, it probably means we’ve spent too much time on it.

He also says with something I wish more software developers would strive for:

What’s different about being a CTO vs something like a lead engineer?
Understanding the business model. Making technical choices that shift the business.

The software architect in me cringes at this disregard for software that was obviously well crafted, but the CTO in me understands the point. And that supports the authors opening point in the article:CTOs are worried about how to be great leaders.

After all, being a great leader means not only making that decision to not spend as much time on that technical solution despite knowing it’s not 100% perfect, but also making sure the software architects understand that you aren’t blindly asking them to accrue technical debt.

It’s really interesting to read all the challenges and thoughts that go into being a CTO. It’s not just a fancy 3-letter title. It has meaning.

These four articles cover a lot of information, and I plan on pulling from them key quotes for use later on (some of which I’ve done above). You should definitely spend some time reading through them.

WeGotYourSite

I’ve been on a Startup Weekend kick this past year.  I’ve attended the 3rd Philly Startup Weekend, the first Philly Health Startup Weekend, the 4th Philly Startup Weekend, and the Lehigh Valley Startup Weekend, where my team working on an idea I pitched took 3rd place.  I had a blast at each one.

I also attended the Lehigh Valley Hackathon, where I took first and tied for fan favorite.  I’ve also had the pleasure of helping to plan and participate in 2 hackathons (called Hack’d) at the place I work: MeetMe.

My projects have included Autistic Touch and Special Places, apps centered around children with autism, or their families, shopping services, a music-profile site for bands, and then WeGotYourSite, a service for businesses that lets you use Facebook as your CMS for your website.

I’ve continued to work on WeGotYourSite after the startup weekend.  The team is still active, and we hope to actually make this work.  Sure, there are challenges, and but the basic premise was sound, and we are making good progress.

These events have done a lot for me.  They force you into positions that are outside your comfort zone.  You are forced to pitch in front of everyone, you need to form groups with people you don’t know, and you need to look beyond just the technical side of things.  You need to validate the desires of your customers.  Are you building something people would pay for?  You need to understand how you would go about getting those customers.  You need to understand what’s important, and what can wait.  You come to understand the importance of having a simple message.  You start seeing all the problems that exist in this world, and what we can do to get there.

Whenever I have a problem, I don’t see a problem, but instead, a potential pain-point in need of a solution.

Inbred Code Review

I’ve never heard this term before, but it’s something I’ve coined here at work. Essentially, it’s when a few people working on the same project pass code reviews back and forth to one another.  Problems in the code are harder to detect, because the same group of people get tunnel vision. They see the same code all day long, and find it harder to edit.

Code reviews are supposed to solve that problem.  You giving your code to another person to review, to pass a critical eye looking for design mistakes.  When the people you pass your code to is as familiar with the code as you are, it deadens their ability to look at your code with a fresh look.

Be wary of inbred code reviews.  Try to include on person not familiar with the project on code reviews.

“Jason, looks ok to me, but I think we need to expand the gene pool on this baby.”

On another note, I didn’t realize it was so long since I last blogged.  I have a lot to write, so I’m going to try to implement some form of schedule for writing more often.  I enjoy it, I just forget to.

PHP Tips and Tricks: Array Lengths

This is a simple trick.  It makes the assumption that you manage your arrays properly, and in this case, you are using an array (or list), and not a dictionary.  Basically, a list that starts at 0 (though, the method can be adjust to fit other starting points).

Anyways, there are times I need to know if an array contains 15 elements.  I can quickly discover this like so:

if ( isset($array[14]) ) {

All this does is check to see if there is a value set for element 14.  Again, this makes the assumption that the interface you are calling returns what it says it will.  It should, and if it doesn’t, that’s a serious bug.

This also comes in handy if I only want to return a subset of the information, and need to find out if there is more information.  Let’s say I want to return as little information as possible via the API (I only want to return the first page of results), but I also want to know if there are more results (for pagination, let’s say).  I can then ask the API for 16 results, and then check if there are more results like so:

$isMore = isset($array[15]);

With this simple technique, I need only return 16 results.  I don’t need to do anything else fancy, just return 16 results, display 15 of them, and recognize that there are more results.

Finally, you can use this technique to ensure the length of a string.  So, lets say we want to enforce a minimum line length for passwords, we can enforce it like so.

$isPasswordLongEnough = isset($password[7]);

Obviously in all these cases, we have to be aware of off-by-one errors. For example, $password[7] checks for a password of at least 8 characters, not 7.

Injectors: Dependency Injection with Traits

With the release of PHP 5.4, Traits were added to our toolbox.  And, if I might be so bold, it’s one of the most exciting features I’ve seen come out of PHP in a long time.

Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.

A Trait is similar to a class, but only intended to group functionality in a fine-grained and consistent way. It is not possible to instantiate a Trait on its own. It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.

With this in mind, I knew when I first saw traits that it was the way to solve dependency injection.  Granted, when I say solve dependency injection, I’m mostly referring to the way dependency injection (or DI) is being solved in the current incarnations of PHP frameworks.  Basically, through the use of dependency injection containers (DIC).  Essentially, a dependency injection container stores objects, or the ability to create objects, in some “master” object or container.  I’m not going to spend too much time on what DI is, or what a DIC is.  Fabien Potencier has done an excellent job on the subject with is “What is Dependency Injection” series.

Anyways, let’s be clear about two things here:

  1. Dependency injection is good.
  2. Dependency injection containers solve a real problem.

However, the current incarnations of DICs have problems of their own.  First, let’s cover a problem with basic DI, and what DIC solves.

<?php

class User
{
  protected $record;
  public function __construct( $userId )
  {
    $db = new DB( );
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( 1 );

So, you might recognize this style of programming.  A User is created by passing a $userId to the constructor, whereby it calls the DB class to fetch a record.  What we’ve done here is couple the User class to the DB class.  This means we can’t ever create a User unless we have a DB available.  If we want to create a User from some other source, we can’t without a rewrite.  It also makes testing User difficult.  To test User, we also need to use DB, and make sure that is setup.

The first step to a solution is to inject the DB into the User class like so.

<?php

class User
{
  protected $record;
  public function __construct( $userId, DB $db )
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( 1, new DB( ) );

Now, when we create the User class, we need to pass in the DB container.  That way, we can “inject” into the User class any data store we want.  In fact, we’d probably want to take this a a step further and instead of requiring a DB class, we wants to require an Interface of the DataStore type.

<?php

interface DataStore
{
  public function get( $source, $condition );
  public function limit( $limit );
  public function execute( );
}

class DB implements DataStore
{
  // implementation goes here
}

class User
{
  protected $record;
  public function __construct( $userId, DataStore $db )
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
  }
  // ....
}

$user = new User( '1', new DB( ) );

Okay, so here we see the DataStore hsa been quickly drafted (it’s actually a fairly bad implementation, but serves for the examples).

This means if at some point, we want to create a User from some call to an API, can can inject that instead.

<?php

interface DataStore
{
public function get( $source, $condition );
public function limit( $limit );
public function execute( );
}

class DB implements DataStore
{
// implementation goes here
}

class API implements DataStore
{
// implementation goes here
}

class User
{
protected $record;
public function __construct( $userId, DataStore $db )
{
$this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
}
// ....
}

$user = new User( 1, new API( ) );

And that is dependency injection.  However, a problem occurs a your class starts needing more and more.

<?php

class User
{
  protected $record;
  public function __construct( $userId, DataStore $db, ISession $session, IConfig $config, ITracker $tracker, IMailer $mailer)
  {
    $this->record = $db->get( 'users', "userid = $userid" )->limit( 1 )->execute( );
    $session->start( $this->record->userid );
    $session->lifetime( $config->yes );
    // ...
  }
  // ....
}

Suddenly, you keep adding more and more to your constructor, and it takes on a whole new meaning.  Even worse off is that you might not need the Mailer unless you want to send the user a message.  This means unless you are sending a message, you are creating an object that won’t ever get used.  This also places a lot of work on the programmer using the User class.  Every time they want want to create a User object, they need to create all these classes.  Sure, you could only require the Mailer if the user is going to message someone, and require they use a setMailer( ) function, but that creates even more confusing.

Yeah, gets fairly confusing fast.

So, what do we do about that?

Dependency Injection Container

The idea with the DIC is that you can store your objects, or the generation of those objects in one central registry (generally an array) that can be called from anywhere.  In our example, it might look like this.

<?php

class User
{
  protected $record;
  public function __construct( $userId )
  {
    $db = Container::get('DB');
    $session = Container::get('Session', array('userId' => $userId));
    // ...
  }
}

new User( $id );

In this case, Container is simply that, a container of other objects.  We map the string ‘DB’ to a method, or some system that will return to us the DB class.  Actually, that’s not quite right.  Instead, it returns, in our example, a class that implements the DataStore interface.

In our Container, we can make what DB returns actually be anything we want.

This helps tremendously in testing, because we can setup DB to be something other than an actual DB class.  It can simply be a mock DataStore object setup just for testing.

This is where we currently stand with dependency injection containers in PHP.  They are, for better or worse, global arrays we pass around.  That isn’t so much a problem.  Rather, the problem is one of discovery.  Remember how I said containers like this map a string to an object?  That’s because that’s pretty much all it does.

I pass in DB, and I hope I get back an object like DB.  But where do I go to find out what exactly is happening?  Container::get isn’t actually generating the object.  That’s most likely abstracted out someplace else.  Another problem is knowing which values get will accept.  If I call Container::get(‘Cookie’), will that work as expected?  What about Container::get(‘Mailer’)?  What do these actually return?  Nothing enforces this, nothing is easily discoverable through straight PHP code.  And, frankly, I don’t know how you’d document this.

Container::get, at best, can tell you to pass it a string, and it will return, maybe, something.

It basically comes down to this:

$user = new GoogleTracker(  );

// versus

$user = Container::get(‘Tracker’);

In one case, you know exactly which object you are going to use.  In the other, you can only assume.  In the former, you can get to the code quickly.  In the latter, you cannot.

Don’t get me wrong, DI and a DIC solves a problem.  It’s just missing a crucial piece to complete it.

Traits to the Rescue

So now we come to traits.  Let’s start with a simple example.  In most applications, their exists a concept of configuration.

namespace Lib;

class Config
{
    protected $loadedConfigFile = null;

    protected $configName;

    /**
     * @param string $configFile Full path to config file
     */
    public function __construct( $configFile )
    {

        $this->configName = $configName;
    }

    /**
     * @return object
     */
    public function getConfig( )
    {
        if ( ! isset($this->loadedConfigFile) )
        {
            $this->loadFile();
        }

        return $this->loadedConfigFile;
    }

    /**
     * Loads the config file
     *
     * @return void
     */
    protected function loadFile( )
    {
        $this->loadedConfigFile = json_decode(file_get_contents($this->configName));
    }
}

Ignore the lack of error checking (please!), and let’s explore how we could use a trait to load this.  What we want is to enforce that the same config file is only loaded once.  That way, multiple calls to create Config will only ever have to load the file once.  So, our trait would look like this.

namespace LibInjector;

trait Config
{
   /**
    * @return LibConfig
    */
   public function getConfig( $configName )
   {
        $keyName = __TRAIT__ . $configName;

        if ( ! LibContainer::exists( $keyName ) )
        {
            LibContainer::set( $keyName, new LibConfig($configName) );
        }

        return LibContainer::get( $keyName );
    }
}

Here, the Config trait is created.  We’ve contained the loading code for a Config object in a single place, and that place is easily discovered.  Now, when we want to use the Config class, we can add it to a class like so.

You’ll note I placed the Config trait into the Injector namespace. I like to think of traits used in this manner as an injector – the trait allows you the program to easily inject other needed code into your code.

namespace Lib;

class User
{
    use InjectorConfig;

    function __construct()
    {
        $this->config = $this->getConfig( 'UserConfig.json' );
    }
}

But does this really abstract out the calling of the code?  Sure!

In this case, the trait Config’s getConfig method is fairly short, but that doesn’t mean it can’t expand to handle other cases.  If you want to replace LibConfig with AnotherLibConfig, it’s simply a matter of switching it out.  You can also have getConfig use both Config libraries, determining which one to use based not the $configName passed (let’s say, to handle an XML config file, and a JSON config file, and using two different libraries to handle that).

Injectors are also testable. Granted, you’ll have to Mock out the test Injectors, but I found that to be easy as well.  Again, you can do anything you like in the injector, so handling different test cases is trivial.

Using injectors also give you the benefit of an easy code path to follow.  After all, the class is explicitly using InjectorConfig, which is a specific trait, and easily discovered.  Most IDE’s will make this as easy as clicking on the name Config and it will take you right to the appropriate trait.  And there you see the creation code.

Also, you’ll note getConfig has been given the tag @return LibConfig.  This again provides for clear documentation, and IDE’s should return the proper type, allowing for better auto completion.

I’ve yet to find a case where using an injector has made things difficult or challenging.  And it’s wonderful to work with them.  If I’m in an object and need to include  a Config or Cache object, it’s as simple as adding a use statement at the top of the class and it’s available.

Injectors

I hope you find the use of Injectors interesting.  If you have any questions, let me know.  I’ll try to answer them.  This article has been sitting in my drafts file for far too long, and I need to get it out. So, I’m sure there are errors riddled throughout.  My apologies.  However, I hope the message gets across.  Try using Injectors, and let me know how they work out for you.  I’d love to hear it.

Simple, or why companies reinvent solutions

A designer knows that he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away – Antoine de St-Expurey

HipChat

At work, we are currently experimenting with HipChat.  HipChat, if you aren’t aware, is chat client like IRC.  In fact, the similarities are great.  You log in, you join a chat room, you can talk to people, it keeps a history.  Even there client reminds you of an IRC client.  So the question becomes, in a world with IRC freely available and at your disposal, with MSN and ICQ and various other chat applications available, how could HipChat hope to make an entrance.

Through simplicity.

How does HipChat work? Well, you log into your account, and then you can start chatting away in whatever room you want.  Its contrary to the way IRC works.  With IRC, you have to decide on a server.  Actually, before that, you have to figure out which IRC client you want.  And, of course, you have to learn to use the application.  You probably still have to set up an account on the IRC server (unless you don’t mind not “owning” your name).  Doing this means learning how nickserv works on that network.  Then you have to learn how to join a chatroom… well, it’s annoying.

How does your car work?

Specifically? How do all the computers in your car play a part?  Do you know?  Does it affect your ability to drive?

HipChat works by hiding the complexity.  Driving works because it hides the complexity of the engine and everything that makes it work.  Computers do this as well.  Considering all someone has to do to get a computer and OS up and running is turning the power on, it’s fairly simple from a user perspective.

So, HipChat is successful because it has removed everything unnecessary from the process of group chat.  It doesn’t even require a local client.  You can log in to a website like you do everywhere else and start chatting.  No download required.

One Button

Oddly enough, this is something Microsoft discovered and pioneered before Apple’s iPhone.  Once you started your computer up, there was a button: Start. This made further use of the computer simple.  It was the single starting point, and it even said “Start” so you had a good understanding that whenever you wanted to do something with Windows, you’d Start there.  This of course led to the joke that if you wanted to shut down, you’d want to Start the shutdown process with the Start button.

Regardless, both the Start button and the iPhone/iPad/iPod’s single home button have become popular.  The idea here is removing all unnecessary buttons from the device or system.  The less you have to do, the easier the action becomes.

Less is more, as they say.

Apple took this further with their Magic Mouse.  I’ll admit, I love the little thing.  The combination of a mouse and a touch interface makes it a pleasure to use.  The Magic Touch Pad is also another nice addition.  In this case, there really is no button on the device (that the actual device is an entire button is beside the point).  It’s just flat.

Keyboards

Keyboards are, in some respects, the anti-thesis. It has many different buttons, and modifiers that do different things. Luckily, for the most part, the buttons follow simple rules. The layout is in such a way that makes touch typing incredibly easy.  That touch typing is a skill that’s been around since before computers makes it an easy mechanism to use.  After all, why not build on top of what people already know.  We do this with most calendar applications, which are laid out in a way that is familiar to most everyone.

So, even with all those buttons, a keyboard is still fairly simple because it’s not necessarily attached to the keyboard.  It helps that the letters are printed on the keys in a standard order.  So, because of these simple rules and the fact that their is a history attached to the use of the keyboard, it’s an exception to the rule.  Somewhat.

Virtual keyboards, while following the same layout in most cases, generally don’t share some of the common properties with physical keyboards.  After all, one of the principles of touch typing is actually touching the keys, returning to the home row, and this is facilitated by the little bumps on the ‘F’ and ‘J’ key.  With these, we can easily return to our starting position (And, if you’ll note, on a numerical key pad, you have the same bump on the 5 key).  Virtual keyboards don’t actually have this (despite the “bumps” appearing drawn on.

I’m actually surprised by the number of people that don’t realize what these little bumps are for.

Regardless, people like Swype are looking at ways to improve the virtual keyboard experience.  In Swypes case, while the virtual buttons remain, the actual number of presses are reduced.  You just move the pointer, or your finger, over the keyboard.  This ceases to be a keyboard, and more a drawing tool.

What does this all mean?

I don’t think it’s surprising that simple works best.  Simple doesn’t just mean one button (HipChat isn’t just one button, and keyboards have many), efficiently usable by everyone (keyboards work best when touch typing, but other people can get by pecking along with their fingers), or copying what already exists (after all, the single button approach for the iPhone was completely different from any other phone at the time).

Simple is an odd combination of all these things.  More importantly, it’s about understanding what actually makes things difficult.  Having a common rule for keyboards make them easy to use.  The iPhone copied this style.  All those little apps do something, and they all work the same way.  HipChat works just like any other site.  It’s akin to email, and one of the first things people learn to use is email.  The difficulty in using a smartphone wasn’t the nature of a mobile computing device.  It was simply that applications suddenly had different rules, keyboards had to be modified to account for the size, and they tried to carry over the windows motif from the desktop to the mobile device.  Function keys, modifiers, special keys for different things.

And this leads us to the point: removing that difficulty is something people will pay for.  Keyboards haven’t changed much because the difficult is displayed by the keyboard literally spelling out what each button does.  The challenge now is how to solve the problem of typing on a smaller device.  For the vast majority of users, this isn’t an issue.  They don’t touch type anyways.  However, this doesn’t mean it’s the most efficient way for them.  Swype has one solution.  Apple has another solution: Siri.

HipChat tackled the chat arena.  It was a market that wasn’t exciting from my perspective, and felt saturated.  After all, when you thought about chat, you thought about IRC, and the various clients out there competing for users.  HipChat came in and made a business out of it.

This is important.  When we look for future solutions, one thing we often ignore are the current solutions we use.  Is it really as easy as it can be.  Could we improve on it? What are the painful parts?

It’s not easy to do this.  Google, in some ways, has tried this in the past with things like Buzz and Wave.  Twitter is an example of this same thing: a problem existing, and while solutions existing, they weren’t simplified.  Facebook is the same thing (in some regards).

This all goes back to the Unix mantra: do one thing and do it well.

When I want to run a chat room, I want to run a chat room.  I don’t want to setup a server, or manually set up users.  I don’t want to manage nickserv, or anything else.  I simply want to do something, not manage or setup.  Lots of companies understand this.  Amazon’s cloud hosting services, Netflix and their video streaming, and even Amazon with it’s 1 Click purchasing.

So, don’t be scared to solve something that’s already been solved.  Countless companies have built empires on top of “simply” removing things from existing solutions.

Ideas of March 2012

That time again.  I wrote something last year, covering the ideas of march.  Last year, bloggers came out and shared their ideas, and I imagine this year will be just as fun.  So, once again, I’d like to share my thoughts on blogs.  This year, I’d like to take on the point of view of a reader as opposed to a writer of blogs.  After all, far more people consume blogs then actually write them.

Having trouble keeping up? Share!

It’s hard.  Even with a feed reader, it’s hard to keep up with everything that is going on.  In the PHP world, I can head on over to good-ole PHPDeveloper to find out what is going on in the PHP world, but these days, it’s more than just PHP.  I can of course subscribe to my favorite blogs, but as I said, there is far more out there to read than I have time to enjoy.  Twitter helps some, as I can follow a link from twitter from someone I followed, but even if they post something, I might miss it in the ever moving Twitter stream.

What really helps is when people share.  Between Reddit, HackerNews, people retweeting things they’ve found, DZone, and, of course, PHPDeveloper, there are numerous ways to share.  If you are a reader, and you’ve read something, share it!  A tweet about an article might only bring in a few people, but those are people that might not otherwise have found the article.  Share the article!  Help curate, and get it out there.

That’s something I’m trying to commit to.  And while sharing and those ‘social media’ buttons on articles might seem annoying, they actually serve a purpose to remind us how we get our information.  Just because someone has tweeted an article doesn’t mean his followers will see it.  Too often I find myself following a retweet because I missed the original.

And don’t be afraid to submit to sites like Reddit or HackerNews.  Both are wonderful resources.

Your voice matters

Even if it’s a simple thank you.  You don’t need to spend much time, but every little bit helps.  If you read something, and enjoy it, let the author know.  Nothing makes us happier than when someone takes the time to actually respond.  Not everyone will comment, but getting just one comment usually spawns a few others.

If you are nervous about what you have to say, you can also always send an email.  I think it’s fair to say that unless they say otherwise, bloggers have a standing invitation to contact them.  We’re geeks just like you, and we’re writing about stuff you’re clearly interested in as well, so we already have at least one thing in common.

Read, enjoy

Most of all, and most important, is to read the articles.  Spend time and enjoy them.  All too often we get sucked into the 140-characters or less, StackOverflow-style short answers that let us get in and get out.  I find I enjoy blogs so much more when I just allow myself to read and focus.  I don’t just skim the headlines looking for the answer to a solution.  I sit back with a cup of coffee, and spend a little bit of time reading.  I don’t rush through.  I don’t start an internal debate with what’s being said.  I just read.  I just enjoy.

Too often we allow ourselves to become masters of multitasking.  And there are times this is good.  But we need to learn to shut this off.  Blogs give us this chance.  If it’s worth reading, it’s worth focusing on.

To Bloggers

This is a message to bloggers.  Don’t wait for the perfect article.  Just write.  Share stories of projects.  You don’t need to provide a tutorial or novel solution every time you write.  Simply recounting what you did, even if everything you did is what is normally done, can be just as revealing, just as interesting.  Just write.  Share your stories.  People want to read, and not every article need contain examples of code.

Share your mistakes, share your accomplishments.

I should take my own advice.  Recently we launched Locals at myYearbook.  The web version was my baby.  It’s an awesome product, and combined with the mobile version, makes for something an interesting story on the challenges we faced and how it works.  I haven’t written anything on it because, frankly, I worked on it so much that I can’t see the forest for the trees.  It’s completed, and remembering all the interesting details would take time.  And, wrongly, I feel that to do it justice, I would need to go over everything.

Ideas of March

Finally, here are some ideas I am working on for future articles.

  • Basics of tmux, getting strated with the terminal multiplexer
  • vim maps based on file types
  • An approach for a DIC for PHP 5.4
  • And just for kicks, writing a PHP app without conditions or loops (not recommended for sanity!)

 

vim faster with maps

At myYearbook, we pack our JS and CSS files.  Much of this is automated now with Jenkins, but we still have legacy code that must be packed by hand.  And, at the same time, it’s generally wise to test your product with a packed file regardless.  I also try to make it a habit to phpcs my file as often as possible.  The goal here is to keep the file as tidy as possible, and not waiting for the end to fix everything.  Also, during the course of development, I might come across other little things I want to do, and I use vim to make things as easy as possible.

maps

I do this through maps.  I map is fairly simple to setup in vim.

:map ,cs <ESC>:w|:!phpcs --standard=myYearbook %:p

Typing that into a vim instance means I can type ‘,cs’ in normal mode, and vim will w my file to disk, then run phpcs using the myYearbook standard on the current file I’m working in.  Now, I use that often enough that I’ve added it to my .vimrc file.

map <Leader>cs <ESC>:w|:!phpcs --standard=myYearbook %:p

If you aren’t aware, <Leader> is set to ‘,’ using this bit of code in .vimrc:

let mapleader = ","

The comma is popular, but you can use whatever you want, really.

I can also pack my javascript and CSS files with similar ease using “,pj” and “,pc” (pack javascript, and pack css).

map <Leader>pj <ESC>:!jspack %:p > %:p:h/%:r:r.js
map <Leader>pc <ESC>:!csspack %:p > %:p:h/%:r:r.css

You might be wondering what the ‘%:p’ part is.  It’s actually part of the expand functionality of vim.  Basically, the important parts here to understand is that the % is the current file name.  The “:p” and “:r” parts are the modifiers.  In this case, “%:p” has us expand to the full path.  The “:h” modifier removes the last component.  So, “%:p:h” basically says “Give us the full path, and then remove the head.  The head in this case is the file name, so if the full path (“%:p”) is /Users/jasonlotito/test.php, “%:p:h” gives us “/Users/jasonlotito”.

“%:p:h/%:r:r.js” allows me to rename my file.  In our setup, unpacked files contain the extension “.unpack.”  By Simply using the “:r:r” modifiers, I strip off the “.js”, and then the “.unpack”, leaving me with just the file name.  So, if my javascript file was named Modifiers.unpack.js, I’d be left with Modifiers.  I prefix that with %:p:h/ which gives me the directory the file is in, and append “.css” to the path.

Being able to map commonly performed actions, especially to external tools, means I can stay in vim longer.  Sure, I’ll still background vim when I need to perform certain actions, but I’m more apt to start scripting repeated actions, and then mapping them.