<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
	<channel>
		<title>Kris Jordan Blog</title>
		<link>http://krisjordan.com/</link>
		<description />
		<language>en-us</language>
		<copyright>Copyright Kris Jordan.</copyright>
		<lastBuildDate>Wed, 31 Dec 1969 19:00:00 -0500</lastBuildDate>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<generator>HiFi</generator>
		<managingEditor>krisjordan@gmail.com</managingEditor>
		<webMaster>krisjordan@gmail.com</webMaster>
				<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/KrisJordan" /><feedburner:info uri="krisjordan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
			<title>Micro PHP's Missing Tenet</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/bXK1W3JqEiI/micro-php-manifesto</link>
			<description>&lt;p&gt;Ed Finkler's &lt;a href="http://funkatron.com/posts/the-microphp-manifesto.html"&gt;post&lt;/a&gt; on "MicroPHP Manifesto" made the the rounds last week. It expresses a widely felt desire lurking in the minds of PHP developers. Especially those who have spent time working with libraries from the &lt;a href="http://nodejs.org"&gt;Node.js&lt;/a&gt; or &lt;a href="http://clojure.org"&gt;clojure&lt;/a&gt; communities. While the manifesto did a good job covering motivations and aspirations, it missed a key tenet of "micro", and stopped short of covering a few key practical opportunities and obstacles with PHP.&lt;/p&gt;
&lt;h2&gt;"I believe functions are the smallest unit of functionality"&lt;/h2&gt;
&lt;p&gt;The missing tenet from the Micro PHP Manifesto is: &lt;strong&gt;I believe functions are the smallest unit of functionality&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Not classes. Not methods. &lt;em&gt;Functions&lt;/em&gt;. This belief fits in naturally with, and is a precursor to, most every other tenet of the manifesto.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"I like building small things with simple purposes."&lt;/em&gt; There is no smaller or simpler reusable unit of functionality than a function.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"I like building small things that work together to solve larger problems."&lt;/em&gt; Functions and their higher-order friends compose with mathematical simplicity and beauty.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"I want code that is easily verifiable."&lt;/em&gt; Pure functions are the easiest unit of functionality to test.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"I need to justify every piece of code I add to a project."&lt;/em&gt; Do we &lt;em&gt;really&lt;/em&gt; need to subclass &lt;code&gt;Controller&lt;/code&gt; to add a route to our app? Nope, not if you're using &lt;a href="http://www.slimframework.com/"&gt;Slim&lt;/a&gt;, a great HTTP micro framework (full disclosure [&lt;a href="#footnote-1"&gt;1&lt;/a&gt;], my office mate wrote it). An anonymous function will do just fine, thank you. Senseless subclassing is what got us into this mess to begin with!&amp;#160;[&lt;a href="#footnote-2"&gt;2&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;When the traditional PHP framework programmer&amp;#160;looks at a problem, he asks himself these questions, in order of preference:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Can I add a method to an existing class?&lt;/li&gt;
&lt;li&gt;Can I add a subclass and override a method?&lt;/li&gt;
&lt;li&gt;Or should I start a new base class?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When the Micro PHP framework programmer looks at a problem, she asks herself these questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Can I use an anonymous function?&lt;/li&gt;
&lt;li&gt;Can I use a named function?&lt;/li&gt;
&lt;li&gt;Can I add a method to an existing class?&lt;/li&gt;
&lt;li&gt;Can I add a subclass and override a method?&lt;/li&gt;
&lt;li&gt;Or should I start a new base class?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Namespaced functions and function values being legitimate options in 5.3 enables lighter weight libraries that play together nicely. Combined with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; pushing web developers' collective comfort with a more functional style of programming, the micro PHP movement is in a great position to take off.&lt;/p&gt;
&lt;p&gt;But, for the love of &lt;a href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf"&gt;Rasmus&lt;/a&gt;, PHP has avoided solving two fundamental problems that would radically inspire even smaller, even simpler, even more single-purposed, micro PHP libraries.&lt;/p&gt;
&lt;h2&gt;&lt;em&gt;Damnit PHP&lt;/em&gt;, why can't you just...&lt;/h2&gt;
&lt;h3&gt;1. Allow functions to be imported like classes&lt;/h3&gt;
&lt;p&gt;User defined functions are second rate compared to user defined classes in the PHP language. You can &lt;a href="http://www.php.net/manual/en/language.namespaces.importing.php"&gt;import classes&lt;/a&gt; from namespaces but you &lt;a href="http://www.php.net/manual/en/language.namespaces.faq.php#language.namespaces.faq.nofuncconstantuse"&gt;can't import functions&lt;/a&gt;. Read that again. You can import namespaced classes but not namespaced functions. PHP itself doesn't fully believe that "functions are the smallest unit of functionality". Oh, sweet irony. Most of PHP's &lt;a href="http://www.php.net/manual/en/funcref.php"&gt;core functionality&lt;/a&gt; (even &lt;a href="http://www.php.net/manual/en/ref.array.php"&gt;array manipulation&lt;/a&gt;!) is exposed as functions (in a global namespace).&lt;/p&gt;
&lt;p&gt;PHP discourages writing plain old functions by making them more painful to reuse than classes. Currently, the best way to write useable "plain old functions" is to write methods on a class you'll only ever invoke statically (i.e., &lt;a href="http://brianhaveri.github.com/Underscore.php/"&gt;underscore.php&lt;/a&gt;'s &lt;code&gt;__::each&lt;/code&gt;). If PHP respected functions they wouldn't need to be wrapped in bastardized classes to be useful.&lt;/p&gt;
&lt;h3&gt;2. Indoctrinate a symbol loading algorithm&lt;/h3&gt;
&lt;p&gt;So it isn't possible to import namespaced functions directly. But it gets worse. Even using what is available (&lt;code&gt;use namespace; namespace\func();&lt;/code&gt;), if the function has not yet been defined, there is no way to autoload that function's source like PHP will do for classes. But it gets worse. The &lt;a href="http://us3.php.net/manual/en/function.spl-autoload-register.php"&gt;class loading algorithm&lt;/a&gt; is user defined. This is another historical impediment to "micro" component compatibility in PHP, because every framework has its own class loader [&lt;a href="#footnote-3"&gt;3&lt;/a&gt;]. There is hope in PSR-0, but it won't ship with 5.4.&lt;/p&gt;
&lt;p&gt;PHP needs to plant a hard foot in the ground and indoctrinate &lt;strong&gt;one&lt;/strong&gt; built-in, automatic symbol loading algorithm that will load classes &lt;em&gt;and&lt;/em&gt; functions &lt;em&gt;and&lt;/em&gt; constants. The chaos has gone on long enough. If &lt;a href="http://docs.python.org/tutorial/modules.html#packages"&gt;Python&lt;/a&gt; and &lt;a href="http://nodejs.org/docs/v0.4.8/api/modules.html#loading_from_node_modules_Folders"&gt;node.js&lt;/a&gt; can be bold enough to do it, so can PHP. The flexibility has stunted our growth.&lt;/p&gt;
&lt;p&gt;Please, if you are listening PHP Core Team, for the love of the &lt;a href="http://farm3.staticflickr.com/2009/2218075860_b78fd33f83_z.jpg?zz=1"&gt;fat blue elephant&lt;/a&gt; in the room, do whatever it takes and break whatever you need to get these fundamental language utilities in the next major point release. Or even the mythical 6.0. The temporary pain will be worth the massive, revitalizing shock it will give to a community of PHP developers who would like to share components and code in a simple and standard way.&lt;/p&gt;
&lt;h2&gt;How should micro libraries share plain functions until PHP fixes importing and symbol loading?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Step 1. Use a PSR-0 class loader&lt;/strong&gt; There are plenty. The &lt;a href="http://symfony.com/doc/2.0/components/class_loader.html"&gt;Symfony2 ClassLoader&lt;/a&gt;'s is good and PSR-0 compliant. It's MIT. Potencier writes great code. Use it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2. Write plain-old functions as static methods on a bastard, wrapper class.&lt;/strong&gt; Ugh. Step 2 is the worst, but distributing plain-old functions puts consumers back in &lt;code&gt;require_once&lt;/code&gt; hell. If all you are trying to write and share are plain-old functions, use static methods.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3. Write to your local PHP Core politician.&lt;/strong&gt; Demand importable functions and a native, standard symbol loader for PHP.next. Support this PHP &lt;a href="https://wiki.php.net/rfc/autofunc"&gt;RFC for function autoloading&lt;/a&gt;, and this one for &lt;a href="https://wiki.php.net/rfc/splclassloader"&gt;PSR-0 inclusion&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Finally, will an &lt;a href="http://blog.izs.me/"&gt;isaacs&lt;/a&gt; please step up? PHP needs a &lt;a href="http://npmjs.org/"&gt;modern package manager&lt;/a&gt;.&lt;/h2&gt;
&lt;p&gt;If someone really wants to blow oxygen on the Micro PHP fire they should start with a new package manager for PHP. PEAR is far too &lt;a href="http://pear.php.net/manual/en/newmaint.proposal.php"&gt;bureaucratic&lt;/a&gt; and, frankly, &lt;a href="http://pear.php.net/categories/"&gt;embarrassing&lt;/a&gt; in the face of a modern package manager like node.js's &lt;a href="http://npmjs.org/"&gt;npm&lt;/a&gt;. PEAR has been around since before PHP5's release in 2004 and there are 179 modules hosted at pear.php.net for 5.0+. (And only 19 for poor &lt;a href="http://pear2.php.net/categories/"&gt;PEAR2&lt;/a&gt; and PHP 5.3) Contrast with &lt;a href="http://search.npmjs.org/"&gt;npm&lt;/a&gt; which has been around since August 2010 and hosts 6,157 packages.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;npm&lt;/strong&gt; hosts over 30 times more packages than &lt;strong&gt;PEAR&lt;/strong&gt;!?!&lt;/em&gt; How? You don't have to pass a &lt;a href="http://pear.php.net/manual/en/newmaint.proposal.php"&gt;bureaucratic, written proposal process&lt;/a&gt; to publish to npm. Anyone can publish any package they want &lt;a href="http://npmjs.org/doc/developers.html"&gt;in under 10 minutes&lt;/a&gt;. So do all npm packages have the high quality of PEAR packages? No. Do they all follow the same coding standards like PEAR packages? No. Are these real problems to fear in practice? No. The best packages are naturally high quality and obtain the most attention and dependencies. PEAR is selection by committee, npm is natural selection. The Micro PHP movement really needs a package manager with fewer, smaller rules for publishing and sharing. PEAR may be for sharing small packages with simple purposes, but it is certainly &lt;a href="http://pear.php.net/manual/en/newmaint.proposal.php"&gt;not Micro PHP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(Update: some promising movements in this direction are &lt;a href="http://packagist.org/"&gt;Packagist&lt;/a&gt; and &lt;a href="https://github.com/lox/phark"&gt;Phark&lt;/a&gt;.)&lt;/p&gt;
&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;Functions are the smallest unit of functionality. This is a key missing tenet of the Micro PHP Manifesto. It's a practical precursor to many of &lt;a href="http://funkatron.com/posts/the-microphp-manifesto.html"&gt;the others&lt;/a&gt;. This isn't to say object-oriented libraries and designs don't have their place in PHP, they most certainly do, but that if you can solve your design problem with functions, choose functions. Prefer small, simple functions over complex, stateful class hierarchies.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;p&gt;[&lt;a name="footnote-1"&gt;&lt;/a&gt;1] Even fuller disclosure: I've written a "Full Stack" PHP Framework. A lot of what Ed said is wrong with Zend and Symfony was wrong with &lt;a href="htt://recessframework.org"&gt;Recess&lt;/a&gt;, which I wrote three years ago. It's intention was to be light weight. In terms of CLOC, it was, under 10k for a RESTful HTTP layer, ORM, "Views", &amp;amp; Annotations. In terms of code written by end-users, it was, comparatively, too. Recess was the first PHP framework to use &lt;a href="http://www.recessframework.org/page/clean-urls-with-route-annotations"&gt;Annotations&lt;/a&gt;. Declarative-style programming requires less code. I don't use it for new projects anymore. It's still too heavy. It's not line counts or ugly code, though. It caries the PHP 5.2 OOP-only baggage, too [2].&lt;/p&gt;
&lt;p&gt;[&lt;a name="footnote-2"&gt;&lt;/a&gt;2] Ed's post stops short of tracing the legacy leading to the current state of popular frameworks being un-micro. Here's the story. When all you know are objects...all you see are classes. And methods. And private variables. And design patterns. And Java. When all you know is Java all you see is Java.&lt;/p&gt;
&lt;p&gt;PHP did not become be one of the &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;most popular kids&lt;/a&gt; in school without having a "hey look, me too" mindset. PHP grew its popularity in the early 2000s by copying everything it could from Java's object model in the move from PHP4 to PHP5. From &lt;a href="http://www.php.net/manual/en/language.oop5.visibility.php"&gt;visibility&lt;/a&gt; controls to &lt;a href="http://us3.php.net/manual/en/book.reflection.php"&gt;reflection&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When your language is inspired by Java, your libraries and frameworks will be too. You can't look at &lt;a href="http://www.recessframework.org/page/clean-urls-with-route-annotations"&gt;Recess' annotations&lt;/a&gt; without smelling &lt;a href="https://src.springframework.org/svn/spring-samples/mvc-basic/trunk/src/main/java/org/springframework/samples/mvc/basic/account/AccountController.java"&gt;Java&lt;/a&gt;. You can't look at &lt;a href="http://www.doctrine-project.org/"&gt;Doctrine&lt;/a&gt; without smelling &lt;a href="http://www.hibernate.org/"&gt;Java&lt;/a&gt;. You can't look at &lt;a href="https://github.com/symfony/DependencyInjection"&gt;Symfony components&lt;/a&gt; without smelling &lt;a href="http://static.springsource.org/spring/docs/2.5.x/reference/beans.html"&gt;Java&lt;/a&gt;. This isn't to say Symfony is &lt;em&gt;bad&lt;/em&gt;, it's not. It's really damned good, but it's manifesto is different. It's manifesto was written by a &lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_(book)"&gt;Gang of Four&lt;/a&gt;. It's lineage predates PHP 5.3. Popular frameworks and libraries originating before PHP 5.3's release carry the burden of pursuing &lt;a href="http://symfony.com/doc/current/cookbook/service_container/factories.html"&gt;best practice object-oriented patterns&lt;/a&gt; at the cost of ignoring perfect opportunities where standalone or anonymous functions would suffice.&lt;/p&gt;
&lt;p&gt;[&lt;a name="footnote-3"&gt;&lt;/a&gt;3] PEAR/Zend-style &lt;a href="http://framework.zend.com/manual/en/coding-standard.naming-conventions.html"&gt;class naming&lt;/a&gt; and directory structuring became somewhat of a norm before 5.3, but it sucked. &lt;em&gt;Class names&lt;/em&gt; were combined with &lt;em&gt;namespaces&lt;/em&gt; which lead to instantiating classes with names like &lt;a href="http://framework.zend.com/manual/en/zend.db.table.definition.html"&gt;&lt;code&gt;Zend_Db_Table_Definition&lt;/code&gt;&lt;/a&gt;. Only in recent history, since 5.3 namespaces, has the community embraced a "standard" class loading algorithm with &lt;a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md"&gt;PSR-0&lt;/a&gt;. (Design by committee retained PEAR-style support, which is unfortunate, but I digress.) In theory this will make its way into the Standard PHP Library and be bundled with PHP, which will be great.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=bXK1W3JqEiI:Edu5niSJO0g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=bXK1W3JqEiI:Edu5niSJO0g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=bXK1W3JqEiI:Edu5niSJO0g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=bXK1W3JqEiI:Edu5niSJO0g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=bXK1W3JqEiI:Edu5niSJO0g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Tue, 10 Jan 2012 01:52:07 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/micro-php-manifesto</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/micro-php-manifesto</feedburner:origLink></item>
				<item>
			<title>multimethod.js</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/FlzqM1Md87M/multimethod-js</link>
			<description>&lt;h2&gt;What is a multimethod?&lt;/h2&gt;
&lt;p&gt;The quickest way to understand is by looking at a simple, familiar example implemented with a multimethod. So let's write a recursive Fibonacci function.&lt;/p&gt;
&lt;pre&gt;&amp;gt; var fib = multimethod()
                .when( 0, 0 )
                .when( 1, 1 )
                .default( function(n) {
                    return fib(n-1) + fib(n-2);
                });
&amp;gt; fib(20);
6765&lt;/pre&gt;
&lt;p&gt;Multimethods are a functional programming "control structure" enabling you to dynamically build-up and manipulate the dispatching behavior of a polymorphic function. Inspired by &lt;a href="http://clojure.org/multimethods"&gt;Clojure's multimethods&lt;/a&gt;, multimethod.js provides a functional alternative to classical, prototype based polymorphism. The multimethod.js library is MIT licensed, is found on &lt;a href="https://github.com/KrisJordan/multimethod-js"&gt;GitHub&lt;/a&gt;&amp;#160;and &lt;a href="http://search.npmjs.org/#/multimethod"&gt;npm&lt;/a&gt; with &lt;code&gt;npm install multimethod&lt;/code&gt;, and its&amp;#160;annotated source code&amp;#160;is &lt;a href="http://files.krisjordan.com/multimethod-js/multimethod.html"&gt;available here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Motivating Examples&lt;/h2&gt;
&lt;p&gt;Let's use the node.js REPL to build a few multimethods and see what they are capable of doing. In this first example we'll create a mulimethod that calculates the area of shapes instantiated with object literals.&lt;/p&gt;
&lt;pre&gt;&amp;gt; var multimethod = require('multimethod');
&amp;gt; var area = multimethod()
                .dispatch(function(o) {
                    return o.shape;
                })
                .when("square", function(o) {
                    return Math.pow(o.side, 2);
                });
&amp;gt; var aSquare = { "shape":"square", "side": 2 };
&amp;gt; area( aSquare );
4

&amp;gt; var aCircle = { "shape":"circle", "radius": 5 };
&amp;gt; area( aCircle );
undefined

&amp;gt; area.default(function(o) { 
    throw "Unknown shape: " + o.shape;
  });
&amp;gt; area( aCircle );
Unknown Shape: circle

&amp;gt; area.when("circle", function(o) {
    return Math.PI * Math.pow(o.radius, 2);
  });
&amp;gt; area( aCircle );
78.53981633974483
&amp;gt; area( aSquare );
4

&amp;gt; area.remove("circle");
&amp;gt; area( aCircle );
Unknown Shape: circle
&lt;/pre&gt;
&lt;p&gt;Notice how &lt;code&gt;dispatch&lt;/code&gt; returns the value we'll match to a "method" registered with &lt;code&gt;when&lt;/code&gt;. You can introduce, overwrite, and remove new methods dynamically at runtime. Fallback behavior can be established with a &lt;code&gt;default&lt;/code&gt; function called when no methods match the dispatched value.&lt;/p&gt;
&lt;pre&gt;&amp;gt; var hitPoints = multimethod()
                    .dispatch(function(player){ return player.powerUp; })
                    .when( {"type":"star"} , Infinity)
                    .default(5);

&amp;gt; var starPower = { "type":"star" },
&amp;gt;     mario = { "powerUp": starPower };
&amp;gt; hitPoints(mario);
Infinity

&amp;gt; mario.powerUp = null;
&amp;gt; hitPoints(mario);
5

&amp;gt; var godModeCheat = function() { return starPower; };
&amp;gt; hitPoints.dispatch(godModeCheat);
&amp;gt; mario.powerUp;
null
&amp;gt; hitPoints(mario);
Infinity
&lt;/pre&gt;
&lt;p&gt;In this last example notice how we are matching against an object. Matching is done using deep equality so objects and arrays are valid method matching criteria. Also notice how we can completely override our dispatch function to change the logic with which a multimethod evaluates its arguments for dispatch, or, in this case, ignores them!&lt;/p&gt;
&lt;h2&gt;Multimethod Dispatch Algorithm&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;User calls multimethod with argument &lt;code&gt;anArgument&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Multimethod calls its &lt;code&gt;dispatch&lt;/code&gt; function with &lt;code&gt;anArgument&lt;/code&gt;. The returned value is stored in &lt;code&gt;dispatchValue&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Multimethod iterates through each 'method' registered with &lt;code&gt;when&lt;/code&gt; and performs an equality test on the &lt;code&gt;dispatchValue&lt;/code&gt; and each method's match value. If a match is found, set &lt;code&gt;matchFunction&lt;/code&gt; to the method's function and go to step 5.&lt;/li&gt;
&lt;li&gt;If no method match found, set &lt;code&gt;matchFunction&lt;/code&gt; to the multimethod's &lt;code&gt;default&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;Multimethod calls &lt;code&gt;matchFunction&lt;/code&gt; with &lt;code&gt;anArgument&lt;/code&gt;. The returned value is returned to the user who called the multimethod.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;A More Detailed Walkthrough&lt;/h2&gt;
&lt;h3&gt;The Basics&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;multimethod&lt;/code&gt; is instantiated with the &lt;code&gt;multimethod&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;var stopLightColor = multimethod();
&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;multimethod&lt;/code&gt; has methods. A &lt;code&gt;method&lt;/code&gt; is has two parts, its match value and its implementation function. Methods are added using &lt;code&gt;when&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;stopLightColor.when("go",    function() { return "green"; })
              .when("stop",  function() { return "red"; });
