Uncategorized

...now browsing by category

 

On Muted Methods, Fluent Interfaces, and Bar Game

Monday, August 24th, 2009

One night a weekend back I went out to the local bar back home with my younger sister some of our friends. Back home means Rutherfordton, North Carolina. The kind of charming area that greets you at the county line with the road sign “Welcome to Rutherford County, Small Town Friendly”. A friendly place, it is.

While sitting at the bar one of my sisters’ friends drew a lot of attention from the gentlemen of Rutherford County. We’ll call her Liz (gah, when does 30Rock start up again??). Some would come up and chat, others ask for a dance. The most peculiar case of them all was one who had been ordering drinks from across the bar and finally got up the courage to come over and, without a word, slip Liz a piece of paper with his phone number on it before disappearing into the night.

Yes, this post is about programming, bear with me.

Let’s give this guy, say Dennis, the benefit of the doubt and assume that these tactics have worked before with success. On this particular night with a gorgeous girl from out of town: no dice. Dennis wouldn’t get the callback.

Let’s pseudo-code this scenario:

$liz = new AttractiveOutOfTownGirl();
$dennis = new SmallTownFriendlyYoungMan();
$liz->setDrink($dennis->buyDrink('Vodka Redbull'));
$liz->setDrink($dennis->buyDrink('Sex on the Beach'));
$liz->receiveNumber($dennis->getPagerNumber());
$dennis->disappearIntoTheNight();

Spot any patterns? Thrice Dennis has taken an action that results in some value: he’s bought 2 drinks and retrieved his pager number. All of his methods have resulted in some value that is handed to Liz and he’s getting no acknowledgement back. He interacted with muted methods. Dennis’ shot at success depended on Liz having some internal, finite state machine that transitioned from “stranger” to  “stranger willing to call a stranger” with every additional drink. How could this have gone better for Dennis?

Before we get there let’s talk about muted methods. Procedures. Voids. Black holes in programs where input results in no output. Scary stuff! But why, what’s so bad about muted functions? Let’s nitpick our example. It is so  choppy. Do you feel the choppiness?

Noun verb.
Noun verb.
Noun verb.
Liz set drink.
Liz set drink.
Liz give number.

When your verb is muted, there’s nothing more to be said. End of story. Next line. You’ve got nothing to play off of, no chance to converse. When you’re working with muted functions you have no segue. You’re giving without receiving.

If muted functions are the problem, how could this scene look a little less ugly? Perhaps Dennis could have conversed with Liz. Interacted with her. Made use of a more fluent interface

$dennis->saysTo($liz, "Hey girl, from out of town?") // returns $liz
       ->saysTo($dennis, "Yes, how'd you know?") // returns $dennis
       ->saysTo($liz, "Never did seen you before!") // returns $liz
       ->isStillSmiling()
       ? // If she's smiling
   $liz->setDrink($dennis->buyDrink('Vodka Redbull')) // returns $liz
       ->saysTo($dennis, "Thanks, you're kind of cute.")
       ->saysTo($liz, "That's how we're grown here. Can I call you?")
       ->saysTo($dennis, "Sure, my name is Liz and the number is...")
       ->punchesInNumber("919-928-9090") // returns $dennis
       ->says("Great, call you tomorrow!") // returns $dennis
       ->disappearIntoTheNight()
       : // If she's frowning
$dennis->movesAlong();

When you’re not dealing with muted methods you give your code the chance to come to life in a more fluid, fluent way. There’s only sentences here, it’s just longer, richer, and more involved. There’s magical, programmatic banter happening here!

This style of object-oriented interface, where method chaining and thoughtful return values enable a pseudo-domain specific language written entirely in a general purpose language, has been called a “Fluent Interface” by Martin Fowler and Eric Evans. It’s an inspiring departure from the days of the void, black hole methods like setters.