&lt;/pre&gt;
&lt;p&gt;You can call a &lt;code&gt;multimethod&lt;/code&gt; just like any other function. It will dispatch based on the argument(s) passed in, invoke the matched &lt;code&gt;method&lt;/code&gt;, and return the results of the &lt;code&gt;method&lt;/code&gt; call.&lt;/p&gt;
&lt;pre&gt;console.log( stopLightColor("go") ); // "green"
&lt;/pre&gt;
&lt;p&gt;When no method matches control can fallback to a &lt;code&gt;default&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;stopLightColor.default( function() { return "unknown"; } );
console.log( stopLightColor("yield") ); // prints "unknown"
&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;multimethod&lt;/code&gt; can handle new cases dynamically at run time.&lt;/p&gt;
&lt;pre&gt;stopLightColor.when("yield", function() { return "yellow"; });
&lt;/pre&gt;
&lt;p&gt;There is a shorter way for a &lt;code&gt;method&lt;/code&gt; to return a plain value. Rather than passing an implementation function to &lt;code&gt;when&lt;/code&gt;, pass the value.&lt;/p&gt;
&lt;pre&gt;stopLightColor.when("yield", "yellow");
console.log( stopLightColor("yield") ); // prints "yellow"
&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;method&lt;/code&gt; can be removed dynamically at run time, too.&lt;/p&gt;
&lt;pre&gt;stopLightColor.remove("go");
console.log( stopLightColor("go") ); // prints "unknown"
&lt;/pre&gt;
&lt;h3&gt;Dispatch Function&lt;/h3&gt;
&lt;p&gt;Each &lt;code&gt;multimethod&lt;/code&gt; call first invokes a &lt;code&gt;dispatch&lt;/code&gt; function whose return value is used to match the correct &lt;code&gt;method&lt;/code&gt; to call. The &lt;code&gt;dispatch&lt;/code&gt; function is passed the arguments the &lt;code&gt;multimethod&lt;/code&gt; is invoked with and returns a value to match against.&lt;/p&gt;
&lt;p&gt;The default &lt;code&gt;dispatch&lt;/code&gt; function is an identity function. The basic &lt;code&gt;stopLightColor&lt;/code&gt; examples could have been created with an explicit &lt;code&gt;dispatch&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;var stopLightColor = multimethod()
      .dispatch(function(state){
         return state;
      })
      .when('go', 'green');
console.log( stopLightColor('go') ); // green
&lt;/pre&gt;
&lt;p&gt;The power of the &lt;code&gt;multimethod&lt;/code&gt; paradigm is the ability to dispatch with a user-defined function. This gives a &lt;code&gt;multimethod&lt;/code&gt; its "polymorphic" powers. Unlike classical, object-oriented polymorphism where the compiler dispatches based on the type hierarchy, a &lt;code&gt;multimethod&lt;/code&gt; can dispatch on any criteria.&lt;/p&gt;
&lt;pre&gt;var contacts = [
  {"name":"Jack", "service":"Twitter","handle": "@jack"},
  {"name":"Diane","service":"Email",  "address":"d@g.com"},
  {"name":"John", "service":"Phone",  "number": "919-919-9191"}
];

var sendMessage = multimethod()
     .dispatch(function(contact, msg) {
       return contact.service;
     })
     .when("Twitter", function(contact, msg) {
       console.log("Tweet @"+contact.handle+":"+msg);
     })
     .when("Email", function(contact, msg) {
       console.log("Emailing "+contact.address+":"+msg);
     })
     .default(function(contact, msg) {
       console.log("Could not message " + contact.name);
     });

// Blast a message
contacts.forEach( function(contact) {
  sendMessage(contact, "Hello, world."); 
});
&lt;/pre&gt;
&lt;p&gt;Plucking a single property from an object is so commonly used as a &lt;code&gt;dispatch&lt;/code&gt; function, like in the example above, there is a shortcut for this pattern. The following &lt;code&gt;dispatch&lt;/code&gt; call is equivalent to above.&lt;/p&gt;
&lt;pre&gt;sendMessage.dispatch( 'service' );
&lt;/pre&gt;
&lt;p&gt;A &lt;code&gt;multimethod&lt;/code&gt;'s &lt;code&gt;dispatch&lt;/code&gt; is usually specified when constructed.&lt;/p&gt;
&lt;pre&gt;var sendMessage = multimethod('service');
&lt;/pre&gt;
&lt;p&gt;Just like &lt;code&gt;method&lt;/code&gt;s can be added and removed from a &lt;code&gt;multimethod&lt;/code&gt; at run time, the &lt;code&gt;dispatch&lt;/code&gt; function can also be redefined at run time. Ponder the implications of that for a minute. It is really powerful and really dangerous. Don't shoot your eye out.&lt;/p&gt;
&lt;h3&gt;Deep Equality Matching&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;method&lt;/code&gt;'s match value is compared to &lt;code&gt;dispatch&lt;/code&gt;'s return value using the underscore.js &lt;a href="http://documentcloud.github.com/underscore/#isEqual"&gt;&lt;code&gt;isEqual&lt;/code&gt;&lt;/a&gt; function. Deep equality &lt;code&gt;method&lt;/code&gt; matching enables concise expressivity. Contrast this with a traditional &lt;code&gt;switch&lt;/code&gt; statement that is limited by JavaScript's === equality behavior.&lt;/p&gt;
&lt;pre&gt;var greatPairs = multimethod()
      .when( ["Salt", "Pepper"], "Shakers" )
      .when( [{"name":"Bonnie"}, {"name":"Clyde"}], "Robbers" );
console.log( greatPairs( ["Salt", "Pepper"] ) ); // Shakers
&lt;/pre&gt;
&lt;h2&gt;API Recap&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Constructor: &lt;code&gt;multimethod&lt;/code&gt;( [fn | string] ): No arg constructor uses an identity function for &lt;code&gt;dispatch&lt;/code&gt;. Single arg constructor is a shortcut for calling &lt;code&gt;dispatch&lt;/code&gt; with the same argument.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dispatch&lt;/code&gt;(fn | string): Sets the &lt;code&gt;multimethod&lt;/code&gt;'s &lt;code&gt;dispatch&lt;/code&gt; function. String values are transformed into a pluck function which projects a single property value from the first argurment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;when&lt;/code&gt;(match, fn | value): Add a &lt;code&gt;method&lt;/code&gt; to be invoked when the &lt;code&gt;dispatch&lt;/code&gt; return value matches 'match'. If a non-function &lt;code&gt;value&lt;/code&gt; is provided it will be returned directly. Calling &lt;code&gt;when&lt;/code&gt; with the same &lt;code&gt;match&lt;/code&gt; value twice will override the previously registered &lt;code&gt;method&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;remove&lt;/code&gt;(match): Remove a &lt;code&gt;method&lt;/code&gt; by it's &lt;code&gt;match&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default&lt;/code&gt;(fn | value): Catch-all case when no &lt;code&gt;method&lt;/code&gt; match is found.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Install with &lt;code&gt;npm&lt;/code&gt; for use in node.js based projects.&lt;/p&gt;
&lt;pre&gt;npm install multimethod
node
&amp;gt; var multimethod = require('multimethod');
&lt;/pre&gt;
&lt;p&gt;For in-browser use you will need to grab &lt;a href="http://documentcloud.github.com/underscore/"&gt;underscore.js&lt;/a&gt; and multimethod.js:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;underscore.js
&lt;ul&gt;
&lt;li&gt;Development: &lt;a href="http://documentcloud.github.com/underscore/underscore.js"&gt;http://documentcloud.github.com/underscore/underscore.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Minified: &lt;a href="http://documentcloud.github.com/underscore/underscore-min.js"&gt;http://documentcloud.github.com/underscore/underscore-min.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;multimethod.js
&lt;ul&gt;
&lt;li&gt;Development: &lt;a href="https://raw.github.com/KrisJordan/multimethod-js/master/multimethod.js"&gt;https://raw.github.com/KrisJordan/multimethod-js/master/multimethod.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Minified: &lt;a href="https://raw.github.com/KrisJordan/multimethod-js/master/multimethod-min.js"&gt;https://raw.github.com/KrisJordan/multimethod-js/master/multimethod-min.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How-to Contribute&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Submit bugs and feature requests on &lt;a href="https://github.com/KrisJordan/multimethod-js/issues"&gt;GitHub Issues&lt;/a&gt; page.&lt;/li&gt;
&lt;li&gt;Fork the repository and submit pull requests. Pull requests that update the test suite for coverage on changes will be brought in quickly.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=FlzqM1Md87M:JdN2vRkkvlo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=FlzqM1Md87M:JdN2vRkkvlo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=FlzqM1Md87M:JdN2vRkkvlo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=FlzqM1Md87M:JdN2vRkkvlo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=FlzqM1Md87M:JdN2vRkkvlo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 15 Dec 2011 17:40:00 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/multimethod-js</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/multimethod-js</feedburner:origLink></item>
				<item>
			<title>Fixing WebKit's Accept Header</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/_pCpD-I2ILs/fixing-webkits-accept-header-to-support-content-negotiation-and-rest</link>
			<description>&lt;p&gt;WebKit has been on the forefront of web browser innovation for years, but their HTTP Accept header has lagged behind. (tl;dr &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267"&gt;it is fixed now&lt;/a&gt;.) The Accept header is how the web browser says to the web server "these are the content-types I can understand and the order in which I prefer them." For more detail, wrote about it in more detail on the &lt;a href="http://www.gethifi.com/blog/browser-rest-http-accept-headers"&gt;HiFi CMS Blog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;Accept header&lt;/a&gt; allows a single object or&amp;nbsp;&lt;em&gt;resource&lt;/em&gt; to have a single URI with multiple &lt;em&gt;representations&lt;/em&gt;, such as HTML, XML, or JSON. It is a fundamental component of the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"&gt;HTTP spec&lt;/a&gt; and REST style web services. Unfortunately, today's web services rarely use content-negotiation, because browsers have historically chosen bad Accept headers. &lt;a href="http://www.webkit.org/"&gt;WebKit&lt;/a&gt;'s&amp;nbsp;was the last serious offender:&lt;/p&gt;
&lt;pre&gt;application/xml,
application/xhtml+xml,
text/html;q=0.9,
text/plain;q=0.8,
image/png,
*/*;q=0.5       &lt;/pre&gt;
&lt;p&gt;Parsed and prioritized:&lt;/p&gt;
&lt;pre&gt;1. application/xml
2. application/xhtml+xml
3. image/png
4. text/html
5. text/plain
6. */*
&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://www.gethifi.com/blog/browser-rest-http-accept-headers"&gt;WebKit's Accept header preferred XML over HTML&lt;/a&gt;&amp;nbsp;prior to&amp;nbsp;my fix &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267"&gt;landing in trunk today&lt;/a&gt;. Web services could not offer both HTML and XML for a single resource and use content negotiation because WebKit based browsers (Safari, Chrome, et. al.) would be served the XML data not the HTML web page. Developers have had to hack around the issue. &lt;a href="http://apiwiki.twitter.com/w/page/22554648/FrontPage"&gt;Twitter's API&lt;/a&gt;, for example, uses a common work around that changes the URI by&amp;nbsp;&lt;a href="http://dev.twitter.com/doc/get/statuses/friends_timeline"&gt;appending a format extension&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;http://api.twitter.com/&lt;em&gt;version&lt;/em&gt;/statuses/friends_timeline.&lt;em&gt;format&lt;/em&gt;
format ::= json | xml | rss | atom&lt;/pre&gt;
&lt;p&gt;The goal of the fix for WebKit's Accept header was straightforward: prefer HTML over XML. The ultimate solution was to minimize risk and take Firefox's lead. Here is the Accept header, already in order of preference, WebKit-based browsers will be using in the future:&lt;/p&gt;
&lt;pre&gt;text/html,
application/xhtml+xml,
application/xml;q=0.9,
*.*;q=0.8&lt;/pre&gt;
&lt;h2&gt;Contributing to Open Source Software&lt;/h2&gt;
&lt;p&gt;&lt;img class="right" src="http://files.krisjordan.com/webkit-contribution-process-s354x148.png" alt="WebKit Contribution" width="354" height="148" /&gt;The fix may have been committed today, but the&amp;nbsp;&lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267"&gt;initial bug report was filed in July 2009&lt;/a&gt;, almost two years ago! What took such a simple, but important, fix so long to be made?&amp;nbsp;I would like to say it was the need for &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267#c4"&gt;five other people to chime in&lt;/a&gt; on the ticket, &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267#c2"&gt;someone on the WebKit team to notice&lt;/a&gt;, or &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267#c0"&gt;a duplicate bug request&lt;/a&gt; to be filed 15,000 tickets later. But no, &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=27267#c7"&gt;all the WebKit team needed&lt;/a&gt; was for someone, &lt;em&gt;anyone&lt;/em&gt;, to submit a patch. So I checked out the subversion repository, made a patch, submitted it, and boom, &lt;a href="http://trac.webkit.org/browser/trunk/Source/WebCore/loader/FrameLoader.cpp#L7"&gt;I have contributed code to WebKit&lt;/a&gt; and fixed its Accept header woes. Very cool, but I feel &lt;em&gt;horrible&lt;/em&gt; for not doing so with the original bug report in 2009; content negotiation would be more usable today.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt;: no matter how big or small an open source project is, when you find a bug and know the fix&amp;nbsp;&lt;em&gt;just do it&lt;/em&gt;. Do not assume code to be sacred or untouchable; &lt;em&gt;just &lt;a href="http://www.hulu.com/watch/38477/saturday-night-live-update-thursday-fix-it"&gt;fix it&lt;/a&gt;&amp;nbsp;&lt;/em&gt;and let the committers make the call. Bug reports are helpful, but patches and pull requests are gold. Discussions get read, code gets committed.&amp;nbsp;&lt;em&gt;Code speaks louder than words.&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_pCpD-I2ILs:Lz88GWYlY98:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_pCpD-I2ILs:Lz88GWYlY98:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=_pCpD-I2ILs:Lz88GWYlY98:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_pCpD-I2ILs:Lz88GWYlY98:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=_pCpD-I2ILs:Lz88GWYlY98:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 10 Mar 2011 21:25:56 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/fixing-webkits-accept-header-to-support-content-negotiation-and-rest</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/fixing-webkits-accept-header-to-support-content-negotiation-and-rest</feedburner:origLink></item>
				<item>
			<title>Refactoring Cache Tables using Memoize</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/po7rBQIzG_I/refactor-with-memoize</link>
			<description>&lt;p&gt;Have you ever written code that feels like this?&lt;/p&gt;
&lt;pre&gt;var byKey = function (key) {
	... do slow, expensive stuff ...
	return { value: &amp;ldquo;something expensive&amp;rdquo; };
};&lt;/pre&gt;
&lt;p&gt;And later optimized it to feel like this?&lt;/p&gt;
&lt;pre&gt;var lookup = {};
var byKey = function (key) {
    if ( lookup[key] === undefined ) {
        ... do slow, expensive stuff ...
        lookup[key] = { name: &amp;ldquo;something expensive&amp;rdquo; };
    }
    return lookup[key];
};&lt;/pre&gt;
&lt;p&gt;I certainly have. The lookup table is a trusty pattern for caching the results of expensive calls. With four additional lines of code you can dramatically improve the performance of an often called function. Sprinkle these lines around your most expensive, &lt;a href="http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)"&gt;referentially transparent&lt;/a&gt; functions and you have a nicely optimized program, right?&lt;/p&gt;
&lt;p&gt;With a functional language this pattern is considered harmful; an anti-pattern to refactor. It may be four lines of code, but it is redundant when used over and over. Your function&amp;rsquo;s intentions become conflated with performance concerns. It would be best to keep our intentions and optimizations separate.&lt;/p&gt;
&lt;p&gt;Can we simply write &amp;ldquo;cache this function&amp;rsquo;s return values&amp;rdquo;? It would feel like this,&lt;/p&gt;
&lt;pre&gt;var byKey = cache( function(key) {
    ... do expensive stuff ...
    return { name: &amp;ldquo;something expensive&amp;rdquo; };
} );&lt;/pre&gt;
&lt;p&gt;That feels much better. Although, not knowing what the &lt;code&gt;cache&lt;/code&gt; function actually does is a little off-putting. Let&amp;rsquo;s implement it.&lt;/p&gt;
&lt;blockquote&gt;If you are unfamiliar with anonymous functions and closures in JavaScript this is about to get slightly hairy. Understanding those concepts will make writing JavaScript much more interesting, and little blog posts like this more palatable. I suggest &lt;a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742"&gt;Crockford&lt;/a&gt;, but there are plenty of &lt;a href="https://developer.mozilla.org/en/JavaScript/Guide/Closures"&gt;good on-line resources&lt;/a&gt;, too.&lt;/blockquote&gt;
&lt;p&gt;We need our &lt;code&gt;cache&lt;/code&gt; function to take any function we throw at it and return a new function. The returned function must accomplish what our imperative lookup table code did: remember the arguments of previous invocations and cache their return values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var cache = function( expensiveFn ) {
    var lookup = { };
    return function(key) {
        if(lookup[key] === undefined) {
            lookup[key] = expensiveFn(key);
        }
        return lookup[key];
    };
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let's walk through this. We have defined &lt;code&gt;cache&lt;/code&gt; as a function that takes expensiveFn as a parameter. Within this function we setup the variable lookup to be our hash/cache table. Then we return a function that encapsulates the lookup table pattern used earlier. Do you see how the structure has been extracted and the state hidden within the closure?&lt;/p&gt;
&lt;p&gt;In computer science this function is conventionally named &lt;code&gt;memoize&lt;/code&gt;. It is often demonstrated using a recursive function like &lt;code&gt;factorial&lt;/code&gt;. Factorial is a more beautiful application of memoization than basic key-value caching, but this is an anti-patterm you are more likely to find in real code.&lt;/p&gt;
&lt;h3&gt;An Exercise for the Reader&lt;/h3&gt;
&lt;p&gt;The most obvious shortcoming to &lt;code&gt;cache&lt;/code&gt;, our implementation of &lt;code&gt;memoize&lt;/code&gt;, is that it does not generalize to functions of more than one argument. If you have a few minutes, pop open your browser&amp;rsquo;s JavaScript console in Firebug or Webkit Inspector and try writing it.&amp;nbsp;Hints: 1) The &lt;code&gt;arguments&lt;/code&gt; keyword provides an array of all arguments a function is called with. 2) A function can be invoked with an array of arguments by using &lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/function/apply"&gt;Function's &lt;code&gt;apply&lt;/code&gt; method&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Refactor one-off caching via lookup tables with &lt;code&gt;memoize&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Plenty of libraries provide a generic memoize function, including &lt;a href="http://documentcloud.github.com/underscore/#memoize"&gt;underscore&lt;/a&gt; in JavaScript. The next time you catch yourself writing a naive in-memory cache lookup table around a function stop and consider memoizing it instead. Using &lt;code&gt;memoize&lt;/code&gt; is faster to write and less bug-prone than a one-off cache, it separates intentional concerns from optimization concerns, and it keeps your code a little cleaner.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=po7rBQIzG_I:C1eRVQA6s1w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=po7rBQIzG_I:C1eRVQA6s1w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=po7rBQIzG_I:C1eRVQA6s1w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=po7rBQIzG_I:C1eRVQA6s1w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=po7rBQIzG_I:C1eRVQA6s1w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Sun, 06 Mar 2011 20:51:33 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/refactor-with-memoize</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/refactor-with-memoize</feedburner:origLink></item>
				<item>
			<title>On Muted Methods, Fluent Interfaces, and Bar Game</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/wOLc1yzWOKU/on-muted-methods-and-fluent-interfaces</link>
			<description>&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Yes, this post is about programming, bear with me.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Let's pseudo-code this scenario:&lt;/p&gt;
&lt;pre&gt;$liz = new AttractiveOutOfTownGirl();
$dennis = new SmallTownFriendlyYoungMan();
$liz-&amp;gt;setDrink($dennis-&amp;gt;buyDrink('Vodka Redbull'));
$liz-&amp;gt;setDrink($dennis-&amp;gt;buyDrink('Sex on the Beach'));
$liz-&amp;gt;receiveNumber($dennis-&amp;gt;getPagerNumber());
$dennis-&amp;gt;disappearIntoTheNight();&lt;/pre&gt;
&lt;p&gt;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 &lt;strong&gt;muted methods&lt;/strong&gt;. Dennis' shot at success depended on Liz having some internal, finite state machine that transitioned from "stranger" to&amp;nbsp; "stranger willing to call a stranger" with every additional drink. How could this have gone better for Dennis?&lt;/p&gt;
&lt;p&gt;Before we get there let's talk about &lt;strong&gt;muted methods&lt;/strong&gt;. Procedures. Voids. &lt;strong&gt;Black holes in programs where input results in no output. Scary stuff!&lt;/strong&gt; But why, what's so bad about muted functions? Let's nitpick our example. It is so&amp;nbsp; &lt;em&gt;choppy&lt;/em&gt;. Do you feel the &lt;em&gt;choppiness&lt;/em&gt;?&lt;/p&gt;
&lt;pre&gt;Noun verb.
Noun verb.
Noun verb.
Liz set drink.
Liz set drink.
Liz give number.&lt;/pre&gt;
&lt;p&gt;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. &lt;strong&gt;When you're working with muted functions you have no segue&lt;/strong&gt;. You're giving without receiving.&lt;/p&gt;
&lt;p&gt;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 &lt;strong&gt;fluent interface&lt;/strong&gt;...&lt;/p&gt;
&lt;pre&gt;$dennis-&amp;gt;saysTo($liz, "Hey girl, from out of town?") // returns $liz
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;saysTo($dennis, "Yes, how'd you know?") // returns $dennis
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;saysTo($liz, "Never did seen you before!") // returns $liz
       -&amp;gt;isStillSmiling()
       ? // If she's smiling
   $liz-&amp;gt;setDrink($dennis-&amp;gt;buyDrink('Vodka Redbull')) // returns $liz
       -&amp;gt;saysTo($dennis, "Thanks, you're kind of cute.")
       -&amp;gt;saysTo($liz, "That's how we're grown here. Can I call you?")
       -&amp;gt;saysTo($dennis, "Sure, my name is Liz and the number is...")
       -&amp;gt;punchesInNumber("919-928-9090") // returns $dennis
       -&amp;gt;says("Great, call you tomorrow!") // returns $dennis
       -&amp;gt;disappearIntoTheNight()
       : // If she's frowning
   $dennis-&amp;gt;movesAlong();&lt;/pre&gt;
&lt;p&gt;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!&lt;/p&gt;
&lt;p&gt;This style of object-oriented interface, where &lt;em&gt;method chaining&lt;/em&gt; and &lt;em&gt;thoughtful return values&lt;/em&gt; enable a pseudo-domain specific language written entirely in a general purpose language, has been called a &lt;a href="http://martinfowler.com/bliki/FluentInterface.html"&gt;"Fluent Interface" by Martin Fowler and Eric Evans&lt;/a&gt;. It's an inspiring departure from the days of the void, black hole methods like setters.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;When your functions or methods don't return ask yourself "if I &lt;em&gt;were &lt;/em&gt;to return something here &lt;em&gt;what &lt;/em&gt;would be useful?" Most often, it's a reference to the object itself. Or an immutable clone.&lt;/p&gt;
&lt;p&gt;"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. &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;You should subscribe to this RSS feed if immutable clones pique your interest. Or nerdy bar game.&lt;/a&gt;&lt;/p&gt;
&lt;div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 291px; width: 1px; height: 1px;"&gt;setDrink($this-&amp;gt;buyDrink('Vodka Redbull'));&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=wOLc1yzWOKU:viMYnBn6zD8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=wOLc1yzWOKU:viMYnBn6zD8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=wOLc1yzWOKU:viMYnBn6zD8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=wOLc1yzWOKU:viMYnBn6zD8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=wOLc1yzWOKU:viMYnBn6zD8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Mon, 24 Aug 2009 23:47:02 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2009/08/24/on-muted-methods-and-fluent-interfaces</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2009/08/24/on-muted-methods-and-fluent-interfaces</feedburner:origLink></item>
				<item>
			<title>What's on my mind...</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/dVvN1KdVfR8/whats-on-my-mind</link>
			<description>&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.newmediacampaigns.com/page/the-throw-away-computer-virtualization"&gt;Using virtual machines and shell scripts to achieve the Ultimate Small Team Software Engineering Environment&lt;/a&gt; (tm)&lt;/li&gt;
	&lt;li&gt;Real Software Engineering in PHP&lt;/li&gt;
	&lt;li&gt;Trees, Recursion, Permissions, and Architecture of &lt;a href="http://www.newmediacampaigns.com/"&gt;my company&lt;/a&gt;'s next &lt;a href="http://www.newmediacampaigns.com/page/content-management-system"&gt;Content Management System&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;How to simplify internals and increase functionality of the Recess Framework by leveraging PHP 5.3's new features like &lt;a href="http://www.recessframework.org/page/functional-php-anonymous-functions-lambdas-closures"&gt;anonymous functions&lt;/a&gt; and &lt;a href="http://www.newmediacampaigns.com/page/php-namespaces-backslash-example"&gt;namespaces&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;A big client integration project that deals with scary acronyms like HIPAA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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 &lt;a href="http://www.newmediacampaigns.com/"&gt;New Media&lt;/a&gt;'s &lt;a href="http://www.newmediacampaigns.com/blog/category/Development"&gt;Web Development Blog&lt;/a&gt; or the Recess &lt;a href="http://www.recessframework.org/blog"&gt;PHP Blog&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