So, next time you’re writing an interface for some new class, or sitting at a bar wondering how best to approach that attractive member of the opposite sex, avoid muted methods at all costs. They’re black holes. They’re just awkward, feedbackless, and overall uncomfortable for everyone involved.

When your functions or methods don’t return ask yourself “if I were to return something here what would be useful?” Most often, it’s a reference to the object itself. Or an immutable clone.

“Oh, god no, not an immutable clone! I thought this article was about bar game?” Hmm… you’re right. I’ll save the immutable clone wars for another post. You should subscribe to this RSS feed if immutable clones pique your interest. Or nerdy bar game.

setDrink($this->buyDrink(’Vodka Redbull’));

What’s on my mind…

Thursday, August 20th, 2009

In an hour I’ll be out doing late night trivia in a bar in Chapel Hill, North Carolina. Pop trivia has never been something I excel at, but with the right company it’s fun to wager a guess, or two, and let go of the problems that consume idle cycles. As of late my thought has been switching between any of the following:

This space should be more lively than the ghosttown that it has become over the last 8 months. More off the cuff writing on the topic of the hour than the more structured pieces I’ve been writing for New Media’s Web Development Blog or the Recess PHP Blog.

To kick that off the off the cuff writing, a few words on _why. I don’t know _why, I haven’t read the poignant guide to Ruby (although I’ve come across it a number of occasions and been intrigued), nor have I used much of his huge body of open source work. None the less his recent disappearance has been sitting really funny on my stomach. Really funny. This guy is prolithic, talented, and obsessed with teaching the art and joy of programming. I didn’t fully appreciate _why until watching his recent talk at Carnegie Melon [embedded below]. His excitement and creative knack for opening programming up to a younger audience is energizing. Here’s to hoping an even brighter chapter to that story is about to unfold…

Towards RESTful PHP – 5 Basic Tips

Tuesday, December 2nd, 2008

What is REST?
REST is an architectural style, or set of conventions, for web applications and services that centers itself around resource manipulation and the HTTP spec. Web apps have traditionally ignored the HTTP spec and moved forward using a subset of the protocol: GET and POST, 200 OKs and 404 NOT FOUNDs. As we entered a programmable web of applications with APIs the decision to ignore HTTP gave us problems we’re still dealing with today. We have an internet full of applications with different interfaces (GET /user/1/delete vs. POST /user/delete {id=1}). With REST we can say /user/1 is a resource and use the HTTP DELETE verb to delete it. For more detail on REST check out wikipedia and “quick pitch“.

Tip #1: Using PUT and DELETE methods

In PHP you can determine which HTTP method was used with: $_SERVER['REQUEST_METHOD']; From web browsers this will be either GET or POST. For RESTful clients applications need to support PUT and DELETE (and ideally OPTIONS, etc.) as well. Unfortunately PHP doesn’t have $_PUT and $_DELETE variables like it does $_POST and $_GET. Here’s how to access the content of a PUT request in PHP:

$_PUT  = array();
if($_SERVER['REQUEST_METHOD'] == 'PUT') {
    $putdata = file_get_contents('php://input');
    $exploded = explode('&', $putdata); 

    foreach($exploded as $pair) {
        $item = explode('=', $pair);
        if(count($item) == 2) {
            $_PUT[urldecode($item[0])] = urldecode($item[1]);
        }
    }
}

Tip #2: Send Custom HTTP/1.1 Headers

PHP’s header function allows custom HTTP headers to be sent to the client. The HTTP/1.x header contains the response code from the server. PHP will, by default, send back a 200 OK status code which suggests that the request has succeeded even if it has die()’ed or a new resource has been created. There are two ways to change the status code of your response:

header('HTTP/1.1 404 Not Found');
/* OR */
header('Location: http://www.foo.com/bar', true, 201); // 201 CREATED

The first line is a generic way of setting the response status code. If your response requires another header, like the Location header to the resource of a ‘201 Created’ or ‘301 Moved Permanently’, placing the integer status code in the third parameter of header is a shortcut. It is the logical equivalent of the following example, which is easier to read at the cost of being an extra line of code.

header('HTTP/1.1 201 Created');
header('Location: http://www.foo.com/bar');

Tip #3: Send Meaningful HTTP Headers

Policy for deciding when it is appropriate to send each HTTP status code is a full post on its own and the HTTP spec leaves room for ambiguity. There are many other resources on the net which provide insights so I’ll just touch on a few.

201 Created is used when a new resource has been created. It should include a Location header which specifies the URL for the resource (i.e. books/1). The inclusion of a location header does not automatically forward the client to the resource, rather, 201 Created responses should include an entity (message body) which lists the location of the resource.

202 Accepted allows the server to tell the client “yeah, we heard your order, we’ll get to it soon.” Think the Twitter API on a busy day. Where 201 Created implies the resource has been created before a response returns, 202 Accepted implies the request is ok and in a queue somewhere.

304 Not Modified in conjunction with caching and conditional GET requests (requests with If-Modified-Since / If-None-Match headers) allows web applications to say “the content hasn’t changed, continue using the cached version” without having to re-render and send the cached content down the pipe.

401 Unauthorized should be used when attempting to access a resource which requires authentication credentials the request does not carry. This is used in conjunction with www-authentication.

500 Internal Server Error is better than OK when your PHP script dies or reaches an exception.

In the Recess! Framework I use this StatusCodes class to provide named constants for all HTTP/1.1 status codes. Example usage:

header(StatusCodes::httpHeaderFor(StatusCodes::HTTP_NOT_FOUND));

Tip #4: Don’t Use $_SESSION

A truly RESTful PHP application should be entirely stateless- all requests should contain enough information to be handled without additional server side state. In practice this means storing authentication information in a cookie with a timestamp and a checksum. Additional data can also be stored in a cookie. In the event you need more than a cookie’s worth of data fall back to storing it in a central database with the authentication still in the cookie. This is how Flickr approaches statelessness.

Tip #5: Test with cURL or rest-client

cURL makes it easy to execute any HTTP METHOD on a resource URL. You can pass request parameters and headers as well as inspect response headers and data. The command line tool ‘curl’ is standard on many *nix distros. Windows users should check out MinGW/MSYS which supports cURL. Even PHP has cURL functions which are enabled on most hosts (php/curl install page).

cURL Example Usage & Common Parameters:

# curl -X PUT http://www.foo.com/bar/1 -d "some=var" -d "other=var2" -H "Accept: text/json" -I

-X [METHOD] Specify the HTTP method.
-d “name=value” Set a POST/PUT field name and value.
-H [HEADER] Set a header.
-I Only display response’s headers.

Alternatively, a free GUI to test REST interfaces is Java/Swing based rest-client. rest-client is scriptable and has support for JSON/XML.

Tip #6 – Use a RESTful PHP Framework

Frankly, developers shouldn’t have to worry about many of these low-level details of REST when writing PHP apps. REST is based on conventions and conventions, by nature, involve a lot of boilerplate. This is right up a framework’s alley (as Rails has shown). What options exist for PHP? CodeIgniter’s routing completely ignores the HTTP METHOD so there is serious hacking that needs to be done. Cake has REST support but wasn’t designed to make specifying useful response status codes a part of the framework. Konstruct appears to have a very well thought out architecture for a controllers framework built around HTTP and REST. Unfortunately it is not easily approached and lacking (intentionally) many components, like an ORM layer, developers have come to expect in a modern web framework.

(Disclaimer: Shameless Plug!) The lack of a solid, RESTful PHP framework was one of my primary motivations for creating the Recess! Framework. Recess is a full-stack, open source (MIT), RESTful PHP framework. If you’re interested in writing RESTful PHP applications check it out and sign-up to be notified of its upcoming release.

Panel Discussion – Building in the Clouds: Scaling Web 2.0

Thursday, September 18th, 2008