To kick that off the off the cuff writing, &lt;a href="http://ejohn.org/blog/eulogy-to-_why/"&gt;a few words on _why&lt;/a&gt;. I don't know _why, I haven't read the &lt;a href="http://www.ember.co.nz/files/resources/whys-poignant-guide-to-ruby.pdf"&gt;poignant guide&lt;/a&gt; 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 &lt;a href="http://www.vimeo.com/5047563?pg=embed&amp;amp;sec="&gt;his recent talk at Carnegie Melon&lt;/a&gt; [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...
&lt;/p&gt;
&lt;object width="400" height="220" data="http://vimeo.com/moogaloop.swf?clip_id=5047563&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=5047563&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dVvN1KdVfR8:zV_Pmu09bU4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dVvN1KdVfR8:zV_Pmu09bU4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=dVvN1KdVfR8:zV_Pmu09bU4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dVvN1KdVfR8:zV_Pmu09bU4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=dVvN1KdVfR8:zV_Pmu09bU4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 20 Aug 2009 22:39:50 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2009/08/20/whats-on-my-mind</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2009/08/20/whats-on-my-mind</feedburner:origLink></item>
				<item>
			<title>Recess! Framework Screencast #1</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/vo8yEJnM_h8/recess-framework-screencast-1</link>
			<description>&lt;p&gt;I'm excited to get the first Recess! screencast out on the interwebs over at &lt;a href="http://www.recessframework.org"&gt;RecessFramework.org&lt;/a&gt;. Special thanks to &lt;a href="http://www.twitter.com/JoelSutherland"&gt;Joel Sutherland&lt;/a&gt; and the &lt;a href="http://www.newmediacampaigns.com"&gt;Raleigh Web Design&lt;/a&gt; firm &lt;a href="http://www.newmediacampaigns.com"&gt;New Media Campaigns&lt;/a&gt; for helping me launch the Recess site in record time!
&lt;/p&gt;&lt;p&gt;
Without further adieu... &lt;a href="http://www.recessframework.org/page/routing-in-recess-screencast"&gt;Routing in Recess&lt;/a&gt;!
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.recessframework.org/page/routing-in-recess-screencast"&gt;&lt;img class="size-full wp-image-575" title="Recess! Framework" src="http://files.kris.gethifi.com/recesshomepage.gif" alt="Recess! PHP Framework" width="400" height="249" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=vo8yEJnM_h8:uKpGUUlolNs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=vo8yEJnM_h8:uKpGUUlolNs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=vo8yEJnM_h8:uKpGUUlolNs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=vo8yEJnM_h8:uKpGUUlolNs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=vo8yEJnM_h8:uKpGUUlolNs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Tue, 16 Dec 2008 22:34:44 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/12/16/recess-framework-screencast-1</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/12/16/recess-framework-screencast-1</feedburner:origLink></item>
				<item>
			<title>Towards RESTful PHP - 5 Basic Tips</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/pFsDoWtqGoY/towards-restful-php-5-basic-tips</link>
			<description>&lt;strong&gt;What is REST?&lt;/strong&gt;
&lt;p&gt;REST is an architectural style, or set of conventions, for web applications and services that centers itself around &lt;em&gt;resource manipulation&lt;/em&gt; 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 &lt;em&gt;/user/1 is a resource&lt;/em&gt; and use the HTTP DELETE verb to delete it. For more detail on REST check out &lt;a href="http://en.wikipedia.org/wiki/REST"&gt;wikipedia&lt;/a&gt; and "&lt;a href="http://www.megginson.com/blogs/quoderat/2007/02/15/rest-the-quick-pitch/"&gt;quick pitch&lt;/a&gt;".&lt;/p&gt;
&lt;h2&gt;Tip #1: Using PUT and DELETE methods&lt;/h2&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre class="php" name="code"&gt;$_PUT  = array();
&lt;p&gt;if($_SERVER['REQUEST_METHOD'] == 'PUT') {&lt;/p&gt;
&lt;p&gt;    $putdata = file_get_contents('php://input');&lt;/p&gt;
&lt;p&gt;    $exploded = explode('&amp;amp;', $putdata); 
&lt;/p&gt;&lt;p&gt;
    foreach($exploded as $pair) {&lt;/p&gt;
&lt;p&gt;        $item = explode('=', $pair);&lt;/p&gt;
&lt;p&gt;        if(count($item) == 2) {&lt;/p&gt;
&lt;p&gt;            $_PUT[urldecode($item[0])] = urldecode($item[1]);&lt;/p&gt;
&lt;p&gt;        }&lt;/p&gt;
&lt;p&gt;    }&lt;/p&gt;
}&lt;/pre&gt;
&lt;h2&gt;Tip #2: Send Custom HTTP/1.1 Headers&lt;/h2&gt;
&lt;p&gt;PHP's &lt;a href="http://www.php.net/header"&gt;header&lt;/a&gt; function allows custom HTTP headers to be sent to the client. The HTTP/1.x header contains the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"&gt;response code&lt;/a&gt; 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:&lt;/p&gt;
&lt;pre class="php" name="code"&gt;header('HTTP/1.1 404 Not Found');
&lt;p&gt;/* OR */&lt;/p&gt;
header('Location: http://www.foo.com/bar', true, 201); // 201 CREATED&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;pre class="php" name="code"&gt;header('HTTP/1.1 201 Created');
header('Location: http://www.foo.com/bar');&lt;/pre&gt;
&lt;h2&gt;Tip #3: Send Meaningful HTTP Headers&lt;/h2&gt;
&lt;p&gt;Policy for deciding when it is appropriate to send each HTTP status code is a full post on its own and the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"&gt;HTTP spec&lt;/a&gt; leaves room for ambiguity. There are &lt;a href="http://www.xml.com/pub/a/2004/12/01/restful-web.html"&gt;many&lt;/a&gt; &lt;a href="http://blog.brianguthrie.com/articles/2008/08/22/rails-and-rest-a-reference-to-commonly-used-http-status-codes-and-their-use-in-rest-apis"&gt;other&lt;/a&gt; resources on the net which provide insights so I'll just touch on a few.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;201 Created&lt;/strong&gt; 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.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;202 Accepted&lt;/strong&gt; allows the server to tell the client "yeah, we heard your order, we'll get to it soon." Think the &lt;a href="http://www.twitter.com/"&gt;Twitter API&lt;/a&gt; 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.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;304 Not Modified&lt;/strong&gt; 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.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;401 Unauthorized&lt;/strong&gt; 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.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;500 Internal Server Error&lt;/strong&gt; is better than OK when your PHP script dies or reaches an exception.
&lt;/p&gt;&lt;p&gt;
In the &lt;a href="http://www.recessframework.com"&gt;Recess! Framework&lt;/a&gt; I use this &lt;a href="http://www.krisjordan.com/php-class-for-http-response-status-codes/"&gt;StatusCodes class&lt;/a&gt; to provide named constants for all HTTP/1.1 status codes. Example usage:&lt;/p&gt;
&lt;pre class="php" name="code"&gt;header(StatusCodes::httpHeaderFor(StatusCodes::HTTP_NOT_FOUND));&lt;/pre&gt;
&lt;h2&gt;Tip #4: Don't Use $_SESSION&lt;/h2&gt;
A truly RESTful PHP application should be entirely stateless- &lt;strong&gt;all requests should contain enough information to be handled without additional server side state&lt;/strong&gt;. 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. &lt;a href="http://www.krisjordan.com/2008/09/16/cal-henderson-scalable-web-architectures-common-patterns-and-approaches/"&gt;This is how Flickr approaches statelessness.&lt;/a&gt;
&lt;h2&gt;Tip #5: Test with cURL or rest-client&lt;/h2&gt;
&lt;a href="http://www.krisjordan.com/wp-content/uploads/2008/12/rest-client.png"&gt;&lt;img class="alignright size-thumbnail wp-image-494" title="rest-client" src="http://files.kris.gethifi.com/rest-client-150x150.png" alt="" width="150" height="150" /&gt;&lt;/a&gt;&lt;a href="http://curl.haxx.se/"&gt;cURL&lt;/a&gt; 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 &lt;a href="http://www.mingw.org/"&gt;MinGW/MSYS&lt;/a&gt; which supports cURL. Even &lt;a href="http://us2.php.net/curl"&gt;PHP has cURL functions&lt;/a&gt; which are enabled on most hosts (&lt;a href="http://us2.php.net/manual/en/curl.setup.php"&gt;php/curl install page&lt;/a&gt;).

&lt;strong&gt;cURL Example Usage &amp;amp; Common Parameters:&lt;/strong&gt;
&lt;pre&gt;# curl -X PUT http://www.foo.com/bar/1 -d "some=var" -d "other=var2" -H "Accept: text/json" -I&lt;/pre&gt;
&lt;strong&gt;-X [METHOD]&lt;/strong&gt; Specify the HTTP method.
&lt;strong&gt;-d "name=value"&lt;/strong&gt; Set a POST/PUT field name and value.
&lt;strong&gt;-H [HEADER]&lt;/strong&gt; Set a header.
&lt;strong&gt;-I&lt;/strong&gt; Only display response's headers.
&lt;p&gt;
Alternatively, a free GUI to test REST interfaces is &lt;a href="http://code.google.com/p/rest-client/"&gt;Java/Swing based &lt;strong&gt;rest-client&lt;/strong&gt;&lt;/a&gt;. rest-client is scriptable and has support for JSON/XML.&lt;/p&gt;
&lt;h2&gt;Tip #6 - Use a RESTful PHP Framework&lt;/h2&gt;
&lt;p&gt;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 &lt;a href="http://blog.medryx.org/2008/10/03/codeigniter-rest/"&gt;serious hacking&lt;/a&gt; that needs to be done. Cake &lt;a href="http://book.cakephp.org/view/478/Custom-REST-Routing"&gt;has&lt;/a&gt; REST support but wasn't designed to make specifying useful response status codes a part of the framework. &lt;a href="http://konstrukt.dk/"&gt;Konstruct&lt;/a&gt; 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.
&lt;/p&gt;&lt;p&gt;
(Disclaimer: &lt;em&gt;Shameless Plug!&lt;/em&gt;) &lt;strong&gt;The lack of a solid, RESTful PHP framework was one of my primary motivations for creating the &lt;a href="http://www.recessframework.com/"&gt;Recess! Framework&lt;/a&gt;&lt;/strong&gt;. Recess is a full-stack, open source (MIT), &lt;a href="http://www.recessframework.com/"&gt;RESTful PHP framework&lt;/a&gt;. If you're interested in writing RESTful PHP applications check it out and sign-up to be notified of its upcoming release.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=pFsDoWtqGoY:eIiOOZm5YC0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=pFsDoWtqGoY:eIiOOZm5YC0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=pFsDoWtqGoY:eIiOOZm5YC0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=pFsDoWtqGoY:eIiOOZm5YC0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=pFsDoWtqGoY:eIiOOZm5YC0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Tue, 02 Dec 2008 01:33:57 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/12/02/towards-restful-php-5-basic-tips</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/12/02/towards-restful-php-5-basic-tips</feedburner:origLink></item>
				<item>
			<title>PHP Class for HTTP Response Status Codes</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/rZJUbcoexqk/php-class-for-http-response-status-codes</link>
			<description>&lt;p&gt;The &lt;a href="http://www.recessframework.com/"&gt;Recess! Framework&lt;/a&gt; uses the following class which provides constants and simple helper methods for HTTP Response Status Codes.
&lt;/p&gt;
&lt;pre name="code" class="php"&gt;
&lt;p&gt;&amp;lt;?php&lt;/p&gt;
&lt;p&gt;/**&lt;/p&gt;
&lt;p&gt; * StatusCodes provides named constants for&lt;/p&gt;
&lt;p&gt; * HTTP protocol status codes. Written for the&lt;/p&gt;
&lt;p&gt; * Recess Framework (http://www.recessframework.com/)&lt;/p&gt;
&lt;p&gt; * &lt;/p&gt;
&lt;p&gt; * @author Kris Jordan&lt;/p&gt;
&lt;p&gt; * @license MIT &lt;/p&gt;
&lt;p&gt; * @package recess.http&lt;/p&gt;
&lt;p&gt; */&lt;/p&gt;
&lt;p&gt;class StatusCodes {&lt;/p&gt;
&lt;p&gt;	// [Informational 1xx]&lt;/p&gt;
&lt;p&gt;	const HTTP_CONTINUE = 100;&lt;/p&gt;
&lt;p&gt;	const HTTP_SWITCHING_PROTOCOLS = 101;&lt;/p&gt;
&lt;p&gt;	// [Successful 2xx]&lt;/p&gt;
&lt;p&gt;	const HTTP_OK = 200;&lt;/p&gt;
&lt;p&gt;	const HTTP_CREATED = 201;&lt;/p&gt;
&lt;p&gt;	const HTTP_ACCEPTED = 202;&lt;/p&gt;
&lt;p&gt;	const HTTP_NONAUTHORITATIVE_INFORMATION = 203;&lt;/p&gt;
&lt;p&gt;	const HTTP_NO_CONTENT = 204;&lt;/p&gt;
&lt;p&gt;	const HTTP_RESET_CONTENT = 205;&lt;/p&gt;
&lt;p&gt;	const HTTP_PARTIAL_CONTENT = 206;&lt;/p&gt;
&lt;p&gt;	// [Redirection 3xx]&lt;/p&gt;
&lt;p&gt;	const HTTP_MULTIPLE_CHOICES = 300;&lt;/p&gt;
&lt;p&gt;	const HTTP_MOVED_PERMANENTLY = 301;&lt;/p&gt;
&lt;p&gt;	const HTTP_FOUND = 302;&lt;/p&gt;
&lt;p&gt;	const HTTP_SEE_OTHER = 303;&lt;/p&gt;
&lt;p&gt;	const HTTP_NOT_MODIFIED = 304;&lt;/p&gt;
&lt;p&gt;	const HTTP_USE_PROXY = 305;&lt;/p&gt;
&lt;p&gt;	const HTTP_UNUSED= 306;&lt;/p&gt;
&lt;p&gt;	const HTTP_TEMPORARY_REDIRECT = 307;&lt;/p&gt;
&lt;p&gt;	// [Client Error 4xx]&lt;/p&gt;
&lt;p&gt;	const errorCodesBeginAt = 400;&lt;/p&gt;
&lt;p&gt;	const HTTP_BAD_REQUEST = 400;&lt;/p&gt;
&lt;p&gt;	const HTTP_UNAUTHORIZED  = 401;&lt;/p&gt;
&lt;p&gt;	const HTTP_PAYMENT_REQUIRED = 402;&lt;/p&gt;
&lt;p&gt;	const HTTP_FORBIDDEN = 403;&lt;/p&gt;
&lt;p&gt;	const HTTP_NOT_FOUND = 404;&lt;/p&gt;
&lt;p&gt;	const HTTP_METHOD_NOT_ALLOWED = 405;&lt;/p&gt;
&lt;p&gt;	const HTTP_NOT_ACCEPTABLE = 406;&lt;/p&gt;
&lt;p&gt;	const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;&lt;/p&gt;
&lt;p&gt;	const HTTP_REQUEST_TIMEOUT = 408;&lt;/p&gt;
&lt;p&gt;	const HTTP_CONFLICT = 409;&lt;/p&gt;
&lt;p&gt;	const HTTP_GONE = 410;&lt;/p&gt;
&lt;p&gt;	const HTTP_LENGTH_REQUIRED = 411;&lt;/p&gt;
&lt;p&gt;	const HTTP_PRECONDITION_FAILED = 412;&lt;/p&gt;
&lt;p&gt;	const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;&lt;/p&gt;
&lt;p&gt;	const HTTP_REQUEST_URI_TOO_LONG = 414;&lt;/p&gt;
&lt;p&gt;	const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;&lt;/p&gt;
&lt;p&gt;	const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;&lt;/p&gt;
&lt;p&gt;	const HTTP_EXPECTATION_FAILED = 417;&lt;/p&gt;
&lt;p&gt;	// [Server Error 5xx]&lt;/p&gt;
&lt;p&gt;	const HTTP_INTERNAL_SERVER_ERROR = 500;&lt;/p&gt;
&lt;p&gt;	const HTTP_NOT_IMPLEMENTED = 501;&lt;/p&gt;
&lt;p&gt;	const HTTP_BAD_GATEWAY = 502;&lt;/p&gt;
&lt;p&gt;	const HTTP_SERVICE_UNAVAILABLE = 503;&lt;/p&gt;
&lt;p&gt;	const HTTP_GATEWAY_TIMEOUT = 504;&lt;/p&gt;
&lt;p&gt;	const HTTP_VERSION_NOT_SUPPORTED = 505;&lt;/p&gt;
		
&lt;p&gt;	private static $messages = array(&lt;/p&gt;
&lt;p&gt;		// [Informational 1xx]&lt;/p&gt;
&lt;p&gt;		100=&amp;gt;'100 Continue',&lt;/p&gt;
&lt;p&gt;		101=&amp;gt;'101 Switching Protocols',&lt;/p&gt;
&lt;p&gt;		// [Successful 2xx]&lt;/p&gt;
&lt;p&gt;		200=&amp;gt;'200 OK',&lt;/p&gt;
&lt;p&gt;		201=&amp;gt;'201 Created',&lt;/p&gt;
&lt;p&gt;		202=&amp;gt;'202 Accepted',&lt;/p&gt;
&lt;p&gt;		203=&amp;gt;'203 Non-Authoritative Information',&lt;/p&gt;
&lt;p&gt;		204=&amp;gt;'204 No Content',&lt;/p&gt;
&lt;p&gt;		205=&amp;gt;'205 Reset Content',&lt;/p&gt;
&lt;p&gt;		206=&amp;gt;'206 Partial Content',&lt;/p&gt;
&lt;p&gt;		// [Redirection 3xx]&lt;/p&gt;
&lt;p&gt;		300=&amp;gt;'300 Multiple Choices',&lt;/p&gt;
&lt;p&gt;		301=&amp;gt;'301 Moved Permanently',&lt;/p&gt;
&lt;p&gt;		302=&amp;gt;'302 Found',&lt;/p&gt;
&lt;p&gt;		303=&amp;gt;'303 See Other',&lt;/p&gt;
&lt;p&gt;		304=&amp;gt;'304 Not Modified',&lt;/p&gt;
&lt;p&gt;		305=&amp;gt;'305 Use Proxy',&lt;/p&gt;
&lt;p&gt;		306=&amp;gt;'306 (Unused)',&lt;/p&gt;
&lt;p&gt;		307=&amp;gt;'307 Temporary Redirect',&lt;/p&gt;
&lt;p&gt;		// [Client Error 4xx]&lt;/p&gt;
&lt;p&gt;		400=&amp;gt;'400 Bad Request',&lt;/p&gt;
&lt;p&gt;		401=&amp;gt;'401 Unauthorized',&lt;/p&gt;
&lt;p&gt;		402=&amp;gt;'402 Payment Required',&lt;/p&gt;
&lt;p&gt;		403=&amp;gt;'403 Forbidden',&lt;/p&gt;
&lt;p&gt;		404=&amp;gt;'404 Not Found',&lt;/p&gt;
&lt;p&gt;		405=&amp;gt;'405 Method Not Allowed',&lt;/p&gt;
&lt;p&gt;		406=&amp;gt;'406 Not Acceptable',&lt;/p&gt;
&lt;p&gt;		407=&amp;gt;'407 Proxy Authentication Required',&lt;/p&gt;
&lt;p&gt;		408=&amp;gt;'408 Request Timeout',&lt;/p&gt;
&lt;p&gt;		409=&amp;gt;'409 Conflict',&lt;/p&gt;
&lt;p&gt;		410=&amp;gt;'410 Gone',&lt;/p&gt;
&lt;p&gt;		411=&amp;gt;'411 Length Required',&lt;/p&gt;
&lt;p&gt;		412=&amp;gt;'412 Precondition Failed',&lt;/p&gt;
&lt;p&gt;		413=&amp;gt;'413 Request Entity Too Large',&lt;/p&gt;
&lt;p&gt;		414=&amp;gt;'414 Request-URI Too Long',&lt;/p&gt;
&lt;p&gt;		415=&amp;gt;'415 Unsupported Media Type',&lt;/p&gt;
&lt;p&gt;		416=&amp;gt;'416 Requested Range Not Satisfiable',&lt;/p&gt;
&lt;p&gt;		417=&amp;gt;'417 Expectation Failed',&lt;/p&gt;
&lt;p&gt;		// [Server Error 5xx]&lt;/p&gt;
&lt;p&gt;		500=&amp;gt;'500 Internal Server Error',&lt;/p&gt;
&lt;p&gt;		501=&amp;gt;'501 Not Implemented',&lt;/p&gt;
&lt;p&gt;		502=&amp;gt;'502 Bad Gateway',&lt;/p&gt;
&lt;p&gt;		503=&amp;gt;'503 Service Unavailable',&lt;/p&gt;
&lt;p&gt;		504=&amp;gt;'504 Gateway Timeout',&lt;/p&gt;
&lt;p&gt;		505=&amp;gt;'505 HTTP Version Not Supported'&lt;/p&gt;
&lt;p&gt;	);&lt;/p&gt;
	
&lt;p&gt;	public static function httpHeaderFor($code) {&lt;/p&gt;
&lt;p&gt;		return 'HTTP/1.1 ' . self::$messages[$code];&lt;/p&gt;
&lt;p&gt;	}
&lt;/p&gt;&lt;p&gt;
	public static function getMessageForCode($code) {&lt;/p&gt;
&lt;p&gt;		return self::$messages[$code];&lt;/p&gt;
	}
	
&lt;p&gt;	public static function isError($code) {&lt;/p&gt;
&lt;p&gt;		return is_numeric($code) &amp;&amp; $code &amp;gt;= self::HTTP_BAD_REQUEST;&lt;/p&gt;
	}
	
&lt;p&gt;	public static function canHaveBody($code) {&lt;/p&gt;
&lt;p&gt;		return&lt;/p&gt;
&lt;p&gt;			// True if not in 100s&lt;/p&gt;
&lt;p&gt;			($code &amp;lt; self::HTTP_CONTINUE || $code &amp;gt;= self::HTTP_OK)&lt;/p&gt;
&lt;p&gt;			&amp;&amp; // and not 204 NO CONTENT&lt;/p&gt;
&lt;p&gt;			$code != self::HTTP_NO_CONTENT&lt;/p&gt;
&lt;p&gt;			&amp;&amp; // and not 304 NOT MODIFIED&lt;/p&gt;
&lt;p&gt;			$code != self::HTTP_NOT_MODIFIED;&lt;/p&gt;
	}
}
&lt;p&gt;?&amp;gt;&lt;/p&gt;
&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=rZJUbcoexqk:ctTNmKFxD-Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=rZJUbcoexqk:ctTNmKFxD-Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=rZJUbcoexqk:ctTNmKFxD-Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=rZJUbcoexqk:ctTNmKFxD-Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=rZJUbcoexqk:ctTNmKFxD-Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Mon, 01 Dec 2008 19:37:35 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/php-class-for-http-response-status-codes</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/php-class-for-http-response-status-codes</feedburner:origLink></item>
				<item>
			<title>How Recess Solves Common PHP/MySQL Issues</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/fIKdsMH88Q0/how-recess-solves-common-phpmysql-issues</link>
			<description>&lt;a href="http://www.justincarmony.com"&gt;Justin Carmony&lt;/a&gt; wrote a great article titled '&lt;a href="http://www.justincarmony.com/blog/2008/10/25/php-design-biggest-database-oversights/"&gt;PHP Design - Biggest Database Oversights&lt;/a&gt;'. The article points out 5 naive PHP/MySQL design decisions that will come back to haunt projects if they've been made. As I'm getting closer to the public preview release of the &lt;a href="http://www.recessframework.com/"&gt;Recess! Framework&lt;/a&gt; this article discusses how Recess! addresses some of the most common oversights in database development.
&lt;p&gt;
&lt;strong&gt;Re: Oversight #1 - No Data Access Layer&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
Quality software design and engineering is all about abstracting away details and finding the proper layers of functionality. As Justin points out, if there is no layer of abstraction which wraps data access code then low-level data access code will appear everywhere. PHP projects which interleave data connections and queries throughout their code are difficult to maintain. 
&lt;/p&gt;&lt;p&gt;
The database stack in Recess! has four major components: 1) SQL statement builder, 2) Data Sources, 3) Data Sets, 4) Object-Relational Mapped Models. The notion of a 'data access layer' is taken care of by Data Sources. Data sources wrap properly around PDO and introduce new methods beyond PDO's, for example: getTables and getColumns($table). The implementation of these methods is specific to the RDBMS so Recess! also has the notion of a vendor specific driver called a DataSourceProvider. Currently Sqlite and MySql are supported.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Re: Oversight #2 - Design for Only One Database Connection&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
Small, greenfield projects often start out with a single database. This leads to naive data access layers which only support connections to a single database. Recess! supports multiple, named Data Sources. Instead of using a singleton pattern it uses a registry to store the Data Sources by name.
&lt;/p&gt;&lt;p&gt;
Having named Data Sources in an application gets really powerful at higher layers of abstraction, such as at the ORM layer, where we can mark-up a model with a single annotation to define which Data Source the model is persisted in.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Re: Oversight #3 - No Developer Logging&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
This isn't as fully fleshed out yet as I'd like but the plans and hooks are in place to be able to log queries, their stack traces, as well as their EXPLAIN'ed strategies for execution in the RDBMS.  In Recess! there is a distinct difference between Development mode and Production mode. Sql logging will be a toggle option on by default in development and off by default in production.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Re: Oversight #4 - Queries Written in Procedural Processes&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
My dislike of queries being written in procedural code may run even deeper than Justin's! Recess! abdicates SQL string manipulation to a low-level SqlBuilder class. An instance of SqlBuilder allows SQL query strings to be built incrementally using chained method calls. Let's take a look at some examples:
&lt;/p&gt;
&lt;pre name="code" class="php"&gt;
&lt;p&gt;$sqlBuilder = new SqlBuilder();&lt;/p&gt;
&lt;p&gt;$sql = $sqlBuilder&lt;/p&gt;
&lt;p&gt;            -&amp;gt;from('people')&lt;/p&gt;
&lt;p&gt;            -&amp;gt;like('name','Kris')&lt;/p&gt;
&lt;p&gt;            -&amp;gt;orderBy('age')&lt;/p&gt;
&lt;p&gt;            -&gt;toSql();&lt;/p&gt;
&lt;p&gt;// $sql is now: &lt;/p&gt;
&lt;p&gt;// 'SELECT people.* &lt;/p&gt;
&lt;p&gt;//    WHERE people.name = :people_name &lt;/p&gt;
&lt;p&gt;//    ORDER BY people.age&lt;/p&gt;
&lt;p&gt;$args = $sqlBuilder-&amp;gt;getPdoArguments();&lt;/p&gt;
&lt;p&gt;// $args is now array( 'people_name' =&amp;gt; 'Kris' );
&lt;/p&gt;&lt;p&gt;
// Let's add another criterion&lt;/p&gt;
&lt;p&gt;$sql = $sqlBuilder-&gt;equal('home_city', 'Charlotte')-&gt;toSql();&lt;/p&gt;
&lt;p&gt;// $sql is now: &lt;/p&gt;
&lt;p&gt;//  SELECT people.* &lt;/p&gt;
&lt;p&gt;//      WHERE people.name LIKE :people_name &lt;/p&gt;
&lt;p&gt;//      AND people.home_city = :people_home_city &lt;/p&gt;
&lt;p&gt;//      ORDER BY people.age
&lt;/p&gt;&lt;p&gt;
$args = $sqlBuilder-&amp;gt;getPdoArguments();&lt;/p&gt;
&lt;p&gt;// $args is now array( &lt;/p&gt;
&lt;p&gt;//                   'people_name' =&amp;gt; 'Kris', &lt;/p&gt;
&lt;p&gt;//                   'people_home_city' =&amp;gt; 'Charlotte' );&lt;/p&gt;
&lt;/pre&gt;
&lt;p&gt;
SqlBuilder can do more complex things like joins, as well as inserts, updates, and deletes. Recess! users, though, will likely never use SqlBuilder because it's still too low level of an abstraction. Internally, however, having the ability to incrementally construct query strings has made the framework code quite pretty.
&lt;/p&gt;&lt;p&gt;
Here's code at the level of abstraction Recess! developers can expect to write:
&lt;/p&gt;
&lt;pre name="code" class="php"&gt;
&lt;p&gt;class Person extends Model { }&lt;/p&gt;
&lt;p&gt;$person = new Person();&lt;/p&gt;
&lt;p&gt;$person-&amp;gt;name = 'Kris';&lt;/p&gt;
&lt;p&gt;$person-&amp;gt;homeCity = 'Charlotte';&lt;/p&gt;
&lt;p&gt;$people = $person-&amp;gt;find()-&amp;gt;orderBy('name');&lt;/p&gt;
&lt;p&gt;foreach($people as $person) {&lt;/p&gt;
&lt;p&gt;   echo $person-&amp;gt;name, ' ', $person-&amp;gt;age, '&amp;lt;br /&amp;gt;';&lt;/p&gt;
}
&lt;/pre&gt;
&lt;p&gt;
This example just scrapes the surface of Recess! object-relational mapping. Relationships, CRUDS, cascading deletes, etc. are all handled as well. In a future post I'll step through the data access stack's capabilities in more detail. Needless to say, in Recess! queries won't be mixed with procedural code!
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Re: Oversight #5 - No Separation of Reads and Writes&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
Once projects outgrow a single server RDBMS the next step is often to do a Master/Slave setup in MySQL. In a Master/Slave setup expensive and less frequent writes are channeled to the Master server while reads are channeled to the Slave server.
&lt;/p&gt;&lt;p&gt;
In Recess!, by using named data sources as described in #2, we can handle Data Sources on a per model basis. A natural extension of this is handling reads and writes independently on a per model basis. The pseudo-code below shows how this may look on a model:
&lt;/p&gt;
&lt;pre name="code" class="php"&gt;
&lt;p&gt;/** &lt;/p&gt;
&lt;p&gt; * !Source master, For: Writes&lt;/p&gt;
&lt;p&gt; * !Source (slave1, slave2, slave3), For: Reads&lt;/p&gt;
&lt;p&gt; * !HasMany books&lt;/p&gt;
&lt;p&gt; */&lt;/p&gt;
&lt;p&gt;class Person extends Model {}
&lt;/p&gt;&lt;p&gt;
/**&lt;/p&gt;
&lt;p&gt; * !Source master&lt;/p&gt;
&lt;p&gt; * !BelongsTo person&lt;/p&gt;
&lt;p&gt; */&lt;/p&gt;
&lt;p&gt;class Books extends Model {}&lt;/p&gt;
&lt;/pre&gt;
&lt;p&gt;
In a future post I'll describe the Recess! annotations system which will explain the constructs you're seeing in the DocComments. Recess! annotations give us a way of providing static metadata about a class and are built-in to the framework's core. Recess! annotations should be familiar to Java and .Net programmers who have used annotations.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
So that's a quick look at how Recess! handles Justin Carmony's commonly made MySQL/PHP mistakes. These issues are abstracted away in the internals of Recess. If you're a PHP developer check out &lt;a href="http://www.recessframework.com/"&gt;RecessFramework.com&lt;/a&gt; and sign-up to be notified when it is publicly released "very soon now".&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=fIKdsMH88Q0:uDjyYFcA-8E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=fIKdsMH88Q0:uDjyYFcA-8E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=fIKdsMH88Q0:uDjyYFcA-8E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=fIKdsMH88Q0:uDjyYFcA-8E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=fIKdsMH88Q0:uDjyYFcA-8E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 28 Nov 2008 16:25:25 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/11/28/how-recess-solves-common-phpmysql-issues</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/11/28/how-recess-solves-common-phpmysql-issues</feedburner:origLink></item>
				<item>
			<title>Dynamic Properties in PHP and StdClass</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/yHfO0G4RgpY/dynamic-properties-in-php-with-stdclass</link>
			<description>&lt;p&gt;Languages like JavaScript and Python allow object instances to have dynamic properties. As it turns out, PHP does too. Looking at the official PHP documentation on objects and classes you might be lead to believe dynamic instance properties require custom __get and __set magic methods. They don't.&lt;/p&gt;
&lt;h2&gt;Simple, Built-in Dynamic Properties&lt;/h2&gt;
&lt;p&gt;Check out the following code listing:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;class DynamicProperties { }
$object = new DynamicProperties;
print isset($object-&amp;gt;foo) ? 't' : 'f'; // f

// Set Dynamic Properties foo and fooz
$object-&amp;gt;foo = 'bar';
$object-&amp;gt;fooz = 'baz';

// Isset and Unset work
isset($object-&amp;gt;foo); // true
unset($object-&amp;gt;foo);

// Iterate through Properties and Values
foreach($object as $property =&amp;gt; $value)&amp;nbsp; { 
     print($property . ' = ' . $value . '&amp;lt;br /&amp;gt;'); 
}

// Prints:
//   fooz = baz&lt;/pre&gt;
&lt;p&gt;Using the built-in dynamic instance properties is an order of magnitude faster (30x, by my profiling) than using magic __get and __set methods. Built in dynamic property accesses happen without invoking a method call back to PHP script.&lt;/p&gt;
&lt;p&gt;So when does it make sense to use __get and __set? If you need more complex behavior, like calculated properties, you must use __get and __set. Also, as an astute comment points out, if you would prefer &lt;em&gt;not&lt;/em&gt; to have dynamic properties on a class you can throw errors from __get and __set.&lt;/p&gt;
&lt;h2&gt;StdClass: Anonymous Objects&lt;/h2&gt;
&lt;p&gt;Sometimes all that is necessary is a property bag to throw key value pairs into. One way is to use array, but this requires quoting all keys. Another way is to use dynamic properties on an instance of StdClass. StdClass is a sparsely documented class in PHP which has no predefined members.&lt;/p&gt;
&lt;pre name="code" class="php"&gt;$object = new StdClass;
$object-&amp;gt;foo = 'bar';
json_encode($object);&lt;/pre&gt;
&lt;p&gt;Next I'll touch on the SPL's Countable and ArrayAccess as a means of being able to accomplish the following in PHP:&lt;/p&gt;
&lt;pre name="code" class="php"&gt;class MyClass implements Countable, ArrayAccess { ... }
$myObject = new MyClass();
// Using array access notation
$myObject[0] = 'hello';
$myObject[1] = 'world';
$myObject['foo'] = 'bar';
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Thanks to the folks pointing out that you don't need to extend from StdClass in order to have dynamic properties!&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=yHfO0G4RgpY:s6rPHpU9flg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=yHfO0G4RgpY:s6rPHpU9flg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=yHfO0G4RgpY:s6rPHpU9flg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=yHfO0G4RgpY:s6rPHpU9flg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=yHfO0G4RgpY:s6rPHpU9flg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 27 Nov 2008 00:49:15 -0500</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/dynamic-properties-in-php-with-stdclass</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/dynamic-properties-in-php-with-stdclass</feedburner:origLink></item>
				<item>
			<title>How does the quality of political candidates’ websites correlate with campaign success?</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/3y-B0hr6oN8/how-does-the-quality-of-political-candidates%e2%80%99-websites-correlate-with-campaign-success</link>
			<description>&lt;a href="http://www.votethesite.com/"&gt;VoteTheSite.com&lt;/a&gt;, a micro-site my good friends at &lt;a href="http://www.newmediacampaigns.com"&gt;New Media Campaigns&lt;/a&gt; have built, is conducting an on-line experiment to explore just that question. &lt;a href="http://www.votethesite.com/"&gt;VoteTheSite.com&lt;/a&gt; pits congressional candidates’ websites against each other race-by-race. Races can be viewed &lt;a href="http://www.votethesite.com/races/chance"&gt;randomly&lt;/a&gt; or by &lt;a href="http://www.votethesite.com/races"&gt;state&lt;/a&gt;. I was surprised by the range of quality congressional websites have. From top notch sites in &lt;a href="http://www.votethesite.com/races/show/168"&gt;Texas' 5th&lt;/a&gt; to the really poor websites in &lt;a href="http://www.votethesite.com/races/show/378"&gt;Georgia's 1st&lt;/a&gt; they run the quality gamut.