Panel: Jason Hoffman (Joyent), Alistair Croll (Bitcurrent), Alex Barnett (From Bungee Labs to Intuit), Dwight Merriman (10Gen), Jinesh Varia (AWS), Pete Koomen (Google)

Panel session driven by Q&A.

Q) Decision between a component centric cloud and a service centric cloud? In a component centric I need to add instances to my app cluster (i.e. AWS), and in a service centric I write for a specific framework that scales itself (i.e. AppEngine). When does it make sense to focus on each?

A) Hoffman: I think they’ve already converged. It depends on the situation and you do both. The web app tiering has long been dead. You’re already silo’ing your assets. People are going to look at a given functionality in their site and ask what’s the service behind it?

Koomen: With App Engine it’s designed to handle low latency web applications.

Varia: Component clouds are great for flexibility. As the abstractions increase you lose flexibility and you also face lock-in on a technology stack.

Barnett: Scaling for what and why? How much up front consideration do start-ups need to put into becoming scalable? If you’ve only got a set of resources that isn’t infinite how do you face it? The nature and the type of the application will have fundamental implications to the underlying design.

Hoffman: Most web apps don’t have to scale in any reasonable amount of time. Another scaling issue is when you start out bigger and you don’t get enough traffic and have to scale down.

Q) Centralized computing & Distributed computing. Tension going on between centralized and distributed computing. Google has been buying thousands of net scalars and just this morning Amazon announced the cloud delivery service.

A) Merriman: Interesting fact that CDNs are one of the first forms of cloud computing. It’s an easy way to distribute content. Definitely use CDN for static.

Koomen: Scaling is about reducing the constant factor. Has to do with minimizing the amount of work you’re doing in the central server. Whether it’s in the CDN or the client side. It’s about a mentality of reducing what you’re doing on every request.

Hoffman: Amazon was smart about coming out with S3 before coming out with EC2. If you’re dealing with datasets less than a terabyte in size.

Varia: We have been listening a lot. From a scalability perspective many people needed data closer to their customers. Amazon is opening a CDN in 3 continents where the static data will be available from S3 with lower latencies and higher data transfer rates. Customers running RIAs feel it is key to serve content faster.

Q: How much can the edge help?

Hoffman: Outside of serving static content like images the edge doesn’t do anything.

Merriman: I don’t know that I agree with that because if you’re serving to data in Japan.

Hoffman: WAN optimization and network optimization is quite different than edge caching.

Q) How do you measure capacity and performance? What are the metrics you look at?

Kooman: Google cares a lot about CPU and latency. We can scale disk easy.

Hoffman: I think that’s the opposite end. There are things that take up space or move space. Disk space, CPU space, and network space. Then there’s the moving two and from these things. Most people in the real world are not coding against the CPU or CPU bound in a web app. Nobodies writing webapps that saturate the band that comes out of a single server. It takes a long time to fill up a terabyte. What people need is memory and better disk I/O. People still use relational databases. Disk I/O is the main thing.

Barnett: We also worry a lot about the end user experience. We’ve instrumented the AJAX library coming down to track every mouse click and interaction that an application has at a very granular level. You’re able to measure every click in a matter of milliseconds every single click and the latency on web service calls.
Hoffman: There doesn’t currently exist tooling to take end-user experience and feed that all the way back to capacity planning.

Merriman: We had to serve 10 – 20 billion ads per day. There’s a lot of CPU involved in picking which ads to serve. Other issue was just the database. “Have you seen this ad before? How many times?” Lots of data you access in real time and on the back-end on event processing. We looked at CPU a lot and I/O utilization on the database servers.

Varia: At Amazon, metrics is the key. From individual developer, to business, to our whole organization. From a developer we measure in time byte hours which is how much data that person is storing and how it grows. From S3 we measure the number of objects stored (22 billion objects stored) and the number of transactions. We peak at 50,000 transactions per second. We stay ahead of the curve. On the business side we need to understand our segmentation of large, medium, and small businesses.

Barnett: It’s interesting that when we charge for services on a utility model we

Koomen: We’re not going to be able to prevent people from taking out cloud services if they write bad code. So it’s important for us to be able to figure out where the problems exist and bubble that up to the user so they’re not making bad decisions.

Q: How do you guys deal with one rogue app?

Varia: Animoto is a very cool web 2.0 application where you upload your photos and music tracks in a way that it creates a really cool video out of it rendering your photos. They created a Facebook app they went from 25,000 users total, they went to adding 25,000 users every hour. Scaled from 50 servers to 5000 servers in 2 days. They were able to do this because they are built on a cloud platform. They scaled it down during the night time to save on cost. Some of these applications are bursting, no doubt. On an aggregate level the curve is pretty smooth. Amazon takes tremendous pride in figuring out how to add servers and services.

We have certain limits which prevent developers from starting 1000 instances. You are capped at 20 initially. If you want more you have to talk to us. There are security and safety mechanisms in place. If a business has a valid business case we’ll flip the switch.

Hoffman: If you have to spin up new virtual machines to handle traffic bursts you’re going to miss the burst.

Koomen: We deal with bursts like that by dealing with every request agnostically. To address the question from our side on what you do to prevent the users from exploiting a system. We’ve got quotas that measure what individual applications can consume and some knobs to turn.

Jason Fried Web 2.0 Keynote – Be a Software Curator

Wednesday, September 17th, 2008

How many of you are in software? You’re lucky. All you have to do is type. You don’t have to worry about physics. What you work on is easy to change. It’s not like you’re building a house. You can build software anywhere, in your house, in a plane, inside outside. Doesn’t matter you can build software. You’re lucky you can do all these things.

But you have to worry about some things that others don’t have to worry about. Take this water bottle, if it’s heavy I know it’s full. If it was twice as big and painted solid we could agree it was a terrible design. We can look at an object and know whether or not something has good or bad design just by looking at it. Software doesn’t have that kind of instant ‘a-ha’ nebulous feedback. It doesn’t have edges. It doesn’t cast shadows. It’s just there and often expands and continues to expand. That’s one of the really tough tricks of software development.

What would your software be like if it was physical? What would it be like if it was in your hand? Comfortable or spiky? Too big on one side and not on the other? Shiny or textured? On a table would it fall over or would it stick up? What would happen if it was a physical device. What would it look like if it was a car? Would it look like this?

The first version of software is pretty good. Version 2 and 3 pretty good. 4 and 5 might be the best. After that it devolves. This is the problem of saying yes to too many customers. You have to have discipline to keep your product simple, clean, elegant, and streamlined. You want to be the shepherd. Think of yourself as the editor, what goes in what goes out.

Think of yourself as a curator. You want to be a curator. You have to decide what comes in and what goes out. Curator’s job is to say no. Curator takes an entire universe of options to decide whether or not something makes it into a museum. If you think of your product as a museum and your features as art then you’re in charge. If you take all of the possible art and put it into a room it doesn’t make it a museum. All the art in the world in a single room isn’t a museum it’s a warehouse.

Listen to your customers but innovate on behalf of your entire customer base. As time goes on certain customers become more and more vocal. Be very careful about agreeing to everything the vocal minority says. Customers know a lot about what they want but not about what’s best for your product. If you listen to just a few people you’re going to have a problem. This is why you have to think of yourself as a curator.

As software goes on you trend towards bloat. Bloat is a tricky thing to find. Software doesn’t have a form so it’s hard to figure it out. Once you hit bloat, though, it’s really hard to go back. Once you hit the point where it’s too hard to go back they’ll start over. It’s dangerous.

Keep an eye out for bloat and these feature requests. Listen to customers but don’t do everything they say. Make your software a collection of art. Not a warehouse. When 37Signals built their second product called HighRise they would build this incredibly successful sophomore follow up. Thought about all the possible things they could do with a CRM. Two months in they were just doing it all and it turned out to be pretty shitty. Adding more and adding more without being critical of what went in along the way. They had to throw it out and start over.