&lt;p&gt;
&lt;a href="http://www.votethesite.com/"&gt;&lt;img class="size-full wp-image-446" title="VoteTheSite.com" src="http://files.kris.gethifi.com/votethesite.jpg" alt="VoteTheSite.com - Vote on Political Websites" width="300" height="213" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
After the elections have taken place the votes on websites will be tallied up and compared to election results. Should be really interesting to see what the outcome is and how strong website quality correlates with campaign success.
&lt;/p&gt;&lt;p&gt;
Within the first 24 hours over 5,000 votes have been cast. Congrats to the &lt;a href="http://www.newmediacampaigns.com"&gt;New Media&lt;/a&gt; team for getting this out the door so quickly (with a little help from the Mechanical Turk)! &lt;a href="http://www.votethesite.com/races"&gt;Go vote on the websites in your state&lt;/a&gt;…
&lt;/p&gt;&lt;p&gt;
VoteTheSite.com was written (in under 2 days!) on an early version of the PHP Framework, the &lt;a href="http://www.recessframework.com/"&gt;Recess! Framework&lt;/a&gt;, I’ve had my head down plugging away on the past couple of weeks. Expect blog activity to pick up as the &lt;a href="http://www.recessframework.com/"&gt;Recess! Framework&lt;/a&gt; moves closer to a public release. Sign up to be notified of the release at &lt;a href="http://www.recessframework.com/"&gt;RecessFramework.com&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=3y-B0hr6oN8:j7YMtZGchto:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=3y-B0hr6oN8:j7YMtZGchto:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=3y-B0hr6oN8:j7YMtZGchto:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=3y-B0hr6oN8:j7YMtZGchto:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=3y-B0hr6oN8:j7YMtZGchto:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Wed, 29 Oct 2008 17:11:41 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/10/29/how-does-the-quality-of-political-candidates%e2%80%99-websites-correlate-with-campaign-success</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/10/29/how-does-the-quality-of-political-candidates%e2%80%99-websites-correlate-with-campaign-success</feedburner:origLink></item>
				<item>
			<title>Hello Again, Old Friend: Revisiting a PHP Framework</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/gwP4s19G_Oc/hello-again-old-friend-revisiting-a-php-framework</link>
			<description>&lt;p&gt;I'm in the process of replumbing the lightweight PHP application framework I wrote with &lt;a href="http://www.jsuth.com/"&gt;Joel Sutherland&lt;/a&gt; over three years ago. Its original design was inspired by the &lt;a href="http://struts.apache.org/"&gt;Java Struts Framework&lt;/a&gt;. It enabled us to rapidly develop the first version of &lt;a href="http://www.newmediacampaigns.com/"&gt;New Media Campaigns&lt;/a&gt;' &lt;a href="http://www.newmediacampaigns.com/page/content-management"&gt;website management software&lt;/a&gt;. Two summers ago we did a major redesign inspired by the &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt; nature of &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;. Since then Joel and &lt;a href="http://www.joshlockhart.com/"&gt;Josh Lockhart&lt;/a&gt; have been tweaking the framework by addressing the issues which crop up after their intensive use while rewriting New Media's system. 
&lt;/p&gt;&lt;p&gt;
Energized by &lt;a href="http://www.krisjordan.com/live-blogging-from-web-20-expo-new-york/"&gt;what I saw at the Web 2.0 Expo&lt;/a&gt; in NY I'm back at it again. My three big goals with this take:
&lt;/p&gt;&lt;p&gt;
1) &lt;strong&gt;Get it in the wild: Open source with an &lt;a href="http://en.wikipedia.org/wiki/MIT_License"&gt;MIT license&lt;/a&gt;&lt;/strong&gt;. This is going to happen before the New Year. Hopefully sooner. We intended to do this with V2. It actually &lt;em&gt;was &lt;/em&gt;publicly available in 2006 for a brief period of time but without any real plan for evangelism. I've been using open source software for a long time and its high time to give back.
&lt;/p&gt;&lt;p&gt;
2) &lt;strong&gt;Play nice in the new RESTful world.&lt;/strong&gt; If I had to bet on a paradigm for interacting with web APIs I would bet the farm on &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt;. It is perfectly aligned with the grain of the web. Most existing frameworks written without an emphasis on REST have made awkward face lifts to adapt. When revisiting our own framework and considering how to make it properly RESTful this would have held true if not for...
&lt;/p&gt;&lt;p&gt;
3) &lt;strong&gt;Signficantly &lt;/strong&gt;&lt;strong&gt;Improving the Architecture.&lt;/strong&gt; Revisiting old code is a joy. It's easy to forget how clever you were and how much work you did. Yet it's very disturbing to realize how hacked some of the fundamental design was. As mentioned, the current version was influenced significantly by what Rails plumbing looked like circa-2006. Since then two really important things have changed: 1) the emphasis on tying closer to HTTP protocol, and 2) two additional years of experience with systems design under the belt.
&lt;/p&gt;&lt;p&gt;
So, &lt;em&gt;here's to take 3&lt;/em&gt;! Bits available for download in upcoming months. E-mail me at krisjordan/gmail if interested in being copied on barely functional, pre-release bits in the mean time. Otherwise, &lt;a href="http://feeds.feedburner.com/KrisJordan/"&gt;stay tuned&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=gwP4s19G_Oc:mNRE5KRPTrI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=gwP4s19G_Oc:mNRE5KRPTrI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=gwP4s19G_Oc:mNRE5KRPTrI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=gwP4s19G_Oc:mNRE5KRPTrI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=gwP4s19G_Oc:mNRE5KRPTrI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Wed, 08 Oct 2008 13:26:45 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/10/08/hello-again-old-friend-revisiting-a-php-framework</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/10/08/hello-again-old-friend-revisiting-a-php-framework</feedburner:origLink></item>
				<item>
			<title>Brainstorming Ideas with Sharpies &amp; Sticky Notes</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/s19t19yjb88/brainstorming-ideas-with-sharpies-sticky-notes</link>
			<description>&lt;p&gt;After getting a &lt;a href="http://www.krisjordan.com/2008/09/07/10-minute-mock-prototyping-tips-for-powerpoint/"&gt;comment&lt;/a&gt; from &lt;a href="http://talk.presentationsroundtable.com/"&gt;Ric Bretschneider&lt;/a&gt; of Microsoft's &lt;a href="http://blogs.msdn.com/powerpoint/archive/2008/09/14/one-more-special-intern.aspx"&gt;PowerPoint team&lt;/a&gt; I came across the book &lt;a href="http://www.amazon.com/gp/product/0596522347?ie=UTF8&amp;amp;tag=krijoronsofst-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596522347"&gt;slide:ology&lt;/a&gt; on his site &lt;a href="http://talk.presentationsroundtable.com/"&gt;Presentations Roundtable&lt;/a&gt;.  I picked up &lt;a href="http://www.amazon.com/gp/product/0596522347?ie=UTF8&amp;amp;tag=krijoronsofst-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596522347"&gt;slide:ology&lt;/a&gt; from a bookstore on my way out to New York and it is a great piece of work (and art!) authored by &lt;a href="http://slideology.com/contributors/"&gt;Nancy Duarte&lt;/a&gt; of &lt;a href="http://www.duarte.com/"&gt;Duarte Design&lt;/a&gt;. Duarte Design is the firm behind Al Gore's "An Inconvenient Truth" &lt;a href="http://www.duarte.com/#1.0.0"&gt;Keynote slide deck&lt;/a&gt;. They are also the designers of &lt;a href="http://www.ted.com/index.php/talks/john_doerr_sees_salvation_and_profit_in_greentech.html"&gt;John Doerr's TED talk&lt;/a&gt;'s deck. Duarte Design is truly first class.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.krisjordan.com/wp-content/uploads/2008/10/stickynotesexcerpt.jpg"&gt;&lt;img class="size-thumbnail wp-image-426" title="Innovating with Sticky Notes" src="http://files.kris.gethifi.com/stickynotesexcerpt-150x150.jpg" alt="Innovating with Sticky Notes" width="105" height="105" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
A technique that caught my eye was "Innovating with Sticky Notes" (p28). The premise is to use a sharpie and generate ideas on sticky notes. One idea per sticky note (the bonus of using a sharpie is that is about all you can fit). Just unleash as many ideas as possible and get them up on the wall. Structure and flow can then be orchestrated by rearranging the notes.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.krisjordan.com/wp-content/uploads/2008/10/stickynotes.jpg"&gt;&lt;img class="size-thumbnail wp-image-427" title="stickynotes" src="http://files.kris.gethifi.com/stickynotesexcerpt-150x150.jpg" alt="Idea Notes for Chord Talk" width="105" height="105" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
I decided to give the sticky note method a shot with a talk I'm giving on the &lt;a href="http://en.wikipedia.org/wiki/Chord_project"&gt;Chord Protocol&lt;/a&gt; in a &lt;a href="http://www.cs.unc.edu/~dewan/290/f08/"&gt;graduate class&lt;/a&gt; I'm auditing at UNC. I must admit I really liked the technique after trying it out. It's quick and dirty and prevented me from getting lost in details and aesthetics. My focus remained on the big ideas and overall message I wanted to 'teach'. I would even go so far as to say that it's &lt;em&gt;fun&lt;/em&gt;. Once I'm done with the talk I'll narrate a slideshow and throw it up on here so you can see the end result.
&lt;/p&gt;&lt;p&gt;
This sharpie + sticky notes method is only a detail in the grand thesis of Nancy Duarte's &lt;a href="http://slideology.com/"&gt;slide:ology&lt;/a&gt;. Spend some quality time with &lt;a href="http://www.amazon.com/gp/product/0596522347?ie=UTF8&amp;amp;amp;tag=krijoronsofst-20&amp;amp;amp;linkCode=as2&amp;amp;amp;camp=1789&amp;amp;amp;creative=9325&amp;amp;amp;creativeASIN=0596522347"&gt;this book&lt;/a&gt; before you prepare your next presentation, you won't regret it.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;Aside: if you're going to use this technique on a wall at a coffee shop be prepared for inquisitive looks! :)&lt;/p&gt;
&lt;/em&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=s19t19yjb88:SOIp_5nk4lk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=s19t19yjb88:SOIp_5nk4lk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=s19t19yjb88:SOIp_5nk4lk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=s19t19yjb88:SOIp_5nk4lk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=s19t19yjb88:SOIp_5nk4lk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Wed, 01 Oct 2008 20:17:48 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/10/01/brainstorming-ideas-with-sharpies-sticky-notes</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/10/01/brainstorming-ideas-with-sharpies-sticky-notes</feedburner:origLink></item>
				<item>
			<title>10 High Order Bits from the Web 2.0 Expo in NY</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/zGZspOISsRs/10-high-order-bits-from-the-web-20-expo-in-ny</link>
			<description>&lt;h3&gt;&lt;a href="http://www.krisjordan.com/2008/09/17/david-heinemeier-hansson-go-rest-with-rails/"&gt;&lt;img class="alignright size-thumbnail wp-image-223" title="WS - Deathstar" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="105" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;10. &lt;a href="http://www.krisjordan.com/2008/09/17/david-heinemeier-hansson-go-rest-with-rails/"&gt;Your Web App: Give it a REST&lt;/a&gt;&lt;/h2&gt;
&lt;a href="http://www.krisjordan.com/2008/09/17/david-heinemeier-hansson-go-rest-with-rails/" target="_blank"&gt;David Heinemier Hansson's session&lt;/a&gt; about making &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; RESTful cast this battle as an epic one between the REST Rebels and the Imperial &lt;strong&gt;WS-*&lt;/strong&gt; Death Star. It's going to be a tough fight but you know who's gonna win.
&lt;p&gt;
REST (&lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Representational State Transfer&lt;/a&gt;) is the elegant architecture and set of conventions first presented in &lt;a href="http://en.wikipedia.org/wiki/Roy_Fielding"&gt;Roy Fielding&lt;/a&gt;'s PhD dissertation "&lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm"&gt;Architectural Styles and the Design of Network-based Software Architectures&lt;/a&gt;". It is well aligned with the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html" target="_blank"&gt;HTTP protocol&lt;/a&gt; and much simpler to implement and use than SOAP, XMLRPC, etc.
&lt;/p&gt;&lt;p&gt;
Implementing RESTful APIs in web applications is getting really easy with leading frameworks like &lt;a href="http://www.rubyonrails.org/"&gt;Rails&lt;/a&gt; and Cake supporting REST as a first-class citizen. The &lt;a href="http://en.wikipedia.org/wiki/Atom_(standard)"&gt;Atom format&lt;/a&gt; is leading the charge as a RESTful format supported by the big players: Google, &lt;a href="http://www.infoq.com/news/2008/03/microsoft-atompub"&gt;Microsoft&lt;/a&gt;, Yahoo, Twitter, etc.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.krisjordan.com/2008/09/18/clay-shirky-keynote/"&gt;&lt;img class="alignright size-thumbnail wp-image-289" title="Clay" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="105" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;9. &lt;a href="http://www.krisjordan.com/2008/09/18/clay-shirky-keynote/"&gt;"It’s Not Information Overload, It’s Filter Failure" &lt;/a&gt;&lt;/h2&gt;
&lt;a href="http://en.wikipedia.org/wiki/Clay_Shirky"&gt;Clay Shirky's talk&lt;/a&gt; states that since the invention of the printing press humans have always faced information overload. We have been surrounded by more information than we can consume in an entire lifetime for centuries. The problem is not information over load, it's filter failure. We need better filters.
&lt;p&gt;
&lt;a href="http://en.wikipedia.org/wiki/Jay_Adelson"&gt;Jay Adelson&lt;/a&gt; of &lt;a href="http://www.digg.com"&gt;Digg&lt;/a&gt; believes building better filters is exactly the mission Digg and other players in the collaborative filter space are addressing.&lt;/p&gt;
&lt;h2&gt;&lt;img class="alignright size-thumbnail wp-image-382" title="iPhone GPS" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="105" /&gt;8. &lt;a href="http://www.krisjordan.com/2008/09/18/andrew-turner-mikel-maron-trends-and-technologies-in-where-20/"&gt;Sensor Driven Data: The Web is Getting Orwellian&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With Apple putting GPS in iPhones, Google putting GPS in Android, Nikon putting GPS in the Coolpix P6000, and ... you get the point. GPS, motion sensors, video recorders, microphones, and other sensors are increasingly distributed and surrounding us.
&lt;/p&gt;&lt;p&gt;
Tim O’Reilly believes a BIG revolution is happening Here. Tim is really bullish on sensor driven data. &lt;a href="http://en.oreilly.com/where2008/public/content/home"&gt;Where 2.0 has its own O'Reilly Conference&lt;/a&gt;. This space is heating up fast.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.jquery.com/"&gt;&lt;img class="alignright size-thumbnail wp-image-378" title="jQuery" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="37" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;7. &lt;a href="http://www.jquery.com" target="_blank"&gt;Javascript is Bringing Sexy Back to the Browser&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;John Resig gave a session on &lt;a href="http://www.krisjordan.com/2008/09/17/john-resig-building-a-visualization-language/"&gt;processing.js&lt;/a&gt;, his visualization engine running atop the HTML5 Canvas. The canvas has really low level functionality, a la OpenGL for 2-D surfaces, but with the right libraries in place it can lead to some truly impressive results. Flickr's Paul Hammond gave perhaps the most compelling story of the use of Javascript and Canvas. After building Flickr Stats, using Canvas for graph visualizations, a team member loaded a page on an iPhone. It just flat out worked.
&lt;/p&gt;
Unfortunately my friends over at Microsoft are slowing down the progress here with no planned support for the HTML5 Canvas in IE8. Google's &lt;a href="http://excanvas.sourceforge.net/"&gt;excanvas&lt;/a&gt; gets around this for IE users by mapping to VML. Unfortunately excanvas currently only works in quirks mode in IE8. &lt;em&gt;Damnit Microsoft&lt;/em&gt;, you've brought IE8 a long ways towards being a modern, friendly player on the web, why not support Canvas? &lt;em&gt;Come on Oz, come on.&lt;/em&gt;
&lt;h3&gt;&lt;a href="http://dataportability.org/"&gt;&lt;img class="alignright size-thumbnail wp-image-313" title="Data Portability" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="96" height="96" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;6. &lt;a href="http://www.krisjordan.com/2008/09/19/joseph-smarr-tying-it-all-together-implementing-the-open-web/" target="_self"&gt;The Open Web is Nearing the Tipping Point&lt;/a&gt;&lt;/h2&gt;
&lt;a href="http://www.dataportability.org/"&gt;DataPortability&lt;/a&gt; co-founders Chris Saad and Daniela Barbosa gave a &lt;a href="http://www.krisjordan.com/2008/09/18/chris-saad-daniela-barbosa-understanding-the-basics-of-personal-data-and-dataportability/" target="_blank"&gt;great session&lt;/a&gt; on the basic motivations behind the movement. The future the DataPortability group is trying to create, one which allows us to owning our data, our contacts, our relationships, etc. and be able to move them freely and easily between the on-line systems we use sounds truly empowering. The big players are joining the party: Microsoft, Google, Facebook, Six Apart, Linked In, Yahoo, Digg, Plaxo, MySpace. But Chris says "Who cares about them? This is a grassroots effort!"

&lt;a href="http://www.josephsmarr.com/"&gt;Joseph Smarr&lt;/a&gt;, Chief Architect of &lt;a href="http://www.plaxo.com"&gt;Plaxo&lt;/a&gt;, gave another &lt;a href="http://http://www.krisjordan.com/2008/09/19/joseph-smarr-tying-it-all-together-implementing-the-open-web/"&gt;interesting session&lt;/a&gt; on the major components of the open web and how they fit together. OAuth, OpenID, Open Social, and others were covered. The feeling I walked away with is that &lt;em&gt;we're a lot closer than I thought.&lt;/em&gt;
&lt;h2&gt;&lt;a href="http://danga.com/"&gt;&lt;img class="alignright size-thumbnail wp-image-388" title="Danga" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="105" /&gt;&lt;/a&gt;5. &lt;a href="http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/" target="_blank"&gt;Web Scalability thanks to Async &amp;amp; Danga&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;"You can’t drop something in 40,000 buckets, synchronously, at once", said Digg's Lead Architect, Joe Stump in his session "&lt;a href="../2008/09/18/joe-stump-scaling-digg-and-other-web-applications/"&gt;Scaling Digg and Other Web Applications&lt;/a&gt;". He was referencing what happens when Kevin Rose posts a message on Twitter. (&lt;a href="http://twitter.com/kevinrose"&gt;Rose&lt;/a&gt; &lt;em&gt;actually &lt;/em&gt;has nearly 65,000 followers on Twitter) Asynchronous task queuing is how the folks at Digg, Twitter, and Flickr deal with problems that are &lt;em&gt;really hard&lt;/em&gt; to do in real time in any scalable fashion.
&lt;/p&gt;&lt;p&gt;
Just about all of Brad Fitzpatrick's (of LiveJournal and OpenID fame) lightweight systems software, freely available at Danga.com, seems to be used by the biggest Web 2.0 players to achieve scale. That memcached, gearman, perlbal, djabberd, and mogilefs, all came out of Fitzpatrick and Danga is just incredible. No wonder Google gobbled him up from Six Apart.&lt;/p&gt;
&lt;h3&gt;&lt;img class="alignright size-medium wp-image-377" title="Twitter API" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="119" height="28" /&gt;&lt;/h3&gt;
&lt;h2&gt;4. &lt;a href="http://www.krisjordan.com/2008/09/16/web-20-expo-building-successful-next-generation-web-20-apps-from-dion-hinchcliffe/"&gt;Web 2.0 Traffic: It's Out-of-Band
&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The knowledge tidbit that stuck out more in my mind than any other was that Twitter gets 10 times the amount of traffic from its API than it does through its website. It makes sense, I'd just never acknowledged it explicitly. &lt;a href="http://www.krisjordan.com/2008/09/16/web-20-expo-building-successful-next-generation-web-20-apps-from-dion-hinchcliffe/"&gt;Dion Hinchcliffe's workshop&lt;/a&gt; painted a similar story for many other Web 2.0 successes. The canonical example is YouTube with the embedded video. The decision to put html snippets plainly visible, right beside of the video, was perhaps their most genius move. Modern web applications and services are making themselves relevant by opening as many channels of distribution possible through feeds, widgets, badges, and programmable APIs.&lt;/p&gt;
&lt;h3&gt;&lt;a href="http://www.php.net"&gt;&lt;img class="alignright size-thumbnail wp-image-375" title="PHP" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="84" height="47" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;3. &lt;a href="http://www.krisjordan.com/2008/09/16/cal-henderson-scalable-web-architectures-common-patterns-and-approaches/" target="_blank"&gt;Cal Henderson's PHP Tent Revival&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If not for Cal Henderson I may have never have touched PHP again. I'm probably going to come back to this topic in more depth in a future post but Cal's workshop "&lt;a href="http://www.krisjordan.com/2008/09/16/cal-henderson-scalable-web-architectures-common-patterns-and-approaches/"&gt;Scalable Web Architectures: Common Patterns and Approaches&lt;/a&gt;" renewed my interest in, relationship with, and respect for PHP. The funny thing is that wasn't even the point of the talk. Cal and &lt;a href="http://www.krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications/"&gt;Joe Stump of Digg&lt;/a&gt;'s succinct point that &lt;em&gt;Langauges Don't Scale&lt;/em&gt; is right on. Sure PHP isn't as beautiful, trendy, or well designed as Python or Ruby are. However, some of the design decisions made by PHP's Rasmus, specifically the 'shared nothing'ness, make it a great technology for web applications. There's a reason why Facebook, Digg, Flickr, and co. are still on it.
&lt;/p&gt;
After Cal's workshop I asked him: &lt;strong&gt;if you could do it all over again with Flickr would you choose to go with Python or Ruby?&lt;/strong&gt; Cal's answer: &lt;strong&gt;Nope, I'd do it in PHP.&lt;/strong&gt;
&lt;h3&gt;&lt;a href="http://www.krisjordan.com/2008/09/17/jason-fried-10-things-weve-learned-at-37signals/"&gt;&lt;img class="alignright size-thumbnail wp-image-376" title="Bambi on Ice" src="http://files.kris.gethifi.com/ws-deathstar-150x150.jpg" alt="" width="105" height="105" /&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h2&gt;2. &lt;a href="http://www.krisjordan.com/2008/09/17/jason-fried-10-things-weve-learned-at-37signals/" target="_blank"&gt;Set Your Baby Free&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;By grooming and nurturing a web app internally for an extended period of time is you lose a lot of value. &lt;a href="http://www.krisjordan.com/2008/09/17/jason-fried-10-things-weve-learned-at-37signals/"&gt;Jason Fried&lt;/a&gt;'s notion of "half a product is better than a half-assed product" is so fitting here. &lt;a href="http://www.krisjordan.com/2008/09/18/sandy-jen-scaling-synchronous-web-apps-lessons-learned-from-meebo/"&gt;Sandy Jen of Meebo echoes similar notions in her talk&lt;/a&gt;: Start out with something simple, see if it works, evolve. Bring your customers into the feedback loop as quickly as possible. Joshua Schachter, founder of delicious, spoke of the exact same sentiments in his talk on "&lt;a href="http://www.krisjordan.com/2008/09/17/joshua-schachter-lessons-learned-in-scaling-and-building-social-systems/"&gt;Scaling and Building Social Systems&lt;/a&gt;".&lt;/p&gt;
&lt;h2&gt;1. Want to Set the World on Fire? &lt;em&gt;YOU &lt;/em&gt;Better Bring the Fire.&lt;/h2&gt;
&lt;em&gt;If &lt;span style="text-decoration: underline;"&gt;you&lt;/span&gt; are not bringing the heat, get out of the kitchen&lt;/em&gt;. Passion was the common thread amongst the most inspiring talks I saw at the conference. Between &lt;a href="http://garyvaynerchuk.com/"&gt;Gary Vaynerchuk&lt;/a&gt;, &lt;a href="http://www.37signals.com/"&gt;Jason Fried&lt;/a&gt;, and &lt;a href="http://www.huffingtonpost.com/"&gt;Arianna Huffington&lt;/a&gt; the message was  consistent: be passionate. I'm going to let Gary roll this one out with his amazingly energetic keynote on building personal brand...