Don’t get into the bad habit of saying yes to requests. It’s hard to change expectations. Customers will request a feature and tell you they want one thing but not what they really need. They want a way to collaborate on comments on a to-do list but they don’t know how to enunciate what they’re actually after. When 37Signals was building campfire for all of these things campfire could actually do. It could possibly have video conferencing, possibly have audio capabilities. What they actually ultimately needed was much, much simpler.

When you get all these ideas that your customers have you have to say more than you say yes. Your software has to be a curated collection of ideas, a curated collection of features.

Question: What’s the best way to turn down a feature bloat from within a company?

Answer: Just ask the person who asked for it to build it. I’m not going to build that shit. Build it yourself.

Question: How would you redesign office?

Answer: Office is fine. Modern office isn’t about spreadsheets and word processors anymore. It’s about collaboration. Make it more collaborative.

Question: Who should be the chief curator?

Answer: Everyone has to have that in them. The DNA of your company has to be about curation. It ultimately has to come from the top. Steve Jobs is probably the ultimate curator in the world.

[ Follow the Feed for notes on talks from other web leaders & innovators at the Web 2.0 Expo in New York going on this week. ]

Fred Wilson – New York’s Web Industry from 95 to 08

Wednesday, September 17th, 2008

1995 – 30 seed and early stage tech deals in NYC, 230 in Silicon Valley. In 2008 the numbers are more like 116 in NYC and 360 in San Francisco. From 1/8th to 1/3rd.

Let’s bury the name Silicon Alley and call ourselves Broadway or New York. It’s not an alley. It all started when Red Burns opens the ITP @ NYU in 1979. In 1989 Connect Times wrote about the launch of AOL. In 91 ZDNet was formed to bring Ziff-Davis media on-line. In 93 some New York dial-up companies were started. Jupiter started throwing conferences. New York was the center of the events business regarding the internet. Prodigy was in New York in 93. Total NY, Razorfish, and Pseudo were started up in 94. Silicon Alley came about in this time. TimeWarner launched PathFinder, iGuide launched in 94, both failed and were gone by end of 90s. Created a technology oriented building out of a failed investment bank in 95. Seth Godin started permission marketing. Interactive agencies started getting real business in 95. Silicon Alley Reporter Radio Show in 1997.

Razorfish bought 4 companies in 1997 and agencies started buying everything they could. Kozmo.com was started in 1998, Fred Wilson invested in it, everyone in New York loved it at the time. Kids ask to this day “why is it not around?” 1998 was the last year of sanity in the first internet wave. In 99 the big offline companies finally wanted to come on-line. Hell broke loose in 1999. The party everyone remembers is the one Josh threw for the month of December. Jason Calacanis advice to HBS students in 99 “take whatever money you have left that you haven’t given Harvard, leave school tomorrow, start an internet company.”

2001 was difficult: layoffs, bankruptcies, etc. Rock bottom was 2002. Doubleclick’s “welcome to silicon alley” was removed. Calacanis moved to California. It was bad. In 2003 Fred launched ABC. Tim and John coined Web 2.0. In 2003 Schachter turned on an IBM PC and started Delicious out here in New York. Union Square Ventures raised 125 million in 2004 and has since been invested in NYC start-ups. Etsy was launched in NY. Delicious was sold to Yahoo and people could see it was. Google came in 2006 and took over Port Authority. Largest operation they have outside of the Valley. Sergey just bought an apartment in the West Village. We’re finally making money.

In 2007 there was lots of startup activity in the Alley. Buddy Media, TargetSpot, Path101, Tumblr.

Today: Here we are and Web 2.0 Expo has come to NY City. What happens in NYC is more creative, more connected, different from the other startups. There might come a time when New York is 70 to 80 percent of the Valley.