&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="390" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="src" value="http://blip.tv/play/Ac6tAIa8DQ" /&gt;&lt;embed type="application/x-shockwave-flash" width="480" height="390" src="http://blip.tv/play/Ac6tAIa8DQ"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=zGZspOISsRs:H83zH4_7eMI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=zGZspOISsRs:H83zH4_7eMI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=zGZspOISsRs:H83zH4_7eMI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=zGZspOISsRs:H83zH4_7eMI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=zGZspOISsRs:H83zH4_7eMI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 25 Sep 2008 18:41:09 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/25/10-high-order-bits-from-the-web-20-expo-in-ny</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/25/10-high-order-bits-from-the-web-20-expo-in-ny</feedburner:origLink></item>
				<item>
			<title>Joseph Smarr - Tying it All Together: Implementing the Open Web</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/6Icu-huO6Qg/joseph-smarr-tying-it-all-together-implementing-the-open-web</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;em&gt;&lt;a href="http://www.josephsmarr.com/"&gt;Joseph Smarr&lt;/a&gt; is the &lt;a href="http://www.plaxo.com/about/management_team#joseph"&gt;Chief Platform Architect&lt;/a&gt; at &lt;a href="http://www.plaxo.com/"&gt;Plaxo&lt;/a&gt;.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;img class="size-full wp-image-364" title="Joseph Smarr" src="http://files.kris.gethifi.com/joseph_smarr.jpg" alt="Joseph Smarr" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
Lots of open source building blocks for bringing things together. How do all these pieces sit together and what is the landscape going to look like when the dust settles?
&lt;/p&gt;&lt;p&gt;
The social web today is very broken. On each site you have to re-create an account, re-enter profile info, re-find friends, re-establish relationships. New social apps have limited options: create yet-another-silo and start from scratch or make a widget inside of an existing walled garden.
&lt;/p&gt;&lt;p&gt;
There's got to be a better way and there is. Help is on the way. It's coming in the form of new building blocks that establish: who I am, who I know, and what's going on. We're going to aim for the medium level of detail on each of the projects which fit into these building blocks.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Who I am&lt;/strong&gt;: Creating a portable, durable online identity. OpenID is important in this space. OpenID lets you come to a new website and allows you to log-in with an account that exists on another site. You can sign up and sign in with your existing account. You can then link and share your profile data between sites. When you go through Plaxo's sign up you can sign in with any open ID. This takes you over to your identity provider and allows you to verify that you want to share your information with Plaxo. This is good for users and for Plaxo by reducing friction. Yahoo is OpenID, MySpace is on the way, AOL is signed up, some of Google's properties are supported, this has majorly caught on.
&lt;/p&gt;&lt;p&gt;
Consolidate your online identity with me-links for rel=me (XFN). The social graph API allows you to query Google using REST for the downstream me links. This makes it easy to find out more information about users by what exists on the web. Again great for both the consumer in not having to duplicate info and great for businesses in terms of getting data into your systems.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Who I know&lt;/strong&gt;: You need to be able to build and maintain relationships. Until recently the only way you could get at this information was to scrape your webmail address books. It's kind of hacky and insecure. The good news is over the last year that this isn't going away, it's useful, and they've made it easy to practice safe portability. Google, Yahoo, and Microsoft have mechanisms for getting at the information without giving a new service your webmail password. OAuth is a means for sharing private data between trusted sites. A bunch of people came together and came up with a standard way of getting at data. OAuth is supported by Google, MySpace, it's a part of DataPortability. OAuth gives a third party site a token which is revocable. It can be scoped access. Friends-list portability allows for continuous discovery across multiple sites.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://files.kris.gethifi.com/joseph_smarr.jpg"&gt;&lt;img class="size-medium wp-image-365" title="The Open Stack" src="http://files.kris.gethifi.com/joseph_smarr.jpg" alt="The Open Stack" width="300" height="225" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;What's going on?&lt;/strong&gt; Because the entire web is becoming social you're creating and doing interesting things on a lot of different sites. You can't walk each site to check and see who is doing what. OpenSocial is trying to define a standard language for social networking applications on the web. You can drop in widgets that work on all social networking sites. OpenSocial is going mainstream and has over 500 million users by the end of the year. Everyone is agreeing on standard APIs at the server-to-server level. RSS and Atom is another important piece which is often overlooked. It's an important standard for sharing "here's what going on right now." If you put RSS together with OAuth you can get private update feeds. Jabber XMPP is becoming more important, too, it started as an open standard for instant messaging. One of the things they built in as a result is that it is federated. It's a good set of open tools for different sites sending messages to each other.
&lt;/p&gt;&lt;p&gt;
This stuff is out there, it's real, and it fits into these standard blocks. What we'll do now is pull everything together.
&lt;/p&gt;
&lt;strong&gt;How does the friends list portability work?&lt;/strong&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;em&gt;Tell the site your social graph provider&lt;/em&gt;: XRDS-Simple (discovery) + OAuth (access)&lt;/li&gt;
	&lt;li&gt;&lt;em&gt;Site fetches your data to find local friends&lt;/em&gt;: Site fetches your data to find your local friends ??? No standard way to do this yet. A project that's going on and in draft spec is still up and coming is PortableContacts.net.&lt;/li&gt;
	&lt;li&gt;&lt;em&gt;Site lets you connect to people you want&lt;/em&gt;: You can periodically look for new matches.&lt;/li&gt;
&lt;/ol&gt;
&lt;strong&gt;How does contact portability work?&lt;/strong&gt;
&lt;ol&gt;
	&lt;li&gt;User signs in with an OpenId: Site fetches OpenID URL -&amp;gt; looks for X-XRDS-Location, Site parses XRDS-Simple doc to discover available APIs&lt;/li&gt;
	&lt;li&gt;Site tries to access contacts API -&amp;gt; gets a 401: WWW-Authenticate response header specifies OAuth, OAuth discovery (via XRDS) provides OAuth endpoints&lt;/li&gt;
	&lt;li&gt;Site sends user through OAuth&lt;/li&gt;
&lt;/ol&gt;
A resource Joseph wrote on OpenID: &lt;a href="http://www.plaxo.com/api/openid_recipe"&gt;http://www.plaxo.com/api/openid_recipe&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=6Icu-huO6Qg:CzI5OSBfiew:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=6Icu-huO6Qg:CzI5OSBfiew:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=6Icu-huO6Qg:CzI5OSBfiew:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=6Icu-huO6Qg:CzI5OSBfiew:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=6Icu-huO6Qg:CzI5OSBfiew:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 19 Sep 2008 16:39:22 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/19/joseph-smarr-tying-it-all-together-implementing-the-open-web</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/19/joseph-smarr-tying-it-all-together-implementing-the-open-web</feedburner:origLink></item>
				<item>
			<title>Jeffrey Zeldman and Panel - Content Matters</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/b91vwqhZzQQ/jeffrey-zeldman-and-panel-content-matters</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;img class="aligncenter size-full wp-image-350" title="The Panel" src="http://files.kris.gethifi.com/panel.jpg" alt="" width="500" height="140" /&gt;
&lt;/p&gt;
&lt;em&gt;&lt;span style="text-decoration: underline;"&gt;The Panel:&lt;/span&gt;
Liz Danzico – &lt;a href="http://www.bobulate.com"&gt;Bobulate.com&lt;/a&gt; - part information architect, part usability analyst, and part editor.&lt;/em&gt;
&lt;em&gt;Alex Write “Information Architect” – &lt;a href="http://www.nytimes.com"&gt;NyTimes.com&lt;/a&gt; – Previously a UX designer and journalist in California.
Bre Pettis – “Videographer” – &lt;a href="http://www.brepettis.com"&gt;BrePettis.com&lt;/a&gt;, &lt;a href="http://www.etsy.com/"&gt;Etsy.com&lt;/a&gt;
Kristina Halverson – “Content Strategist” – &lt;a href="http://www.braintraffic.com"&gt;BrainTraffic.com&lt;/a&gt;
Jeffrey Zeldman  - “Evangelist” – &lt;a href="http://www.alistapart.com"&gt;AlistApart.com&lt;/a&gt;, &lt;a href="http://www.happycog.com"&gt;HappyCog.com&lt;/a&gt;, &lt;a href="http://www.zeldman.com/"&gt;Zeldman.com&lt;/a&gt;
&lt;p&gt;Paul Ford – “Editor” – &lt;a href="http://www.harpers.org"&gt;Harpers Magazine&lt;/a&gt;, &lt;a href="http://ftrain.com"&gt;ftrain.com&lt;/a&gt;, &lt;a href="http://www.themorningnews.com/"&gt;themorningnews.com&lt;/a&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Liz Danzico Setting Context for Panel Discussion&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
&lt;img class="size-full wp-image-351" title="Liz Danzico" src="http://files.kris.gethifi.com/panel.jpg" alt="" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
The people on this panel are interested in changing your minds on the role of the content in design and user experience mocks. The original name of this talk was: copy matters.
&lt;/p&gt;&lt;p&gt;
You may have heard these two conflicting views: 1. Content drives traffic. Content certainly is a primary reason for users to come to you. 2. Users don’t read on-line (Jakob Nielsen).
&lt;/p&gt;&lt;p&gt;
We will be talking about whether we are at a cross-roads. Going back a little bit in history to transitions in media, people referred to television as radio with pictures. When movies and television were first made cameras were stationary. Early MTV was just bands on the stage playing. When we make transitions from old to new we borrow metaphors from old technology and apply them to the new. As we look at the web as a publishing medium we’re looking at a different publishing medium. Different responsibilities for makers, editors, etc.
&lt;/p&gt;&lt;p&gt;
“&lt;strong&gt;We aren’t writing, we are speaking in text&lt;/strong&gt;.” – Erika Hall of Mule Design.
&lt;/p&gt;&lt;p&gt;
“&lt;strong&gt;The internet looks like writing, but it’s actually a conversation.&lt;/strong&gt;” –Khoi Vinh, NYTimes.com
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;What kind of content are we talking about in the panel?&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Navigation &amp;amp; Orientation content&lt;/strong&gt; – Daytum.com, Flickr.com with rotating greetings setting the tone in different languages. Navigation on CNN is an example of clear communication on sub-pages. Matched with URL and page hierarchy.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Labels &amp;amp; Action&lt;/strong&gt; – Vimeo with its labels. Geni.com as a quick review of what labels are.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Help Content &lt;/strong&gt;– Tick “Just kidding I Remember Now” link next to “Send me my password”.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Non-textual content&lt;/strong&gt; – Visual content like election maps, photos, info visualization.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Content, content, !&lt;/strong&gt; – Marketing communications sites like Business Week with Editorial Content, etc.
&lt;/p&gt;&lt;p&gt;
With this new publishing model and these new types of content, how are we going to make it work? Ask the experts!
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Q) What is the nature of the content work you do? The reason I asked each of you to the panel is because each of you has a different role in content.&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Halverson&lt;/strong&gt;- Typically our clients are dealing with content that helps discuss their products and services. We are trying to help them wrangle, plan for the creation, creating, standards and structures in place to help them govern that content. I got into content strategy because I was handed wire frame to fill content for websites.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Pettis&lt;/strong&gt;- I got into video and videos about how to make things. For two years had a show called video projects. I’m a video guy who thinks print is a part of the past.
&lt;/p&gt;&lt;p&gt;
&lt;img class="size-full wp-image-353" title="Jeffrey Zeldman" src="http://files.kris.gethifi.com/panel.jpg" alt="Jeffrey Zeldman" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman&lt;/strong&gt;- With the magazine I write, with my website I write. I was a journalist and in advertising and copywrite for a long time. When I started websites back in 1995 the whole thing as that it was self publishing. I thought everyone was going to learn HTML and be self –publishing. &lt;strong&gt;I thought everyone would find their voice and try to find an audience.&lt;/strong&gt; With our client services projects we always start with the content, what it is, what’s there, how they’re going to interact with it. We develop content strategy and architecture before we get to design. If you bring design in fairly late in the process you’ve already worn them down. In terms of the magazine it’s a labor of love.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Q: How do you deal with accommodating both organizing content that is purely visual and content that is textual?&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Write&lt;/strong&gt;- NYTimes publishes a lot of content and we increasingly publish a lot of multimedia content: images, slideshows, interactive flash, etc. Issues that come up is around the metadata layer. All of our photos are in a huge database that exist separately from the article database and content management system. We have a good taxonomy to tag articles but we don’t have the same capabilities with issues. From a design point of view we’re constantly trying to figure out how to weave that content into the site.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Pettis &lt;/strong&gt;– The thing I’m excited about on the internet is that people find a passion and get into it and publish about it. I’m on the blogging team at Etsy. We have really passionate users.  What we do with the blog is open it up so that anyone can pitch ideas. We have over 300 authors on the blog. We have a video team of people who want to point cameras at things and record what they’re thinking and doing. It’s a way of sharing passion and excitement.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Q: How are you helping your clients how to become sophisticated publishers of content?&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Halverson &lt;/strong&gt;– That for me is way down the tracks. As an example take a company with 12 different business units serving 122 different markets. Producing content for a lot of audiences. Our process is A) Figuring out where the content is and who is out there B) establish who is publishing content, reviewing content, etc. C) governing consistent brand standards across the content. &lt;strong&gt;There’s a complete infrastructure lacking within many organizations between print marketing and interactive marketing. We start by trying to bring these people into the same umbrella.&lt;/strong&gt; That challenge in some organization is really difficult. They spend all their money on brand and have no idea how to govern and create content.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– I would just like to say it’s mostly luck. Like woody allen said ablout love: sometimes you’re lucky sometimes you’re not. With clients we would turn things over and sometimes the client would use it and take of running, sometimes they wouldn’t. We built a content management system and would write guidelines and sometimes clients would follow them and sometimes they wouldn’t. We’re doing something for a food manufacturer and they make a delicious bar which has a cool brand and has medical implications so the challenge for copy is that there are pages that have to address people with lupus and there are other birds where there are birds with funny sayings. What rules do you give the client for when they use each tone, how to transition? We create matrices and recommendations and if we’re lucky the client has the right people and the right talent to keep it going. You hope that everyone is passionate about the project.&lt;/p&gt;
&lt;em&gt;&lt;strong&gt;
&lt;p&gt;Question: How do you approach content from a user generated view point?&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– I think it’s both. You have to talk about both sides of the equation.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Liz &lt;/strong&gt;– More and more it’s our responsibility as designers to think about creating very good frameworks that are well thought through, intuitive, and provide intuitive roles which people can participate in. That’s one step: designers create a framework to participate. The second step is for users to actually be involved. The third is an editorial responsibility of the client to monitor content.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– &lt;strong&gt;If you abandon the responsibility of editorial control you lose a lot of value.&lt;/strong&gt; If your content is of high quality you’ll get comments of high quality. Generally because the writing is so good at NYTimes there are some really well thought out comments.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Write &lt;/strong&gt;– When user generated content works well it’s when it’s well channeled. If there’s a cacophony of noise you can’t get anything out of it. &lt;strong&gt;At NYTimes you can comment on certain articles but it’s all moderated by a team of people that try to keep the level of discourse civil.&lt;/strong&gt; The notion of just opening things up and letting people go after it leads to craziness.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Ford &lt;/strong&gt;– Another example: how many wiki sites are dead on the web right now?
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– The first site I worked on for a client was Batman Forever in 1995. We had a forum and seeded some content. It went well initially, people used it. But once we were off the job and the movie stopped needing to sell tickets so they stopped keeping track of the forum. Suck.com later did a piece on it. People were making racist comments and trying to have sex with each other.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Ford &lt;/strong&gt;- You can get content for free but you can’t get editing for free.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Halverson &lt;/strong&gt;– We’ve had companies who try to fix their content problems by buying a really expensive CMS. They think the magical content will just arrive. You must plan for, create, and govern content.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– Even Flickr is about constraints. They encourage a certain kind of user.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Halverson &lt;/strong&gt;– Good example but an easy example because the site is for fun. It gets more complicated when the matter is more serious.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Q: What kinds of tips can you give to people who are responsible for creating content?&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Write &lt;/strong&gt;- Part of the design process is what are the words that exist on the page? “The vacuous victory of typesetters over authors.” People tend to think of the web as boxes and content blocks.
&lt;/p&gt;&lt;p&gt;
&lt;img class="size-full wp-image-357" title="Bre Pettis" src="http://files.kris.gethifi.com/panel.jpg" alt="Bre Pettis" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Ford &lt;/strong&gt;– If you are the one doing content make it very easy to get tons of feedback. I’m the sole guy doing web copy on Harpers and I hear back from customers constantly. When you are the person doing the copy it’s your job to make it as straightforward as possible.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Pettis &lt;/strong&gt;– I’m shocked to hear businesses farming out content and passion.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Halverson &lt;/strong&gt;– I often work with people who are responsible for content on top of their many other jobs. &lt;strong&gt;Don’t conceive of and put boxes on your wireframes for content you don’t have time to create and govern. Scale back.&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Zeldman &lt;/strong&gt;– &lt;strong&gt;I think that’s the most important piece of advice I’ve heard today. Scale back.&lt;/strong&gt; If you don’t have the people to do it, you shouldn’t do it. Grow slowly.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=b91vwqhZzQQ:W4eQ55SuYAA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=b91vwqhZzQQ:W4eQ55SuYAA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=b91vwqhZzQQ:W4eQ55SuYAA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=b91vwqhZzQQ:W4eQ55SuYAA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=b91vwqhZzQQ:W4eQ55SuYAA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 19 Sep 2008 15:09:25 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/19/jeffrey-zeldman-and-panel-content-matters</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/19/jeffrey-zeldman-and-panel-content-matters</feedburner:origLink></item>
				<item>
			<title>Jay Adelson - Organizing Chaos: The Growth of Collaborative Filters</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/xWkM0xFmjUE/jay-adelson-organizing-chaos-the-growth-of-collaborative-filters</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="390" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="src" value="http://blip.tv/play/Ac7CEoa8DQ" /&gt;&lt;embed type="application/x-shockwave-flash" width="480" height="390" src="http://blip.tv/play/Ac7CEoa8DQ"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;Jay Adelson is &lt;span class="caps"&gt;CEO&lt;/span&gt; of &lt;a href="http://www.digg.com/"&gt;Digg&lt;/a&gt;, guiding all aspects of the company’s development, growth and management. Under his leadership, Digg has grown to 26 million visitors per month, and is now considered one of the top socially focused Web sites.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;img class="alignright size-full wp-image-340" title="Jay Adelson of Digg" src="http://files.kris.gethifi.com/jay-adelson.jpg" alt="" width="200" height="200" /&gt;Why do collaborative filters matter? How many of you used google? How many of you have used Digg? Any time you take the interests of a group and use that to filter and create relevance for an audience and a group then that is collaborative filtering. Even search is a sense of collaborative filtering, just think about backrub and page rank or clicks on a search result. This has evolved.
&lt;/p&gt;&lt;p&gt;
So what’s changed? Now you’re on the web 24 hours a day. In 2003 Berkeley said there were about 2.3 million sites added every day. Now there’s about a terabyte a day added to the net. This data is dynamic. Privacy and sense of privacy has also changed. Younger generation doesn’t have the same issues associated with privacy that we have and our parents have. How I use my away message on AIM, “I’m at lunch”, whereas my teenage baby sitter’s will say “I’m feeling down” “I’m full”. We are moving from a seek culture to a connecting culture.
&lt;/p&gt;&lt;p&gt;
Let’s break social filtering down into three parts:
&lt;/p&gt;&lt;p&gt;
1) something like a Digg or a Zeitgeist is the same for everyone.
&lt;/p&gt;&lt;p&gt;
2) social networks where I create a subset of groups with just my friends. I can’t use my friends as a judging factor for what might be interesting to me.
&lt;/p&gt;&lt;p&gt;
3) The exciting thing, the point I can leave you with today, is the &lt;strong&gt;hyper-personalization opportunity&lt;/strong&gt;. Instead of looking at a social network, look at everyone and pair you with people like you and use that collective wisdom that are more specifically interesting to you. Since your personal data is going to move from website to the next you have to think about how you can take that information and deliver experiences specific to individual users. Collaborative filters are the key to the monetization to Web 2.0 applications&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=xWkM0xFmjUE:FGb9ZFaGlo4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=xWkM0xFmjUE:FGb9ZFaGlo4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=xWkM0xFmjUE:FGb9ZFaGlo4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=xWkM0xFmjUE:FGb9ZFaGlo4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=xWkM0xFmjUE:FGb9ZFaGlo4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 19 Sep 2008 14:30:45 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/19/jay-adelson-organizing-chaos-the-growth-of-collaborative-filters</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/19/jay-adelson-organizing-chaos-the-growth-of-collaborative-filters</feedburner:origLink></item>
				<item>
			<title>Arianna Huffington in Conversation with Tim O'Reilly</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/-ZSx155d2NY/arianna-huffington-in-conversation-with-tim-oreilly</link>
			<description>&lt;embed src="http://blip.tv/play/Ac6+Z4a8DQ" type="application/x-shockwave-flash" width="480" height="390" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt; 
&lt;p&gt;
&lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Arianna_Huffington"&gt;Arianna Huffington&lt;/a&gt; is an author and nationally syndicated columnist in the United States. She is the founder of &lt;a href="http://www.huffingtonpost.com/"&gt;The Huffington Post&lt;/a&gt;, an online news/commentary website and aggregated blog.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;img class="alignright size-full wp-image-335" title="Huffington and O'Reilly" src="http://files.kris.gethifi.com/huffington.jpg" alt="" width="200" height="200" /&gt;&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: How did you get where you are? People look and think you’re at the center of the new media world.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: &lt;strong&gt;The secret is you must have passion.&lt;/strong&gt; I fell in love with the web when I realized that people without a platform could have one on the web. I love the obsessive/compulsive nature of the web. Even if you don’t own a printing press or the history of a hundred years in business you can reach an audience. We wanted to do three things: we wanted to have an attitude, we wanted to provide a platform for other bloggers (we now have over 2,000), and we wanted to have a community which is central to what we do.&lt;/p&gt;
&lt;p&gt;From day 1 we made sure the comments on the blog were pre-moderated. There is no substitute for pre-moderation. We now have 30 humans who pre-moderate around the clock all year.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Do the moderators actually participate in discussions?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: For now all they do is delete ad-hominem, violent attacks.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Describe your process. I remember a movie about Watergate where there was a huge debate as to whether the news should be front page or not. Do you guys have staff meetings where you debate what news goes front page?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: We’ve got an editorial team. We’ve got a guy who decides the splash headline. We still believe Iraq is the biggest disaster in the history of US Policy. Even when mainstream isn’t following it anymore we are because it is such a catastrophe.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: So you’re kind of like Rupert Murdoch, you don’t necessarily want to be impartial but can promote causes.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: There is a huge difference between us because the &lt;strong&gt;news we run is based on facts&lt;/strong&gt;. When you say you’re giving both sides of the story and one side of the story isn’t based on fact it’s not newsworthy to present it.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: How do you read the current political situation?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: You know, it’s really interesting. Last week we had this amazing phenomenon of the media being distracted. &lt;strong&gt;The selection of Sarah Palin was a little bit like a soap opera.&lt;/strong&gt; People obsessed over all these small stories around her. Did she really sell her plane on eBay? Then, suddenly, reality set-in and the house is on fire. We’ve woken up and I’m glad about it. I wrote about it and felt that Sarah Palin was a Trojan Horse. I really feel she is a major danger.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Let’s talk about financial deregulation. This is a house that’s currently burning. What do you think about what brought us here?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: What brought us here is the illusion that you can have free markets, unregulated bring about public good. Look at the 85 billion we’ve agreed to put into AIG. &lt;strong&gt;America is basically telling the people: if you are big enough you are not going to be allowed to fail. But if you’re an ordinary American and your house is foreclosed then you’re on your own.&lt;/strong&gt; This isn't what America used to be.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Coming back around to Huffington Post as a new media phenomenon. You’re in New York, not California, what has that brought to you?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: We love being in New York. It’s been great for us to be infused in the energy of the city. It’s been a great place for us to recruit young, driven editors. We’ve found great people to work in our technology department. &lt;strong&gt;The key is to be surrounded by people who constantly want to invent and reinvent.&lt;/strong&gt; We are constantly creating new technological tools, bringing in new video, all of it is a part of keeping people engaged.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Why do you think the conservative blogs have failed and progressive blogs are succeeding?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;:  &lt;strong&gt;Conservatives do so well on talk radio because they're great at being blowhards.&lt;/strong&gt; It’s because they can talk without being corrected or checked on facts. They don’t have to speak in truth because no one is pushing back. Progressives do well on the internet because on the internet you have the masses checking your facts and ensuring you’re on top of the truth.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Audience Member&lt;/strong&gt;: I’ve noticed in America we’re engaging the Islamic world. On the other hand our media organizations lacks people who are Muslim American writers.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: First of all that is something we’d like to get better at. If anyone wants to write on any subject of any creed just shoot me an e-mail. It doesn’t have to be politics. Half of our traffic isn’t politics. It could be on any subject.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Do you think the internet will bring greater transparency?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: As you know, radio was a great tool for fascism. I believe &lt;strong&gt;the internet is a great tool for democracy&lt;/strong&gt;. We see the way Obama is using the internet. Without a doubt without the internet Barack Obama would not be the nominee. It’s increasingly become clear that political leaders need the community to be pushing them to do the right thing. People fascinate themselves with polls but they’re awful. At Huffington Post we’ve got this new feature called Pollstrology.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: Could you speak to any of the trends you’re noticing as you bring groups together at the website?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: There is something I’m noticing which I believe is going to be the next big thing of the internet: there is a huge need and longing to unplug and recharge. Our subhead is unplug and recharge. &lt;strong&gt;If all you care about is success and power, sex and money you are still incredibly better off if you unplug and recharge.&lt;/strong&gt; Find an oasis.  We have 2-5 minute breaks.
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Tim&lt;/strong&gt;: What do you do to recharge?&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Arianna&lt;/strong&gt;: I personally do yoga, I hike, I get enough sleep most of the time. If you have any ideas for how to recharge let us know, send them to me.
&lt;/p&gt;
&lt;em&gt;[ &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow the Feed&lt;/a&gt; for notes on talks from other &lt;a href="../live-blogging-from-web-20-expo-new-york/"&gt;web leaders &amp;amp; innovators&lt;/a&gt; at the Web 2.0 Expo in New York going on this week. ]&lt;/em&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=-ZSx155d2NY:qgezLcRbjTs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=-ZSx155d2NY:qgezLcRbjTs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=-ZSx155d2NY:qgezLcRbjTs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=-ZSx155d2NY:qgezLcRbjTs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=-ZSx155d2NY:qgezLcRbjTs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Fri, 19 Sep 2008 13:56:14 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/19/arianna-huffington-in-conversation-with-tim-oreilly</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/19/arianna-huffington-in-conversation-with-tim-oreilly</feedburner:origLink></item>
				<item>
			<title>Sandy Jen - Scaling Synchronous Web Apps: Lessons Learned from Meebo</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/_tYVFu5-5ZE/sandy-jen-scaling-synchronous-web-apps-lessons-learned-from-meebo</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;img class="alignright size-full wp-image-323" title="Sandy Jen of Meebo" src="http://files.kris.gethifi.com/sandy_jen.jpg" alt="" width="200" height="200" /&gt;&lt;em&gt;Sandy is a co-founder of &lt;a href="http://www.meebo.com/"&gt;meebo&lt;/a&gt; in Mountain View.  She majored in Computer Science at Stanford. Sandy is the 'Server Chick'.&lt;/p&gt;
&lt;/em&gt;
&lt;p&gt;
Things to keep in mind about scalability: what works for someone else won’t necessarily work for you. You know the most about your stuff. Don’t hire consultants. You built your app. &lt;strong&gt;Don’t get married to a technology but don’t be a total flirt.&lt;/strong&gt; It is a very high cost to rip out your guts and start over again. Remember that this is supposed to be fun. You’re building a product. You always have a customer who will be happy that you’re building this thing for them.
&lt;/p&gt;&lt;p&gt;
Synchronous web applications are very different from asynchronous web applications. Traditionally “async” implies “more complex”. On the web it’s opposite because the browser is meant to be async. If you’re going to build a synchronous app you’re probably taking something that used to be on the desktop to the web. That’s where all the problems of scaling come into. Meebo is a good example of synchronous on the web, so is Gmail, many games out there.
&lt;/p&gt;&lt;p&gt;
Doing synchronous on the web is like trying to fill a square hole with a round peg. The hole is that there are a lot of platforms (OS, browsers, etc). When we test a release we test on all the OSes and the browsers and safari and now chrome. Spotty network connections are not going to be 100% stable, still people using dial-up. The limitation of only being able to have 2 open http requests allowed imposes a serious constraint. &lt;strong&gt;It’s hard to measure how successful a synchronous app is based on traditional page view metrics.&lt;/strong&gt; Alexa doesn’t pick up how much traffic Meebo actually gets in relation to other page view based sites.
&lt;/p&gt;&lt;p&gt;
The peg, the thing you’re shoving into the hole, is the need for instantaneous data transfer. Long polling is challenging because you’re using resources on both the client and the server. This is making the browser do more work. The user experience needs to be seamless and feel fast, light, and feel better than the desktop equivalent.
&lt;/p&gt;&lt;p&gt;
What is synchronous? What has to be synchronous? What doesn’t have to be synchronous? The more you try to dump into synchronous the more trouble you’re going to have trying to scale it. Sometimes you cheat in order to create the seamless user experience.
&lt;/p&gt;&lt;p&gt;
Find the right holes for your pegs: &lt;strong&gt;don’t underestimate server side architecture&lt;/strong&gt;! Type of app determines the type of synchronous scaling. Bottlenecks can be anywhere: memory, CPU, bandwidth, storage, disk i/o. Based on the type of app you’re building it will be in different places. You won’t know where all the bottlenecks are until you let it loose. With Meebo it went from one to another to another. We solved the memory problem a while ago and it’s come back since then.
&lt;/p&gt;&lt;p&gt;
Things that people say are great, synchronous helpers: long polling (COMET) connections without having to poll every 5 seconds. Meebo started with Apache and it wasn’t good for us, so lighttpd was a much better fit. When it comes to compiled vs. interpreted languages it goes either way. &lt;strong&gt;We use C but it’s kind of a bitch to hire for because there aren’t many people doing it any more.&lt;/strong&gt; Databases can be really expensive or really cheap. Start simple and if you need to get more complicated do it when you need to. Memcache is great, we’ll talk about it more later. Load balancers, finally, are just really expensive and you have to buy in pairs.
&lt;/p&gt;&lt;p&gt;
Simple is better unless you’re rich. First question: what am I using it for? Am I using memcache because everyone else is? We tried it at Meebo but it turns out most of our data wasn’t cacheable. What I gaining? Scalability at the cost of maintainability? Can I use DNS round-robin instead of load balancers?  FastCGI vs. web modules vs. PHP? When we first started we didn’t want to reinvent the wheel. We started out really simple with CGI written in PHP. We wound up just writing a module directly into the web server and that’s what we’re still doing today. &lt;strong&gt;Start out with something simple, see if it works, evolve.&lt;/strong&gt; Do I need to save state? Is it persistent? Can I store it in a cookie? Meebo didn’t have user accounts for a year. Launching feedback light is not a bad thing.
&lt;/p&gt;&lt;p&gt;
There’s a constant tug of war between the front-end and the back-end. Whose bug is it anyway? You have to figure out where the workload makes sense. The browser can be really slow. Most of Meebos users use IE. Say you’re using a web request and you pass a lot of data down to the client to process it can really bog down the user experience. Pick one, release it, and ask if it’s slower or faster than the last release. Your users know more about your product than you do. Listen. Efficiency with data transfer: when we first started out I picked variable names with single letters to save bandwidth. Once we started hiring it was confusing.
&lt;/p&gt;&lt;p&gt;
Must find a balance between good enough vs. perfect. &lt;strong&gt;Perfection is enough simplicity in the system to allow for adaptation.&lt;/strong&gt; &lt;strong&gt;Users don’t care how clever you are, they just want their product to work.&lt;/strong&gt; Long polling isn’t perfect, browsers have quirks. Sometimes perfect is not good enough (look at Ruby!). Release enough and things will asymptotically approach perfection. Don’t be afraid to try things.
&lt;/p&gt;&lt;p&gt;
Think ahead but don’t think ahead too much. A great example of this is security. You can spend a long time trying to fix security holes but if your product never ships, who cares? Over designed code is hard to roll back from. Hacky code can work and not be so bad. When you first build you won’t know where you’re going to need to scale so over-thinking the problem is a waste. It’s all about balance.
&lt;/p&gt;&lt;p&gt;
Nothing simulates real life. Have contingency plans on both front-end and back-end. Don’t build flood gates, build dams: One time we rolled out a feature that took a huge amount of bandwidth and we were able to switch it off. When you roll out features be very transparent with your users and say “hey try this out, let us know what you think”, they’ll get a lot less upset when you have to roll it back.
&lt;/p&gt;&lt;p&gt;
Be a user of your own product. Don’t be afraid to break your own product. Stay in the loop of your community and stay in touch with the pulse. What is your firefox/ie breakdown? 70% of Meebo’s users use IE. When we use when we use Meebo? IE.
&lt;/p&gt;&lt;p&gt;
It’s ok to be “Big Brother” in the sense of being aware of what’s going on. &lt;strong&gt;Monitor key areas but don’t go overboard on monitoring, you’ll learn to ignore your alerts.&lt;/strong&gt; Ignoring what systems are telling you in feedback mechanisms are dangerous. Monitoring is being aware of how healthy your system is at any given point. Can I log in? What is our downtime percentage?
&lt;/p&gt;&lt;p&gt;
Final thoughts are that there are no magic solutions to scalability. It’s important for you to know your system like the back of your hand. Correlate effects to the changes you’ve made in your systems. Do not lose sight of your goal: why are you scaling? Finally, remember, &lt;strong&gt;everyone scales differently!&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
[ &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow the Feed&lt;/a&gt; for notes on talks from other &lt;a href="../live-blogging-from-web-20-expo-new-york/"&gt;web leaders &amp;amp; innovators&lt;/a&gt; at the Web 2.0 Expo in New York going on this week. ] &lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_tYVFu5-5ZE:hhJR46rzrNU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_tYVFu5-5ZE:hhJR46rzrNU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=_tYVFu5-5ZE:hhJR46rzrNU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=_tYVFu5-5ZE:hhJR46rzrNU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=_tYVFu5-5ZE:hhJR46rzrNU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 17:01:58 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/sandy-jen-scaling-synchronous-web-apps-lessons-learned-from-meebo</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/sandy-jen-scaling-synchronous-web-apps-lessons-learned-from-meebo</feedburner:origLink></item>
				<item>
			<title>Chris Saad, Daniela Barbosa - Understanding the Basics of Personal Data and DataPortability</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/V7NHF786Iow/chris-saad-daniela-barbosa-understanding-the-basics-of-personal-data-and-dataportability</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;em&gt;Chris is Co-Founder and Chairperson at &lt;a href="http://www.dataportability.org/"&gt;DataPortability Project&lt;/a&gt;. Daniela is Chairperson, Steering Committee and Co-founder at the Dataportability Project.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.dataportability.org"&gt;&lt;img class="alignright size-full wp-image-313" title="data-portability" src="http://files.kris.gethifi.com/data-portability.jpg" alt="" width="200" height="200" /&gt;&lt;/a&gt;There have been many tech inflection points. Intel gave birth to the standardized PC architecture. Windows became a standard for GUIs, drivers, and all the plumbing which allowed for a whole new class of applications to be built. TCP/IP led to the standardization of the the internet. HTTP/HTML brought us the web. We’re moving further and further up the step and we’re getting to the point where we should be thinking about standardizing on the data.
&lt;/p&gt;&lt;p&gt;
The data portability video was done very early on. You’ve got data everywhere, accounts everywhere, profiles everywhere, friends everywhere, contact details. Upload your photos, avatars, music, rinse, and repeat. Again and again and again. Network fatigue. Your data locked up in someone else’s hands.  DataPortability is all about creating a web where information can freely flow through the network.
&lt;/p&gt;&lt;p&gt;
Imagine owning and controlling your relationships. Imagine controlling your calendar, images, and other content. Today we all join Flickr, Digg, Twitter, Facebook, etc. Imagine instead that these applications joined you and that you are the data. These applications had to ask for access to the data. Why? So you can sync your friends between Twitter and Del.icio.us and keep them sync’ed. Go to Kodak.com and print your photos from Facebook.
&lt;/p&gt;&lt;p&gt;
&lt;img class="alignright size-full wp-image-314" title="Daniela" src="http://files.kris.gethifi.com/data-portability.jpg" alt="" width="200" height="200" /&gt;Today we share we comment, we rate, we create. Users sign up, fill out profile, add friends, interact with your stuff, you make money, they share your stuff, you get more traffic. Everything but interacting with your stuff and making money is friction that is repeated at every web site. Why the data lock-in model is actually a myth. Example: Amazon.com has a lot of data on you on their site. Why in the world would they want to release this data? It is because Amazon only has a small slice of the data. They don’t know the searches you do on Google. The data they do have is expiring rapidly. In a DataPortability system you get more data, reduced network fatigue, and more usage of everything.
&lt;/p&gt;&lt;p&gt;
DataPortability means you can access and synchronize the data you have between multiple services.&lt;/p&gt;
&lt;p&gt;In January Robert Scoble, with Plaxo, scraped his contacts from Facebook. This is what we refer to as Scoblegate. It set off a flurry of discussion around the idea of being able to move your data between websites and applications.
&lt;/p&gt;&lt;p&gt;
&lt;img class="alignright size-full wp-image-315" title="Chris Saad" src="http://files.kris.gethifi.com/data-portability.jpg" alt="" width="200" height="200" /&gt;DataPortability, as a group, is not writing any code or providing any code as a group, we’re advocating a stack. There are lots of open questions around security, privacy, ownership, business models, and user education. How can we evangelize and educate for the user?
&lt;/p&gt;&lt;p&gt;
Many of the big vendors are playing: Microsoft, Google, Facebook, Six Apart, Linked In, Yahoo, Digg, Plaxo, MySpace. But who cares about them! “If you’re out there I don’t mean you specifically.” (Haha) The DataPortability Project is an open, grass-roots effort.
&lt;/p&gt;&lt;p&gt;
We have a governance model where everyone can join and get involved immediately. We are experimenting with a radically transparent leadership model. Everyone will own this because everyone has helped to build it. It’s not a product, nor a service, it’s an idea. That means YOU, yes YOU.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=V7NHF786Iow:tolCsIi8FbU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=V7NHF786Iow:tolCsIi8FbU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=V7NHF786Iow:tolCsIi8FbU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=V7NHF786Iow:tolCsIi8FbU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=V7NHF786Iow:tolCsIi8FbU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 16:08:51 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/chris-saad-daniela-barbosa-understanding-the-basics-of-personal-data-and-dataportability</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/chris-saad-daniela-barbosa-understanding-the-basics-of-personal-data-and-dataportability</feedburner:origLink></item>
				<item>
			<title>Joe Stump - Scaling Digg and Other Web Applications</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/aV0mmMn6yaY/joe-stump-scaling-digg-and-other-web-applications</link>
			<description>&lt;em&gt;[Live from Web 2.0 Expo 9/16 - 9/19 &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow along the other Expo Talks in RSS&lt;/a&gt;.]&lt;/em&gt;
&lt;p&gt;
&lt;img class="alignright size-medium wp-image-304" title="Joe Stump" src="http://files.kris.gethifi.com/joe_stump.jpg" alt="" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
&lt;em&gt;Joe Stump is currently the Lead Architect for Digg where   he spends his time partitioning data, creating internal services, and   ensuring the code frameworks are in working order.&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.digg.com"&gt;Digg&lt;/a&gt; by the numbers: 30,000,000 Ron Paul fans. 13,000 requests a second, bunches of servers.
&lt;/p&gt;&lt;p&gt;
“Web 2.0 sucks (for scaling).” Web 1.0 was easy where we had this landrush of just getting content on-line.
&lt;/p&gt;&lt;p&gt;
Web 2.0 somebody had a bright idea that we would turn content over to the users. The problem is people like creating a lot of shit. Web 1.0 was easy to scale because I only needed to worry about a could hundred thousand some records. Now we’ve got a lot more to worry about. Another thing I hate is AJAX which makes interacting with websites really easy. It gives users the ability to create shit even faster.
&lt;/p&gt;&lt;p&gt;
Making your PHP code 300% faster doesn’t matter, it’s not where your bottlenecks are. “PHP Doesn’t Scale” – Cal Henderson. PHP doesn’t scale, Java doesn’t scale, Ruby doesn’t scale – languages don’t scale. When you’re worrying about scale and storing 4 billion kitten photos: how you program it probably doesn’t matter.
&lt;/p&gt;&lt;p&gt;
What’s scaling? Scaling is specialization. As you get bigger and as you grow the solutions being sold to you by vendors won’t cut it. You have to cut your database into different pieces and make it very specialized and specific to your needs. We’re going to talk about some of the techniques we use at Digg. Scaling is also about severe hair loss. I’m not joking. I’m going bald. It’s tough. It’s not easy. You can’t do it alone.&lt;/p&gt;
&lt;p&gt;Often people get confused with scaling out and scaling up. You get to a point where you can’t scale up anymore. You can’t just buy more expensive machines at some point. Everyone is scaling out right now with lots of crappy boxes. We expect to fail.
&lt;/p&gt;&lt;p&gt;
Your mom lied; don’t share. Decentralize, expect failures and just add boxes. Amazon is one of the best at this.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://camelcase.blogspot.com/2007/08/cap-theorem.html"&gt;CAP Theorem&lt;/a&gt; says you can only pick two of the following three: strong Consistency, high Availability, Partition tolerance.
&lt;/p&gt;&lt;p&gt;
What are my options? Denormalize, eventually consistent, parallel, asynchronous, specialize.
&lt;/p&gt;&lt;p&gt;
Denormalization is necessary in partitioned solutions and it’s becoming a huge problem for Digg. If you’re not using queues and messaging systems you’re going to want to look into &lt;a href="http://www.danga.com/gearman/"&gt;gearman&lt;/a&gt; and &lt;a href="http://www.danga.com/djabberd/"&gt;djabberd&lt;/a&gt;. You wonder why things are going slow and you realize you’re doing 5 synchronous trips to the database. You’ve got to make these calls async with either http calls or gearman. One thing Digg is big on is running the numbers before you try and fix a problem. Run the numbers to make sure things actually will work. We’ll discuss a case of this.
&lt;/p&gt;&lt;p&gt;
Memcached, &lt;a href="http://www.danga.com/mogilefs/"&gt;OMG Files! (MogileFS)&lt;/a&gt; Digg uses for icons and photos, &lt;a href="http://www.danga.com/gearman/"&gt;Gearman&lt;/a&gt; is a massively distributed fork, and the new favorite toy: &lt;a href="http://memcachedb.org/"&gt;MemcacheDB&lt;/a&gt; “Will be the biggest new kid on the block in scaling.” Initial tests on a laptop yielded 15,000 writes a second. The developer behind this took Berkley DB and Memcache and brought them together.
&lt;/p&gt;&lt;p&gt;
Caching techniques: cache forever and explicitly expire, have a chain of responsibility. We had a generic expiration time on all objects at Digg. The problem is we have a lot of users and a lot of users that are inactive.  &lt;a href="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern"&gt;Chain-of-Responsibility&lt;/a&gt; pattern creates a chain: mysql, memcache, &lt;a href="http://pecl.php.net/package/APC"&gt;apc&lt;/a&gt;, PHP globals. You’re first going to hit globals, if it has it you’ll get it straight back, if not go to the next link in the chain, etc. Used at Facebook and Digg. If you’re caching fairly static content you can get away with a file based cache, if it’s something requested a bunch go with memcache, if it’s something like a topic in Digg we use &lt;a href="http://pecl.php.net/package/APC"&gt;apc&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Partition your data horizontally (rows a-f on one machine) and vertically (some columns on one table, some on another table). Horizontal when you have so much data you need to spread it across a lot of servers. Vertical scaling: Instead of altering tables, add a new table and add new columns to it, this avoids downtime. Abstract your data access so that the partitioned details are hidden from the user.
&lt;/p&gt;&lt;p&gt;
Green badges at Digg are the bane of Joe’s existence. Similar problem to what Twitter and Digg have. If you take a message from one place and drop it in a bunch of other buckets.  Kevin rose has 40,000 followers. You can’t drop something into 40,000 buckets synchronously. 300,000 to 320,000 diggs a day. If the average person has 100 followers that’s 300,000,000 Diggs day. The most active Diggers are the most followed Diggers. The idea of averages skews way out. “Not going to be 300 queries per second, 3,000 queries per second. 7gb of storage per day. 5tb of data across 50 to 60 servers so MySQL wasn’t going to work for us. That’s where memcachedb comes in.” The recommendation engine is a custom graph database from the R&amp;amp;D department and is eventually consistent. An example of problems you run into at real big scale on a social website.
&lt;/p&gt;&lt;p&gt;
[ &lt;a href="http://feeds.feedburner.com/KrisJordan"&gt;Follow the Feed&lt;/a&gt; for notes on talks from other &lt;a href="../live-blogging-from-web-20-expo-new-york/"&gt;web leaders &amp;amp; innovators&lt;/a&gt; at the Web 2.0 Expo in New York going on this week. ] &lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=aV0mmMn6yaY:Phwptg9g8H8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=aV0mmMn6yaY:Phwptg9g8H8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=aV0mmMn6yaY:Phwptg9g8H8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=aV0mmMn6yaY:Phwptg9g8H8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=aV0mmMn6yaY:Phwptg9g8H8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 15:03:02 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/joe-stump-scaling-digg-and-other-web-applications</feedburner:origLink></item>
				<item>
			<title>Andrew Turner, Mikel Maron - Trends and Technologies in Where 2.0</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/L1ufL389cso/andrew-turner-mikel-maron-trends-and-technologies-in-where-20</link>
			<description>&lt;em&gt;Notes from the Web 2.0 Expo - NY talk given by Andrew Turner and Mikel Maron.&lt;/em&gt;
&lt;p&gt;
&lt;img class="alignright size-full wp-image-298" title="Andrew Turner" src="http://files.kris.gethifi.com/andrew_turner.jpg" alt="" width="200" height="200" /&gt;As people are going out and gathering information on their own we’re collecting a lot of geo-aware data. This is becoming a really hot area. Nokia and TomTom just made big acquisitions. Every Web 2.0 service is starting to add location. You can start mining this information with tools like geocodr.
&lt;/p&gt;&lt;p&gt;
How do you start gathering them together? We started a company called geocommons. We’re taking this massive amount of data and trying to pull it all together. It’s an open database of freely available data with creative commons license. You can see where it came from and who posted it. You can search the data.
&lt;/p&gt;&lt;p&gt;
What about when your communities are supplying a lot of data? In Detroit the city is geocoding walking trails. With Hurricane season there are lots of people geocoding where shelters are. A local NYC company social lite is doing place marking with bars using mobile web. Android has a lot of applications which are innovating on the geo aware capabilities of the phone.
&lt;/p&gt;&lt;p&gt;
Mapvertising is one way in which people are trying to make money in this space. But it’s hard. You don’t want to do a search for a romantic restaurant near you and get back a Hooters advertisement.
&lt;/p&gt;&lt;p&gt;
Once people are sharing all of this there is a problem of privacy. Flickr is looking at casual privacy where you can set who is allowed to see where your photos were taken. Fire eagle is a location brokering system. If you trust Yahoo! they can be the trusted holder of your location. You can specify which sites get which granularity (only zip code, for example) of knowledge of your data.
&lt;/p&gt;&lt;p&gt;
NeoCartography sites like EveryBlock and is trying to focus on the data as opposed to the street. You can look at and understand the area based on data. OpenCycleRoute allows you to re-render a map with the best routes for bikes.
&lt;/p&gt;&lt;p&gt;
We’re launching GeoCommons Maker in a couple of weeks which allows you to create proper maps.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Burning Man Experiment&lt;/strong&gt;&lt;img class="alignright size-full wp-image-299" title="Mikel Maron" src="http://files.kris.gethifi.com/andrew_turner.jpg" alt="" width="200" height="200" /&gt;
&lt;/p&gt;&lt;p&gt;
You may think it’s a bunch of naked hippies in the desert blowing things up, and it is, but it’s a whole lot more than that. You show up in a desert and within a week you have a miniature city. It provides a canvas for trying out upcoming geocoding technologies.
&lt;/p&gt;&lt;p&gt;
We collected over 100 gigabytes of data over the week. These are early results. Why is this important for 2.0 Expo? This is a look at what these technologies can enable. Burning Man Earth was a really interesting iteration in Where 2.0.
&lt;/p&gt;&lt;p&gt;
We took remote sensing data every day. We used pictearth.com, diydrones.ning.com, openaerial.com. We got a small plane with a camera. We were gifted 200 Gallons of Fuel. We took a flight path every morning. Really cool pictures of how the event evolves day after day.
&lt;/p&gt;&lt;p&gt;
&lt;a href="http://www.krisjordan.com/wp-content/uploads/2008/09/burningman.jpg"&gt;&lt;img class="size-thumbnail wp-image-300" title="Burning Man Map" src="http://files.kris.gethifi.com/andrew_turner.jpg" alt="" width="150" height="150" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
Processing with ERMapper, ESRI, Photoshop, Sweat. You also are recording with a GPS device which gives you where each photo is centered. Takes a lot of sweat to get everything lined up.
&lt;/p&gt;&lt;p&gt;
Underlying all of the projects we did is the GeoDjango platform. GeoDjango provides facilities for doing mapping. You can do interesting queries on geographic data pretty much for free.  We took the PDF view of the city map, rasterized, and did rectification. Used ESRI, WMS, and Tiling software (TileCache). OpenLayers is an opensource mapping library in Javascript, has editing tools which allow you to draw over a rectified map.
&lt;/p&gt;&lt;p&gt;
In the Future we’re going to turn this into a social application.
&lt;/p&gt;&lt;p&gt;
OpenStreetMap (OSM) is a free map for the world like Wikipedia for maps.  We export from GeoDjango to OSM XML. Import into OSM through its REST AP. Mapnik + mod_tile. The output is a tiled map. Flickr asked if they could take our tiles and use it for people to tag photos. Was really easy to do because we used basic tiles.
&lt;/p&gt;&lt;p&gt;
We need to start making our map tiles and our geotags time aware because the earth changes. By using OpenStreetMap you can get Garmin maps for free. There’s a freeware product called cGPSMapper. We used Garmin Rinos because they have radio built in so you can see where your friends are. At burning man it was incredibly useful. We also did vehicle tracking by sending packets over ham radio and APRS. Signal picked up by a digipeater which sends the data on. Some which take that positioning data and post it to the internet.
&lt;/p&gt;&lt;p&gt;
OpenViewProject.org – we were at WhereCamp at Yahoo and hacked Google street view’s data. Google sent a cease and desist. So a friend of mine bought a lot of gear and a tricycle so that he could do it himself.
&lt;/p&gt;&lt;p&gt;
Gigapans – a gigapan is a gigapixel image. Greater than 500 megapixels. NASA designed a little, sub $200 robot that captures panoramas and their software stitches it together. There’s a site Gigapan that allows you to view these massive photos and zoom in.
&lt;/p&gt;&lt;p&gt;
Kite Aerial Photography – you can script photos for cannons using their developer kit.
&lt;/p&gt;&lt;p&gt;
Google Earth &amp;amp; SketchUp models – Andrew Johnstone would take photos of art and texture models made in SketchUp.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=L1ufL389cso:-ViKBsOb-zM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=L1ufL389cso:-ViKBsOb-zM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=L1ufL389cso:-ViKBsOb-zM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=L1ufL389cso:-ViKBsOb-zM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=L1ufL389cso:-ViKBsOb-zM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 12:52:12 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/andrew-turner-mikel-maron-trends-and-technologies-in-where-20</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/andrew-turner-mikel-maron-trends-and-technologies-in-where-20</feedburner:origLink></item>
				<item>
			<title>Panel Discussion - Building in the Clouds: Scaling Web 2.0</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/qcSsKqMs3OY/panel-discussion-building-in-the-clouds-scaling-web-20</link>
			<description>&lt;em&gt;Panel: Jason Hoffman (Joyent), Alistair Croll (Bitcurrent), Alex Barnett (From Bungee Labs to Intuit), Dwight Merriman (10Gen), Jinesh Varia (AWS), Pete Koomen (Google)&lt;/em&gt;
&lt;p&gt;
Panel session driven by Q&amp;amp;A.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;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?&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
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?
&lt;/p&gt;&lt;p&gt;
Koomen: With App Engine it’s designed to handle low latency web applications.
&lt;/p&gt;&lt;p&gt;
Varia: Component clouds are great for flexibility. As the abstractions increase you lose flexibility and you also face lock-in on a technology stack.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.&lt;/p&gt;
&lt;strong&gt;&lt;/strong&gt;
&lt;p&gt;
&lt;strong&gt;Q) Centralized computing &amp;amp; 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.&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.&lt;/p&gt;
&lt;strong&gt;&lt;/strong&gt;
&lt;p&gt;
&lt;strong&gt;Q: How much can the edge help?&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
Hoffman: Outside of serving static content like images the edge doesn’t do anything.
&lt;/p&gt;&lt;p&gt;
Merriman: I don’t know that I agree with that because if you’re serving to data in Japan.
&lt;/p&gt;&lt;p&gt;
Hoffman: WAN optimization and network optimization is quite different than edge caching.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Q) How do you measure capacity and performance? What are the metrics you look at?&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
Kooman: Google cares a lot about CPU and latency. We can scale disk easy.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.&lt;/p&gt;
&lt;p&gt;Hoffman: There doesn’t currently exist tooling to take end-user experience and feed that all the way back to capacity planning.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
Barnett: It’s interesting that when we charge for services on a utility model we
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
&lt;strong&gt;Q: How do you guys deal with one rogue app?&lt;/strong&gt;
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
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.
&lt;/p&gt;&lt;p&gt;
Hoffman: If you have to spin up new virtual machines to handle traffic bursts you’re going to miss the burst.
&lt;/p&gt;&lt;p&gt;
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.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=qcSsKqMs3OY:fdHLDnaPNv4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=qcSsKqMs3OY:fdHLDnaPNv4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=qcSsKqMs3OY:fdHLDnaPNv4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=qcSsKqMs3OY:fdHLDnaPNv4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=qcSsKqMs3OY:fdHLDnaPNv4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 12:27:40 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/panel-discussion-building-in-the-clouds-scaling-web-20</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/panel-discussion-building-in-the-clouds-scaling-web-20</feedburner:origLink></item>
				<item>
			<title>Clay Shirky - Filter Failures</title>
			<link>http://feedproxy.google.com/~r/KrisJordan/~3/dsdqXvFrxm0/clay-shirky-keynote</link>
			<description>&lt;embed src="http://blip.tv/play/Ac6tV4a8DQ" type="application/x-shockwave-flash" width="480" height="390" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt; 
&lt;p&gt;
&lt;img class="alignright size-full wp-image-288" title="Clay Shirky" src="http://files.kris.gethifi.com/clay-shirky.jpg" alt="" width="200" height="200" /&gt;&lt;em&gt;Clay Shirky is an American writer, consultant and teacher on the social and economic effects of Internet technologies. He teaches New Media as an adjunct professor at New York University's (NYU) graduate Interactive Telecommunications Program (ITP).&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;
How many of you have seen this chart about information? (Chart of exponential data growth.) For 15 years we've been reading the same story about information overload. You can find stories in 93 that are the same as those that showed up in your RSS feed 3 minutes ago. Why is this?
&lt;/p&gt;&lt;p&gt;
Here's why I think this is: Guttenberg back when he invented the printing press, the cost of printing and the volume of what was being printed in those times was greater than a human could read in their whole life. Since you had to print the books in advance you had to take on all the risk of printing the books. The economic decision was pretty simple: make the editorial team at the publisher figure out what is worth printing.
&lt;/p&gt;&lt;p&gt;
The internet introduced post-guttenberg economics. The cost of producing anything by anyone has fallen through the floor. There's no economic logic requiring that you filter what's good from bad is now way down stream. What we're dealing with now isn't information overload, we're always dealing with that. Thinking about filter failure is the problem. Everyone has a morning ritual of removing spam from their e-mail. Some combination of a mechanical filter and manual filter.
&lt;/p&gt;&lt;p&gt;
All of the filter solutions are temporary because you have to assume that the ammount of information coming in is only going to increase. This is a general system design problem. Let me tell you what happened to a friend of mine: a former student, a colleague and a good friend. Last December decided to break off her engagement. She also had to engage in the 21st century practice of &lt;em&gt;changing the status of her relationship&lt;/em&gt;. Might as well buy a billboard. She has a lot of friends on Facebook, but she also has a lot of &lt;em&gt;friends&lt;/em&gt; on Facebook. She doesn't want all these folks, especially fiance's friends, to find out about this. She goes on to Facebook and thinks she's going to fix this problem. She finds their privacy policy and the interface for managing her privacy. She checks the appropriate check boxes and she's able to go from engaged to single. Two seconds later every single friend in her network get the message. E-mails, IMs, phone is ringing off the hook. Total disasterous privacy meltdown. She did her gradutae thesis on the differences of Friendster, Facebook, and MySpace. She's not an average user. Hard to blame Facebook when they've made so much of an effort. The problem is that managing privacy preferences is an &lt;em&gt;unnatural &lt;/em&gt;act. Not something we're used to.
&lt;/p&gt;&lt;p&gt;
Privacy is a way of managing information flow. What she wanted to do is tell four or five of her friends and allow the information to slowly sweep through the network. That's how it used to work. The big problem we're facing with privacy now is how we're moving from a social system to an engineered, binary system. We live most of our lives not in the bubble of privacy, we have what we called back in the day our personal life. We don't have so much personal life anymore. The inneficiency of information flow wasn't a bug, it was a feature. There was something nice about it being difficult to say things in public. This is a question of filtering.  That's a story of outbound information flow. Spam is a story of inbound.
&lt;/p&gt;&lt;p&gt;
There are some stories that you can't even tell the source. Here' s another story. By the time Chris Avenir was 15 MySpace existed. When he gets to college he enrolls in chemistry class. Because he's 18 he starts the study group on Facebook. He gets 146 of his classmates into the group. &lt;img class="alignright size-full wp-image-289" title="Clay" src="http://files.kris.gethifi.com/clay-shirky.jpg" alt="" width="200" height="200" /&gt;Suddenly he's facing 147 charges, one for setting up the group, one for every student he's working with. They claim he's cheating. What has he done? He's crashed two information flows together. To the inside world they say "come here, have conversations" to the outside world they have quality control "students are top notch." What keeps these apart are that the real world is outside of the walls. What he did on Facebook is break down that wall which gives the outside world the ability to see 146 students in a 'study group'. Facebook is not like a fax machine, not like a studygroup meeting. Facebook turns out to be a lot like Facebook. It's different from what's gone before. Only worth spending time on it because of that difference. There is no simple solution to this problem.
&lt;/p&gt;&lt;p&gt;
This isn't a design problem, it's a mental shift. It's understanding we'll have information overload just the way fish have water. A quote: "when you've faced a problem long enough, maybe it's not a problem, it's a fact." Some of this can be solved with programs: look at Digg, Google, etc. But a lot of it can't. When you're getting deluged with information the question you need to ask yourself is "what filter broke?"&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dsdqXvFrxm0:Dzs-rmw99Qs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dsdqXvFrxm0:Dzs-rmw99Qs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=dsdqXvFrxm0:Dzs-rmw99Qs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KrisJordan?a=dsdqXvFrxm0:Dzs-rmw99Qs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KrisJordan?i=dsdqXvFrxm0:Dzs-rmw99Qs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 09:55:48 -0400</pubDate>
			<guid isPermaLink="false">http://krisjordan.com/2008/09/18/clay-shirky-keynote</guid>
			<category>HiFi</category>
			<author />
		<feedburner:origLink>http://krisjordan.com/2008/09/18/clay-shirky-keynote</feedburner:origLink></item>
			</channel>
</rss>

