Alexei Boronine's Bloghttps://www.boronine.com/2018-02-14T00:00:00-05:00On the Joys of Coworking2018-02-14T00:00:00-05:002018-02-14T00:00:00-05:00Alexei Boroninetag:www.boronine.com,2018-02-14:/2018/02/14/Coworking/<p>You exit the visa office eager to start you first day of work. You take the phone out of
your pocket, open the browser and search for a coworking space. You scroll past "Coworking:
the future of work" and "Reimagining work for the 21st century" until you come upon a …</p><p>You exit the visa office eager to start you first day of work. You take the phone out of
your pocket, open the browser and search for a coworking space. You scroll past "Coworking:
the future of work" and "Reimagining work for the 21st century" until you come upon a promising
link: a coworking space in your neighborhood. You click the link. The screen is blank, you are
loading 8 megabytes of custom fonts. While you wait for the text, you stare at the image slowly
filling up the screen. You are reminded of your childhood and the crackling of a DSL modem until
a sweaty stranger bumps into you, breaking your reverie. The image is loaded—it's a photo
of a brick wall.</p>
<div class="figure">
<img alt="coworking" src="https://www.boronine.com/images/coworking.jpg" />
</div>
<p>You wipe the sweat from your forehead and start to scroll, scanning the text in
that bottom third of your screen unobstructed by the sticky header. The scrolling is laggy
due to a smooth-scroll JavaScript plugin. You search for the only pieces of information you
care about: prices and opening hours. You skim the first paragraph that talks about "building a
community of like-minded individuals". You skim the second paragraph that talks about "fostering
an environment of collaboration”. You reach the bottom of the page where you are asked to book a
tour of the space. No opening hours. No prices. You are furious.</p>
<p>You decide to walk there in hopes of convincing them to take your money. Luckily,
the place is nearby and ten minutes later you are standing at their front door. You open
the door and step inside. The tables have been moved to the side of the room, a dozen people
are sitting in the middle watching a presentation. Nobody is working. You look at the
projector screen. The title is "5 Principles of Leadership in a Digital World". You stand
there in angry resignation until you are approached by a girl in a dress, drinking wine
from a plastic cup. She says hi. You wonder if she works here. You ask her "do you work
here?". She says yes. You tell her that you were hoping to work here today. She tells you
to book a tour of the space. You don’t need a tour of the space. You need an electrical outlet.
You consider asking her to let you sit on the floor next to an electrical outlet, but decide
against it. You tell her something polite and leave.</p>
<p>You take the phone out of your pocket, open Google Maps and search for "starbucks". Luckily,
the place is nearby and ten minutes later you are standing at the counter. You take out your
wallet with shaky overcaffeinated fingers. You order a hot chocolate. You sit down at your little
round table, resting your tired legs. You take a sip of your hot chocolate; it burns your tongue,
going down like a mixture of sand and sugar suspended in boiling water. You cough and take out your
laptop. You cannot work. You open up your word processor and begin writing a blog post.</p>
<p>"What is coworking?" you write, "Coworking is a service that rents the use of an electrical outlet
and a wifi connection." You close the word processor with a faint sense of vindication.</p>
Nix, the purely functional build system2018-02-02T00:00:00-05:002018-02-02T00:00:00-05:00Alexei Boroninetag:www.boronine.com,2018-02-02:/2018/02/02/Nix/<p>This blog post is be about <a class="reference external" href="https://nixos.org/nix/">Nix</a>, "The Purely Functional Package
Manager", a software project as mind-blowingly useful as it is difficult to succinctly define.
What makes Nix so peculiar is that it doesn't seem to aim at implementing specific functionality,
instead implementing primitives that make this functionality trivial. This …</p><p>This blog post is be about <a class="reference external" href="https://nixos.org/nix/">Nix</a>, "The Purely Functional Package
Manager", a software project as mind-blowingly useful as it is difficult to succinctly define.
What makes Nix so peculiar is that it doesn't seem to aim at implementing specific functionality,
instead implementing primitives that make this functionality trivial. This cuts both ways:
on the one hand, it results in a radical simplification of a whole slew of build system and
package management tooling, on the other hand it can be quite puzzling for beginners.</p>
<p>While there are many resources praising Nix as a package manager, it is rarely talked about
as a build system, which it most certainly is. In this post I am going to lay out the problem
with traditional build systems and the way Nix solves it, as well as demonstrate its benefits
using a real-world example, my color space project <a class="reference external" href="http://www.hsluv.org/">HSLuv</a>.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title">Table of Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#the-build-environment-problem" id="id5">The build environment problem</a></li>
<li><a class="reference internal" href="#the-nix-solution" id="id6">The Nix solution</a><ul>
<li><a class="reference internal" href="#what-is-nix" id="id7">What is Nix?</a></li>
<li><a class="reference internal" href="#nix-the-programming-language" id="id8">Nix, the programming language</a></li>
<li><a class="reference internal" href="#nix-the-build-system" id="id9">Nix, the build system</a></li>
<li><a class="reference internal" href="#nixpkgs-the-nix-packages-collection" id="id10">Nixpkgs, the Nix Packages collection</a></li>
</ul>
</li>
<li><a class="reference internal" href="#case-study-hsluv" id="id11">Case Study: HSLuv</a><ul>
<li><a class="reference internal" href="#static-website" id="id12">Static website</a></li>
<li><a class="reference internal" href="#packaging-and-publishing-automation" id="id13">Packaging and publishing automation</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="the-build-environment-problem">
<h2>The build environment problem</h2>
<p>Consider this Makefile rule that makes <tt class="docutils literal">hello.o</tt> from <tt class="docutils literal">hello.c</tt>:</p>
<div class="highlight"><pre><span></span><span class="nf">hello.o</span><span class="o">:</span> <span class="n">hello</span>.<span class="n">c</span>
gcc -c hello.c
</pre></div>
<p>Looks simple, but will <tt class="docutils literal">make hello.o</tt> work as expected? This is not certain, because it
depends on the presence of GCC and on its version, and this is precisely where traditional
build systems throw in the towel. They place the burden of reproducing the build environment
on the programmer, often arming him with little more than a list of software to install
manually.</p>
<p>This problem is generally confronted at the level of a language ecosystem. For example,
in Node.js, you use <tt class="docutils literal">package.json</tt> to specify your build tools. In Python, you might
use a <a class="reference external" href="https://github.com/pypa/pipfile">Pipfile</a> or <tt class="docutils literal">requirements.txt</tt>. And likewise in
every other language, which introduces new problems:</p>
<ol class="arabic simple">
<li>Duplicated effort that goes into build system and dependency management tooling</li>
<li>Duplicated effort that goes into learning the aforementioned tools</li>
<li>Solution is limited to tools that have been packaged for the language at hand, often
by reimplementing them in this language. If the tool you are looking for is not available,
you have to install it manually or use multiple dependency management tools side-by-side,
e.g. NPM and pip.</li>
</ol>
</div>
<div class="section" id="the-nix-solution">
<h2>The Nix solution</h2>
<p>Look again at the sample Makefile from the previous section. Imagine yourself as its original
developer. How do you make sure that when the build is run by another developer, the output is
the same? <strong>By making sure the inputs are identical and the build operation is deterministic</strong> <a class="footnote-reference" href="#id3" id="id1">[1]</a>.
In other words, by making sure the build operation is a <a class="reference external" href="https://en.wikipedia.org/wiki/Pure_function">pure function</a>.</p>
<p>It is not hard to see that a Makefile rule is essentially a function whose arguments and return
value are declared in the first line separated by a colon. How would this function be written in
a purely functional programming language? Keep reading to find out.</p>
<div class="section" id="what-is-nix">
<h3>What is Nix?</h3>
<p>Nix is defined by its creators as "The Purely Functional Package Manager", but it is helpful to
see Nix as part of a set of tools that, like all good software, is structured in layers:</p>
<ol class="arabic simple">
<li>Nix, the purely functional programming language</li>
<li>Nix, the build system (think of GNU Make)</li>
<li>Nix, the package manager</li>
<li>NixOS, the Linux distribution</li>
<li>NixOps, the NixOS deployment/configuration/provisioning tool</li>
</ol>
<p>The project is hosted on <a class="reference external" href="https://nixos.org">nixos.org</a> and appears to advertise its Linux distribution as
the most important layer, but I believe for most developers, most of the benefits can be reaped at the
level of the package manager, which can be <a class="reference external" href="https://nixos.org/nix/download.html">installed on MacOS or a Linux distro of your choosing</a>.</p>
</div>
<div class="section" id="nix-the-programming-language">
<h3>Nix, the programming language</h3>
<p>When Nix is discussed online, one of the top comments is always a criticism of its syntax as if
was a fatal flaw of the language. Having actually used Nix, I was puzzled to see this phenomenon.
Then I realized <a class="reference external" href="http://wiki.c2.com/?SmugLispWeenie">where it was coming from</a> and now I happily
collapse these threads. The syntax is fine, trust me.</p>
<p>For the purposes of this post it is enough to know that the Nix expression language is really
small, covered entirely in a <a class="reference external" href="https://nixos.org/nix/manual/#ch-expression-language">short section of the Nix manual</a>. Alternatively, you can learn it as
part of <a class="reference external" href="http://lethalman.blogspot.de/">Luca Bruno's</a> excellent
<a class="reference external" href="https://nixos.org/nixos/nix-pills/index.html">Nix Pills</a> tutorial, which in my opinion is the
best way to learn Nix.</p>
</div>
<div class="section" id="nix-the-build-system">
<h3>Nix, the build system</h3>
<p>What turns a purely functional programming language into a purely functional build system is the
concept of a <em>derivation</em>, a first-class equivalent to a Makefile rule, i.e. a script that
produces a set of files from a set of inputs: other files or configuration values. After installing
Nix, create a file called <tt class="docutils literal">default.nix</tt> with the following contents:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">hello =</span> pkgs<span class="o">.</span>stdenv<span class="o">.</span>mkDerivation <span class="k">rec</span> <span class="p">{</span>
<span class="ss">name =</span> <span class="s2">"hello"</span><span class="p">;</span>
<span class="ss">builder =</span> <span class="nb">builtins</span><span class="o">.</span>toFile <span class="s2">"builder.sh"</span> <span class="s1">''</span>
<span class="s1"> source $stdenv/setup</span>
<span class="s1"> echo "hello world" > $out</span>
<span class="s1"> ''</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</pre></div>
<p>Here we have defined a derivation named <tt class="docutils literal">hello</tt> that creates a text file. The output of a
derivation is a file that gets created at the path provided by the environment variable
<tt class="docutils literal">$out</tt>. You can do anything inside the builder script, as long as you create a file or
directory at <tt class="docutils literal">$out</tt>. What about that <tt class="docutils literal">pkgs</tt> object? Doesn't it look like useless boilerplate?
It sure does, but fear not, we will be making use of it shortly.</p>
<p>In the meantime, let's build the derivation by running <tt class="docutils literal"><span class="pre">nix-build</span> <span class="pre">-A</span> hello</tt> from the same
directory as the file above:</p>
<div class="highlight"><pre><span></span>$ nix-build -A hello
these derivations will be built:
/nix/store/yhca2sy0z8ilkgymsyyj2l02xxbqk7i8-hello.drv
building path<span class="o">(</span>s<span class="o">)</span> ‘/nix/store/nydwxxqnxigsqslvri4hm4yd71al8dxy-hello’
/nix/store/nydwxxqnxigsqslvri4hm4yd71al8dxy-hello
</pre></div>
<p>Nix stores the output in <tt class="docutils literal">/nix/store</tt> but creates a link in the current directory so you can
inspect it:</p>
<div class="highlight"><pre><span></span>$ cat result
hello world
</pre></div>
<p>You can input files into a derivation by referencing them relative to the <tt class="docutils literal">.nix</tt> file directory.
Inputs are defined as arbitary name/value pairs in the <tt class="docutils literal">mkDerivation</tt> parameter and get passed into
the builder script as identically named environment variables. This means in the example below, the
path to the file <tt class="docutils literal">./foo.txt</tt> will be passed in as the environment variable <tt class="docutils literal">$foo</tt>:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">demo =</span> pkgs<span class="o">.</span>stdenv<span class="o">.</span>mkDerivation <span class="k">rec</span> <span class="p">{</span>
<span class="ss">name =</span> <span class="s2">"demo"</span><span class="p">;</span>
<span class="ss">foo =</span> <span class="o">.</span><span class="l">/foo.txt</span><span class="p">;</span>
<span class="ss">builder =</span> <span class="nb">builtins</span><span class="o">.</span>toFile <span class="s2">"builder.sh"</span> <span class="s1">''</span>
<span class="s1"> source $stdenv/setup</span>
<span class="s1"> mkdir $out</span>
<span class="s1"> install $foo $out/foo1.txt</span>
<span class="s1"> install $foo $out/foo2.txt</span>
<span class="s1"> ''</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</pre></div>
<p>Similarly you can reference other derivations:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">hello =</span> pkgs<span class="o">.</span>stdenv<span class="o">.</span>mkDerivation <span class="k">rec</span> <span class="p">{</span>
<span class="ss">name =</span> <span class="s2">"hello"</span><span class="p">;</span>
<span class="ss">builder =</span> <span class="nb">builtins</span><span class="o">.</span>toFile <span class="s2">"builder.sh"</span> <span class="s1">''</span>
<span class="s1"> source $stdenv/setup</span>
<span class="s1"> echo "hello world" > $out</span>
<span class="s1"> ''</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">demo =</span> pkgs<span class="o">.</span>stdenv<span class="o">.</span>mkDerivation <span class="k">rec</span> <span class="p">{</span>
<span class="k">inherit</span> hello<span class="p">;</span>
<span class="ss">name =</span> <span class="s2">"demo"</span><span class="p">;</span>
<span class="ss">foo =</span> <span class="o">.</span><span class="l">/foo.txt</span><span class="p">;</span>
<span class="ss">builder =</span> <span class="nb">builtins</span><span class="o">.</span>toFile <span class="s2">"builder.sh"</span> <span class="s1">''</span>
<span class="s1"> source $stdenv/setup</span>
<span class="s1"> mkdir $out</span>
<span class="s1"> install $foo $out/foo.txt</span>
<span class="s1"> install $hello $out/hello.txt</span>
<span class="s1"> ''</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</pre></div>
<p>When you build the derivation <tt class="docutils literal">demo</tt>, you automatically build its dependent derivation <tt class="docutils literal">hello</tt>:</p>
<div class="highlight"><pre><span></span>$ nix-build -A demo
these derivations will be built:
/nix/store/q2nmhdn3r1nn50rybgihw59irz40z1gp-hello.drv
/nix/store/bsa1bnp05dbdls1hhfv9hbsfr8sp06aj-demo.drv
building path<span class="o">(</span>s<span class="o">)</span> ‘/nix/store/gybvj34iq35rcwm2pggrrx5jpdf7rnz6-hello’
building path<span class="o">(</span>s<span class="o">)</span> ‘/nix/store/nwkjm3i41v30zq6k9jb3nq2m4rw8p524-demo’
/nix/store/nwkjm3i41v30zq6k9jb3nq2m4rw8p524-demo
$ ls result
foo.txt hello.txt
</pre></div>
<p>This is all fine and good, but where are the promised build tools? The compilers, the libraries,
the minifiers and uglifiers? Read on.</p>
</div>
<div class="section" id="nixpkgs-the-nix-packages-collection">
<h3>Nixpkgs, the Nix Packages collection</h3>
<p>To install the necessary build tools, run the following list of commands. Just kidding. The tools
are already there. Where? In that <tt class="docutils literal">pkgs</tt> object we saw in the previous section. See for yourself
by creating the following <tt class="docutils literal">default.nix</tt> file:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">python =</span> pkgs<span class="o">.</span>python36<span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Believe it or not, <tt class="docutils literal">python</tt> here is a derivation no different from the ones we created in the
previous section. Check it out:</p>
<div class="highlight"><pre><span></span>$ nix-build -A python
/nix/store/q9xwwp0k8lim1lr511xqakjxs2iv3j67-python3-3.6.4-env
$ result/bin/python
Python 3.6.4 (default, Jan 15 2018, 17:40:15)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
</pre></div>
<p>And because <tt class="docutils literal">python</tt> is a derivation like any other, we can pass it in as input to our own
derivation. Let's test it out by using Python's handy <a class="reference external" href="https://docs.python.org/3/library/json.html#module-json.tool">command line JSON pretty-printer</a>:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">python =</span> pkgs<span class="o">.</span>python36<span class="p">;</span>
<span class="ss">demo =</span> pkgs<span class="o">.</span>stdenv<span class="o">.</span>mkDerivation <span class="k">rec</span> <span class="p">{</span>
<span class="k">inherit</span> python<span class="p">;</span>
<span class="ss">name =</span> <span class="s2">"demo"</span><span class="p">;</span>
<span class="ss">builder =</span> <span class="nb">builtins</span><span class="o">.</span>toFile <span class="s2">"builder.sh"</span> <span class="s1">''</span>
<span class="s1"> source $stdenv/setup</span>
<span class="s1"> echo "[1,2,3]" | $python/bin/python -m json.tool > $out</span>
<span class="s1"> ''</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</pre></div>
<p>And build:</p>
<div class="highlight"><pre><span></span>$ nix-build -A demo
/nix/store/fy0ffzashvvjnrfwkf1an80nc1v54da6-demo
$ cat result
[
1,
2,
3
]
</pre></div>
<p>Lastly, we need to address the issue of <em>package pinning</em>, ensuring that we are using a specific
version of every package. For that let's take another look at the <tt class="docutils literal">pkgs</tt> object:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">python =</span> pkgs<span class="o">.</span>python36<span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Clearly it contains whatever we imported from <tt class="docutils literal"><nixpkgs></tt>, which is actually just a directory
in <tt class="docutils literal">$NIX_PATH</tt>. On my system, I can rewrite the above as follows:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="l">/nix/var/nix/profiles/per-user/root/channels/nixpkgs</span> <span class="p">{};</span>
<span class="ss">python =</span> pkgs<span class="o">.</span>python36<span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Let's take a look at that directory:</p>
<div class="highlight"><pre><span></span>$ ls /nix/var/nix/profiles/per-user/root/channels/nixpkgs
COPYING doc nixos
README.md lib pkgs
default.nix maintainers svn-revision
</pre></div>
<p>Now I'm going to let you in on a secret: that directory is simply a local copy of the
<a class="reference external" href="https://github.com/NixOS/nixpkgs/">nixpkgs</a> repository. All you need for package pinning is
to use a specific revision of the nixpkgs repo:</p>
<div class="highlight"><pre><span></span><span class="k">rec</span> <span class="p">{</span>
<span class="ss">pkgsLocal =</span> <span class="nb">import</span> <span class="l"><nixpkgs></span> <span class="p">{};</span>
<span class="ss">pkgs =</span> <span class="nb">import</span> <span class="p">(</span>pkgsLocal<span class="o">.</span>fetchzip <span class="p">{</span>
<span class="ss">url =</span> <span class="s2">"https://github.com/NixOS/nixpkgs/archive/866717d75b64cb07cab16d0357edfd00cf339c20.zip"</span><span class="p">;</span>
<span class="ss">sha256 =</span> <span class="s2">"0ikz6m801gfmgzd4q0la5pcivl46yiviad5gvz0qba0pa7wc8g0g"</span><span class="p">;</span>
<span class="p">})</span> <span class="p">{};</span>
<span class="c1"># contents of `pkgs` is pinned to revision 866717d75b64cb07cab16d0357edfd00cf339c20</span>
<span class="p">}</span>
</pre></div>
<p>Here we are importing the local version of nixpkgs for its <tt class="docutils literal">fetchzip</tt> function, then letting Nix
fetch and unpack an archive with a specific revision of nixpkgs, then we import the unpacked directory
the same way we import any other local path. Does this mean Nix will have to fetch and unpack the
archive every time we run <tt class="docutils literal"><span class="pre">nix-build</span></tt>? No, that's what the <tt class="docutils literal">sha256</tt> hash is for. It lets Nix
permanently cache the contents in <tt class="docutils literal">/nix/store</tt> such that subsequent invocations are near-instantaneous.</p>
</div>
</div>
<div class="section" id="case-study-hsluv">
<h2>Case Study: HSLuv</h2>
<p>For a less trivial example, let's look at how Nix is used for HSLuv.</p>
<div class="section" id="static-website">
<h3>Static website</h3>
<p>A good demonstration at Nix's ability to gather up the necessary tools and put them together in a
reproducible manner is building <a class="reference external" href="http://www.hsluv.org/">www.hsluv.org</a>. You can try it yourself
by cloning our <a class="reference external" href="https://github.com/hsluv/hsluv">GitHub repo</a> and running:</p>
<div class="highlight"><pre><span></span>$ nix-build -A website
...
/nix/store/yvwv7dvfgfm4bb83xbmrilabxcra3bbd-hsluv-website
$ ls result
CNAME credits favicon.png implementations math
comparison examples images index.html static
</pre></div>
<p>Here is what went into building that:</p>
<ol class="arabic simple">
<li>OpenJDK version 1.8.0</li>
<li>Haxe 3.4.4</li>
<li>Node.js 6.12.2</li>
<li>mustache.js 2.3.0</li>
<li>PNG.js 3.0.0</li>
<li>Closure Compiler v20170910 (depends: #1)</li>
<li>Haxe-generated JavaScript from <tt class="docutils literal">Hsluv.hx</tt> (depends: #2)</li>
<li>HSLuv Node.js package (depends: #7)</li>
<li>static demo images from <tt class="docutils literal"><span class="pre">generate-images.js</span></tt> (depends: #3, #5, #8)</li>
<li>static HTML from <tt class="docutils literal"><span class="pre">generate-html.js</span></tt> (depends: #3, #4)</li>
<li><tt class="docutils literal">picker.min.js</tt> for color picker demo (depends: #7, #6)</li>
<li>full static website (depends: #9, #10, #11)</li>
</ol>
<p>Not bad for a single command.</p>
</div>
<div class="section" id="packaging-and-publishing-automation">
<h3>Packaging and publishing automation</h3>
<p>HSLuv is packaged for NPM, PyPI, Maven, NuGet, LuaRocks, RubyGems et al. To get a sense of the thrill
and excitement of working through the peculiarities of these systems, imagine yourself doing taxes in
6 countries simultaneously. It's the kind of joy that's best experienced once. Luckily, we can automate
it: the packaging, the signing, the publishing, the retrieval of all the necessary tools, everything.</p>
<p>Let's use Node.js as an example. Take a look at the derivation that creates the Node.js package:</p>
<div class="highlight"><pre><span></span><span class="ss">nodePackageDist =</span> makeNodePackage <span class="p">{</span>
<span class="ss">jsFile =</span> haxeJsCompile <span class="s2">"hsluv.Hsluv"</span><span class="p">;</span>
<span class="ss">exportFile =</span> <span class="o">.</span><span class="l">/javascript/api-public.js</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
<p>Note that it makes use of two functions: <tt class="docutils literal">makeNodePackage</tt> and <tt class="docutils literal">haxeJsCompile</tt> <a class="footnote-reference" href="#id4" id="id2">[2]</a>. What kind of
functional programming language would Nix be if it didn't allow you to define your functions? In this
case, <tt class="docutils literal">makeNodePackage</tt> returns a <em>derivation</em>, which means you can do the following:</p>
<div class="highlight"><pre><span></span>$ nix-build -A nodePackageDist
/nix/store/1nvjb8crxq6gw7jnjgj8m5643snlizyy-js-node-package
$ ls result
README.md hsluv.js package.json
</pre></div>
<p>Now we need to write a script that would publish this package to NPM. Our first instinct is to put
our script into a derivation. But should we? Actually not, for the following reasons:</p>
<ol class="arabic simple">
<li>A publishing script is going to make use of secret keys we don't want leaking into <tt class="docutils literal">/nix/store</tt>.</li>
<li>A publishing script really cannot be thought of as a pure function. It doesn't always produce an
output, and it is often necessary to rerun the same script with the same inputs, in which case Nix,
with its pure-function assumption, will hit the cache (<tt class="docutils literal">/nix/store</tt>) instead.</li>
</ol>
<p>There is a simple solution to this conundrum. Instead of writing a derivation to perform the publishing
we will write a derivation that will produce the script to perform the publishing. Luckily, Nix provides
a convenient function just for this purpose: <tt class="docutils literal">pkgs.writeShellScriptBin</tt>:</p>
<div class="highlight"><pre><span></span><span class="ss">publishScript =</span> pkgs<span class="o">.</span>writeShellScriptBin <span class="s2">"script.sh"</span> <span class="s1">''</span>
<span class="s1"> # npm adduser creates .npmrc file in HOME</span>
<span class="s1"> TEMP_HOME=`mktemp -d`</span>
<span class="s1"> HOME="$TEMP_HOME"</span>
<span class="s1"> echo -e "$NPM_USER\n$NPM_PASS\n$NPM_EMAIL\n" | </span><span class="si">${</span>pkgs<span class="o">.</span>nodejs<span class="si">}</span><span class="s1">/bin/npm adduser</span>
<span class="s1"> </span><span class="si">${</span>pkgs<span class="o">.</span>nodejs<span class="si">}</span><span class="s1">/bin/npm publish </span><span class="si">${</span>nodePackageDist<span class="si">}</span><span class="s1"></span>
<span class="s1"> rm -rf "$TEMP_HOME"</span>
<span class="s1">''</span><span class="p">;</span>
</pre></div>
<p>Let's go through this. First of all, note that <tt class="docutils literal">pkgs.writeShellScriptBin</tt> returns a derivation that
produces a script, in this case called <tt class="docutils literal">script.sh</tt> with the contents specified in the multiline string.
Pay attention to the variables in this script. The curly brace notation (e.g. <tt class="docutils literal">${pkgs.nodejs}</tt>) is
parsed by Nix, not Bash. This means that Nix will insert the location of the <tt class="docutils literal">npm</tt> executable into
the script. Likewise for <tt class="docutils literal">${nodePackageDist}</tt>. Let's see what the script looks like:</p>
<div class="highlight"><pre><span></span>$ nix-build -A publishScript
/nix/store/a2ssw0i6a7j7489mf6q545as62n8rjpv-script.sh
$ cat result/bin/script.sh
<span class="c1">#!/nix/store/4cvvpbqdkrb0hr4p47q3s9l2a6k04y1g-bash-4.4-p12/bin/bash</span>
<span class="c1"># npm adduser creates .npmrc file in HOME</span>
<span class="nv">TEMP_HOME</span><span class="o">=</span><span class="sb">`</span>mktemp -d<span class="sb">`</span>
<span class="nv">HOME</span><span class="o">=</span><span class="s2">"</span><span class="nv">$TEMP_HOME</span><span class="s2">"</span>
<span class="nb">echo</span> -e <span class="s2">"</span><span class="nv">$NPM_USER</span><span class="s2">\n</span><span class="nv">$NPM_PASS</span><span class="s2">\n</span><span class="nv">$NPM_EMAIL</span><span class="s2">\n"</span> <span class="p">|</span> /nix/store/628m9fgdqj0vcxji1lwywc0nvagrq41i-nodejs-6.12.2/bin/npm adduser
/nix/store/628m9fgdqj0vcxji1lwywc0nvagrq41i-nodejs-6.12.2/bin/npm publish /nix/store/1nvjb8crxq6gw7jnjgj8m5643snlizyy-js-node-package
rm -rf <span class="s2">"</span><span class="nv">$TEMP_HOME</span><span class="s2">"</span>
</pre></div>
<p>Note that everything here comes from Nix: the publishing tools, the package to be published, and, if
you look at the shebang, even the shell that will execute this script! The build environment is
completely isolated from your system. Now all we need to do is run the script, passing in the secret
keys as environment variables. In HSLuv, we keep our secret keys in <tt class="docutils literal">secrets.txt</tt>, a file that contains
a series of <tt class="docutils literal">export</tt> statements like the following:</p>
<div class="highlight"><pre><span></span><span class="nb">export</span> <span class="nv">NPM_USER</span><span class="o">=</span>hsluv
<span class="nb">export</span> <span class="nv">NPM_PASS</span><span class="o">=</span>REDACTED
<span class="nb">export</span> <span class="nv">NPM_EMAIL</span><span class="o">=</span>hsluvcontributors@gmail.com
<span class="nb">export</span> <span class="nv">PYPI_USERNAME</span><span class="o">=</span>hsluv
<span class="nb">export</span> <span class="nv">PYPI_PASSWORD</span><span class="o">=</span>REDACTED
...
</pre></div>
<p>So to publish to NPM, we need to <tt class="docutils literal">source secrets.txt</tt> and <tt class="docutils literal">exec result/bin/script.sh</tt>. For this
purpose I made a tiny wrapper in the root folder of HSLuv called <tt class="docutils literal">run.sh</tt>:</p>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env bash</span>
<span class="nv">HSLUV_ROOT</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>dirname <span class="si">${</span><span class="nv">0</span><span class="si">}</span><span class="k">)</span><span class="s2">"</span>
<span class="nv">SCRIPT_DIR</span><span class="o">=</span><span class="s2">"</span><span class="k">$(</span>nix-build -A <span class="si">${</span><span class="nv">1</span><span class="si">}</span> --no-out-link <span class="si">${</span><span class="nv">HSLUV_ROOT</span><span class="si">}</span>/default.nix<span class="k">)</span><span class="s2">"</span>
<span class="nb">source</span> <span class="s2">"</span><span class="si">${</span><span class="nv">HSLUV_ROOT</span><span class="si">}</span><span class="s2">/secrets.txt"</span>
<span class="nb">exec</span> <span class="s2">"</span><span class="si">${</span><span class="nv">SCRIPT_DIR</span><span class="si">}</span><span class="s2">/bin/script.sh"</span>
</pre></div>
<p>It takes the name of the publishing script derivation as a command line argument (<tt class="docutils literal">${1}</tt>), so in
order to use it to publish the NPM package discussed in this section, you only need one line:</p>
<div class="highlight"><pre><span></span>$ ./run.sh publishScript
</pre></div>
<p>Now that's what I call automation.</p>
<p>Hope you found this post useful. If you see any errors or have any suggestions, let me know in the
comments!</p>
<table class="docutils footnote" frame="void" id="id3" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>In a certain pedantic sense, every program is deterministic, provided we know the inputs. The
problem is that programs have inputs that are not passed in explicitly, such as when they request
system time or random numbers from the OS. Nix mitigates many of these sources of "nondeterminism"
so this is rarely a problem in practice.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id4" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>Functions are outside the scope of this blog post. To see the definitions of the functions
referenced here, go to <a class="reference external" href="https://github.com/hsluv/hsluv/blob/master/default.nix">default.nix</a> in
the HSLuv repository. To learn more about Nix functions, see this <a class="reference external" href="https://nixos.org/nix/manual/#ss-functions">quaint little section</a> in the Nix manual.</td></tr>
</tbody>
</table>
</div>
</div>
Installing Docker on Debian Jessie2013-12-30T00:00:00-05:002013-12-30T00:00:00-05:00Alexei Boroninetag:www.boronine.com,2013-12-30:/2013/12/30/Installing-Docker-on-Debian-Jessie/<p>While visiting family for the holidays, I've been lovingly crafting a new Debian-based work environment. After spending days tweaking my Xmonad configuration, I finally decided to install Docker, which I've been happily using at work and in my side projects. Currently, Docker does not support Debian, so it took some …</p><p>While visiting family for the holidays, I've been lovingly crafting a new Debian-based work environment. After spending days tweaking my Xmonad configuration, I finally decided to install Docker, which I've been happily using at work and in my side projects. Currently, Docker does not support Debian, so it took some digging to get it to work.</p>
<p>This guide assumes a clean Debian installation. Note that currently Docker requires a 64bit OS.</p>
<p>First we need to get LXC to work:</p>
<div class="highlight"><pre><span></span>apt-get install lxc
lxc-checkconfig
</pre></div>
<p>Here is the output generated by <tt class="docutils literal"><span class="pre">lxc-checkconfig</span></tt>:</p>
<div class="highlight"><pre><span></span>Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.11-2-amd64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: missing
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup namespace: required
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
</pre></div>
<p>As you can see, user namespace support is missing. We need a kernel compiled with <tt class="docutils literal">CONFIG_USER_NS=y</tt>. Instead of compiling our own, let's grab a newer kernel from unstable, where this is enabled by default:</p>
<div class="highlight"><pre><span></span><span class="nb">echo</span> <span class="s2">"deb http://cdn.debian.net/debian unstable main"</span> > /etc/apt/sources.list.d/unstable.list
apt-get update
</pre></div>
<p>Find the appropriate <tt class="docutils literal"><span class="pre">linux-image</span></tt> package and install it:</p>
<div class="highlight"><pre><span></span>apt-cache search linux-image
apt-get install linux-image-3.12-1-amd64
</pre></div>
<p>If you don't want unstable packages to pollute your apt cache, you should clean up:</p>
<div class="highlight"><pre><span></span>rm /etc/apt/sources.list.d/unstable.list
apt-get update
</pre></div>
<p>Next, we need to tweak cgroups. Add a new mount to <tt class="docutils literal">/etc/fstab</tt>:</p>
<div class="highlight"><pre><span></span><span class="nb">echo</span> <span class="s2">"cgroup /sys/fs/cgroup cgroup defaults 0 0"</span> >> /etc/fstab
</pre></div>
<p>And add the following config to <tt class="docutils literal">/etc/default/grub</tt>:</p>
<div class="highlight"><pre><span></span>GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
</pre></div>
<p>Now we need to reinstall GRUB for the last change to take effect (replace <tt class="docutils literal">sdX</tt> with wherever you want GRUB to go):</p>
<div class="highlight"><pre><span></span>update-grub
grub-install /dev/sdX
</pre></div>
<p>Lastly before rebooting, we need to enable port forwarding by uncommenting the following config in <tt class="docutils literal">/etc/sysctl.conf</tt>:</p>
<div class="highlight"><pre><span></span>net.ipv4.ip_forward=1
</pre></div>
<p>After rebooting into the new kernel (which should become the default option), let's check the output of <tt class="docutils literal"><span class="pre">lxc-checkconfig</span></tt>:</p>
<div class="highlight"><pre><span></span>Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-3.12-1-amd64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
</pre></div>
<p>Looking good.</p>
<p>If you like, you can build Docker from source. I had some trouble doing it, so for the purpose of this tutorial let's keep things real simple and grab the binary:</p>
<div class="highlight"><pre><span></span>wget https://get.docker.io/builds/Linux/x86_64/docker-latest -O docker
chmod +x docker
mv docker /usr/bin/
</pre></div>
<p>Start the docker daemon (it's up to you to make it auto-start, as for me, I like to do it manually):</p>
<div class="highlight"><pre><span></span>docker -d <span class="p">&</span>
</pre></div>
<p>Docker should now be running:</p>
<div class="highlight"><pre><span></span>docker version
</pre></div>
<div class="highlight"><pre><span></span>Client version: 0.7.2
Go version (client): go1.2
Git commit (client): 28b162e
Server version: 0.7.2
Git commit (server): 28b162e
Go version (server): go1.2
Last stable version: 0.7.2
# docker pull ubuntu
# docker run ubuntu echo 'ubuntu on debian'
ubuntu on debian
</pre></div>
<p>If you're having troubles with this tutorial, leave a note in the comments. Have fun!</p>
Why JavaScript Still Sucks2012-12-14T00:00:00-05:002012-12-14T00:00:00-05:00Alexei Boroninetag:www.boronine.com,2012-12-14:/2012/12/14/Why-JavaScript-Still-Sucks/<p>I was among many developers that recently rediscovered JavaScript.
Indeed as a very capable language.
But after using <em>the new</em> JavaScript for a solid year, I came to the conclusion that JavaScript <em>still</em> sucks.
And no, I'm not talking about its wacky comparison operators.
There is a deeper problem, and …</p><p>I was among many developers that recently rediscovered JavaScript.
Indeed as a very capable language.
But after using <em>the new</em> JavaScript for a solid year, I came to the conclusion that JavaScript <em>still</em> sucks.
And no, I'm not talking about its wacky comparison operators.
There is a deeper problem, and a solveable one at that.
Let me explain.</p>
<img alt="See no evil, hear no evil, speak no evil" src="https://www.boronine.com/images/monkeys.jpg" />
<div class="section" id="no-nonsense">
<h2>No Nonsense</h2>
<p>I must've been 13 when my dad gave me <a class="reference external" href="http://www.amazon.com/JavaScript-Programming-Absolute-Beginner-Harris/dp/0761534105">my first programming book</a>.
I was overjoyed to find that under the hood, computers were not a tangled mess of wires and clockwork, no, the code was clear as day.
I felt like I knew it all along, and in a big way I did.
After all, what is code but a formalization of rational human thought?</p>
<p>Now, in all honesty I was expecting a Java book. I googled something along the lines of "is JavaScript and Java the same language".
Turned out they're not, and so, Java ended up being my second.
I didn't even get through the introduction before the first problem appeared: <strong>my mom and stepdad didn't want me installing software on the family computer — I was left without a Java compiler</strong>.
I remember double checking my code before uploading it to <a class="reference external" href="http://www.innovation.ch/java/java_compile.html">an online compiler</a>, then waiting, downloading the jar... rinse, repeat.
Boy was it tedious.</p>
<p>From my perspective back then, JavaScript was truly a no-nonsense language.
You whip up an HTML file in Notepad, open it in Internet Explorer and you're set.
There were no classes, no private and public methods, no final variables.
I didn't know the word "overengineered" back then, but it would have described exactly my impression of Java.
So:</p>
<ol class="arabic simple">
<li>No compilation</li>
<li>Ubiquitous platform</li>
<li>No advanced language features</li>
<li>Oh, almost forgot: <strong>View Source</strong>!</li>
</ol>
<p>Why would a great language like that be so hated?</p>
</div>
<div class="section" id="ad-hoc-hell">
<h2>Ad-hoc Hell</h2>
<p>Here's the problem: JavaScript programs inherited from their language a complete lack of design guidance.
<strong>Everything was ad-hoc:</strong></p>
<ol class="arabic simple">
<li><strong>No OOP</strong>. I am not familiar with any other way to structure <em>imperative</em> programs. Yes, JavaScript has a rudimentary object model, but literally no one knew how it actually worked.</li>
<li><strong>No standard library</strong>. Copying functions from forums and pasting them into your code. Not fun.</li>
<li><strong>No module system</strong>. Constant scouting for download links and ridiculously long source files.</li>
<li><strong>No language resources</strong>. No high-quality resources (and hardly a single decent book) meant your best reference was misguided blog posts and newbie forum questions.</li>
</ol>
<p>So, what happened to make JavaScript popular again?</p>
</div>
<div class="section" id="back-in-vogue">
<h2>Back in Vogue</h2>
<p>I think what jump-started JavaScript's reemergence was Google's work on the V8 engine.
Suddenly, JavaScript was fast.
<em>Real fast</em>.
Fast enough that people decided to bite the bullet and use it to write <em>web applications</em>.</p>
<p>Then <a class="reference external" href="http://nodejs.org/">Node.js</a> came out with some wanky benchmarks and, more importantly, a promise for code reuse on the client and server, a promise not really capitalized on until recently, with the likes of <a class="reference external" href="http://meteor.com/">Meteor</a> and <a class="reference external" href="http://derbyjs.com/">Derby</a>.
Things started to change for the better:</p>
<ol class="arabic simple">
<li><strong>Download buttons got BIGGER</strong></li>
<li>Node.js kind of sort of standardized an import system</li>
<li>People started writing pretty good libraries</li>
<li><a class="reference external" href="https://developer.mozilla.org/en-US/">Good resources</a> started popping up</li>
</ol>
<p>However:</p>
<ol class="arabic simple">
<li><strong>Still no OOP</strong></li>
<li>Client and server JavaScript still completely disconnected</li>
<li>Documentation, even for high profile projects, is lousy at best</li>
</ol>
</div>
<div class="section" id="why-why">
<h2>Why, why?</h2>
<p>I think the root of the problem with modern JavaScript and the main reason that the language still sucks lies in a certain sentiment of the JavaScript community, the sentiment that <strong>JavaScript was a good language all along, it was just a misunderstood language</strong>.
Um, no.
JavaScript was a premature bastard baby, raised by frickin' wolves.
Stop defending JavaScript as a language and start embracing JavaScript as a <em>platform</em>, and as a <em>compilation target</em>.</p>
</div>
<div class="section" id="documentation">
<h2>Documentation</h2>
<p>People can laugh at Java all they want but when I look at Java documentation I see <em>exactly</em> which objects I can make, <em>exactly</em> which parameters each method takes, <em>exactly</em> which errors they throw.
The best I could hope for with a JavaScript library is a fancy piece of example code.
This makes it nearly impossible to write <em>correct</em> software, unless you read the source code of the library you are using.
Even such integral JavaScript projects as <a class="reference external" href="http://expressjs.com/api.html">Express</a> have lousy API documentation.
(<a class="reference external" href="http://emberjs.com/api/">Ember's</a> excellent API documentation might be a counter-example.)</p>
</div>
<div class="section" id="syntax-sugar">
<h2>Syntax Sugar</h2>
<p>The JavaScript community is too quick to dismiss syntax sugar.
I think <strong>syntax sugar creates expressiveness</strong>.
The same way you abstract repeating logic in your code, your language ought to abstract common idioms.</p>
<ol class="arabic simple">
<li>It makes the code more concise.</li>
<li><strong>It helps communicate the *meaning* behind your code rather than the algorithm.</strong> I already know the array iteration algorithm, thank you very much. Stop repeating it and just tell me what you are trying to do.</li>
</ol>
<p>As a coder, your main audience isn't your computer, it is other programmers, including your future self.
Yes, we can all feel cool writing tedious for loops, but who would honestly prefer reading <tt class="docutils literal">for (var i=0; i<arr.length; <span class="pre">i++)</span></tt> rather than <tt class="docutils literal">for e in arr</tt>?
As a side note, the JavaScript version of this loop is actually slower than its CoffeeScript counterpart, do you know why?</p>
</div>
<div class="section" id="jslint">
<h2>JSLint</h2>
<p>As if being a JavaScript developer wasn't painful in itself, <a class="reference external" href="http://www.jslint.com/">JSLint</a> comes and adds insult to injury.
I imagine linting JavaScript as an embarrassing punishment in some kind of coding boot camp, akin to cleaning the toilet with a tooth brush.
In fact, I think I would literally shave a yak instead.</p>
<p>On a more serious note, as programmers we should be looking for automation. Don't you wish you could automate JSLint? Oh wait, you can! CoffeeScript generates perfectly linted code, which I find quite hilarious. Props to <a class="reference external" href="https://github.com/jashkenas">Jeremy</a> for that one.</p>
<img alt="Yak shaving" src="https://www.boronine.com/images/yak.jpg" />
</div>
<div class="section" id="oop">
<h2>OOP</h2>
<p>JavaScript's object model is not enough. Prototypal inheritance is a low level feature that <em>can be used</em> to create a meaningful object model, but in no way constitutes one by itself.</p>
<p>This is part of the reason that JavaScript's API documentation sucks so badly, how are you supposed to document your object-oriented code when your language doesn't even have classes? How are JavaScript libraries, and, most importantly, JavaScript developers supposed to interoperate when <a class="reference external" href="http://stackoverflow.com/questions/383402/is-javascript-s-new-keyword-considered-harmful">we don't even agree on how to instantiate objects</a>?</p>
</div>
<div class="section" id="what-are-the-options">
<h2>What Are the Options?</h2>
<p>Years have passed, laptops were replaced numerously, regimes crumbled, subatomic particles were discovered. JavaScript is still the same. How many years are you willing to wait for basic features? Following the pessimistic tone of this article, let's first list the things that <em>aren't</em> going to be an option:</p>
<ol class="arabic simple">
<li>Mozilla's own JavaScript <a class="reference external" href="https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7">1.7</a> or <a class="reference external" href="https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.8">1.8</a>. The former was released 6 and half years ago, but being backwards-incompatible, literally no one used it and no one ever will, same goes for the latter. <strong>Both dead on arrival.</strong></li>
<li>ECMAScript Harmony. The most recent <a class="reference external" href="http://en.wikipedia.org/wiki/Design_by_committee">Design by Committee</a> sloth, an evolution of the above. Transitioning to this new ECMAScript is going to be an excruciatingly slow and painful process, especially since some of its features are <a class="reference external" href="http://stackoverflow.com/a/6510903/212584">incompatible with JavaScript</a>. <strong>Not a solution unless you're willing to wait for a decade.</strong></li>
</ol>
<p>And, finally, the viable options:</p>
<ol class="arabic simple">
<li><a class="reference external" href="http://coffeescript.org/">CoffeeScript</a>. The syntax is very nice and it supports classes. I think CoffeeScript is not the end, but it is a spectacular start.</li>
<li><a class="reference external" href="http://www.typescriptlang.org/">TypeScript</a>. Builds on JavaScript to add optional static typing, which I, personally, am a big fan of. As pointed out by <a class="reference external" href="https://twitter.com/mohamedmansour">Mohamed Mansour</a> and Dave Hodder in the comments, TypeScript goes further by implementing some ECMAScript proposals and perhaps ECMAScript will eventually borrow the optional static typing from TypeScript. Very interesting.</li>
<li><a class="reference external" href="http://www.dartlang.org/">Google Dart</a>. A wholly new language that ships with a to-JavaScript compiler and <a class="reference external" href="http://www.dartlang.org/articles/js-dart-interop/">some JavaScript interop</a> but overall is not meant to integrate into the JavaScript ecosystem. I fail to see a compelling reason for this other than some Google engineers ignoring reality in favor of making a cool new language from scratch. As a coder I can understand that, but I think it will prove to be the language's downfall.</li>
<li><a class="reference external" href="http://haxe.org/">HaXe</a>. Thanks to Laurence Taylor for pointing it out in the comments. This is a high-level language that compiles to JavaScript, Flash, NekoVM, PHP, C++, C# and Java (soon). I've never used it myself, but it looks really impressive.</li>
</ol>
</div>
<div class="section" id="conclusion">
<h2>Conclusion</h2>
<p>One thing I am ready to bet on: the winner will be a <a class="reference external" href="https://github.com/jashkenas/coffee-script/wiki/List-of-languages-that-compile-to-JS">compile-to-JS</a> language.
We aren't ready for a transition yet, but we are making progress and even though many efforts diverge, they all pave the way for the future of the web.
Regardless of which language wins in the end, I want to emphasize my main point: <strong>JavaScript as it stands today is painfully inadequate, we need to embrace the need for a new language and push forward!</strong></p>
<p>Props to all the people making this happen and here's to hoping that <a class="reference external" href="http://procbits.com/2012/05/18/why-do-all-the-great-node-js-developers-hate-coffeescript">more Node developers divorce their JavaScript purism</a> and join the ranks.</p>
<p><tt class="docutils literal"></script></tt></p>
</div>
Tox-Driven Python Development2012-11-15T00:00:00-05:002012-11-15T00:00:00-05:00Alexei Boroninetag:www.boronine.com,2012-11-15:/2012/11/15/Tox-Driven-Python-Development/<p>Going through Julian Berman's <a class="reference external" href="https://github.com/Julian/jsonschema">jsonschema</a> repo (some of the cleanest Python code I've read, by the way), I stumbled upon a recommendation that greatly improved my Python workflow. I'm talking about <a class="reference external" href="http://tox.testrun.org/">Tox</a>, the Python testing automaton.</p>
<p>Tox allows you to test your code against multiple versions of Python (yes, <a class="reference external" href="http://pypy.org/">PyPy …</a></p><p>Going through Julian Berman's <a class="reference external" href="https://github.com/Julian/jsonschema">jsonschema</a> repo (some of the cleanest Python code I've read, by the way), I stumbled upon a recommendation that greatly improved my Python workflow. I'm talking about <a class="reference external" href="http://tox.testrun.org/">Tox</a>, the Python testing automaton.</p>
<p>Tox allows you to test your code against multiple versions of Python (yes, <a class="reference external" href="http://pypy.org/">PyPy</a> included!) with a single command:</p>
<div class="highlight"><pre><span></span>$ tox
</pre></div>
<p>It uses <a class="reference external" href="http://www.virtualenv.org/en/latest/">virtualenv</a> to create a virtual Python environment for each Python version you want to support, installs your dependencies as well as the package you are currently developing in each of these enviroments and runs a sequence of testing commands of your choice in each environment.</p>
<p>Tox is great for <a class="reference external" href="http://en.wikipedia.org/wiki/Test-driven_development">Test-driven development</a> (TDD). In fact, <strong>I no longer need to activate a virtual environment during development</strong>. My workflow now looks like this:</p>
<ol class="arabic simple">
<li>Write a test</li>
<li>Write some code</li>
<li>Run <tt class="docutils literal">tox</tt> and tweak code until test passes</li>
</ol>
<p>If you think your code works on all versions of Python just because it works on your development version, think again!</p>
<div class="section" id="set-up">
<h2>Set-up</h2>
<ul class="simple">
<li><tt class="docutils literal">pip install tox</tt>. As long as <tt class="docutils literal">tox</tt> is in your <tt class="docutils literal">PATH</tt>, you don't need to set up a virtual environment.</li>
<li>Add <tt class="docutils literal">/.tox</tt> to your <tt class="docutils literal">.gitignore</tt> file.</li>
<li>Create a <tt class="docutils literal">setup.py</tt> file for your package. This is still a complicated matter in Python. setuptools is old, <a class="reference external" href="http://guide.python-distribute.org/introduction.html#current-state-of-packaging">distribute is going in the trash</a>, distutils2 is the future. For now, use setuptools. Specify dependencies using <tt class="docutils literal">install_requires</tt>. Testing dependencies (such as <a class="reference external" href="https://nose.readthedocs.org/en/latest/">nose</a>) will be specified later. If you depend on a version of a package that is not distributed on PyPI, use <tt class="docutils literal">dependency_links</tt> as follows:</li>
</ul>
<div class="highlight"><pre><span></span><span class="n">install_requires</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">"jsonschema==0.7-patched"</span><span class="p">,</span>
<span class="p">],</span>
<span class="n">dependency_links</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># Patched version to support a special feature</span>
<span class="s2">"http://github.com/boronine/jsonschema/tarball</span><span class="se">\</span>
<span class="s2">/391916e71b946db3bf5d92cbb767f620a869fc82#egg=jsonschema-0.7-patched"</span>
<span class="p">]</span>
</pre></div>
<ul class="simple">
<li>Create a <a class="reference external" href="http://docs.python.org/2/distutils/sourcedist.html#manifest-template">MANIFEST.in file</a> to make sure your package includes auxiliary files:</li>
</ul>
<div class="highlight"><pre><span></span>include tox.ini
<span class="c1"># If your tests aren't part of the distributed package, make sure to include them</span>
recursive-include tests *
</pre></div>
<ul class="simple">
<li>Configure Tox with <a class="reference external" href="http://tox.testrun.org/latest/config.html">tox.ini</a>. Testing dependencies go in <tt class="docutils literal">deps</tt>.</li>
</ul>
<div class="highlight"><pre><span></span><span class="k">[tox]</span><span class="w"></span>
<span class="na">envlist</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">py26, py27, pypy</span><span class="w"></span>
<span class="k">[testenv]</span><span class="w"></span>
<span class="na">deps</span><span class="w"> </span><span class="o">=</span><span class="w"></span>
<span class="w"> </span><span class="na">nose</span><span class="w"></span>
<span class="w"> </span><span class="na">unittest2</span><span class="w"></span>
<span class="na">commands</span><span class="w"> </span><span class="o">=</span><span class="w"></span>
<span class="w"> </span><span class="na">nosetests</span><span class="w"></span>
</pre></div>
<ul class="simple">
<li>Run <tt class="docutils literal">tox</tt>. The first run will take a minute because it has to generate the virtual environments. The subsequent runs will be fast.</li>
</ul>
<p>Good luck!</p>
</div>
Make Tastypie Respect blank=False2012-10-10T00:00:00-04:002012-10-10T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-10-10:/2012/10/10/Make-Tastypie-Respect-Blank-Equals-False/<p>More Tastypie pain, documented in <a class="reference external" href="https://github.com/toastdriven/django-tastypie/issues/518">several issues</a>. Tastypie's <tt class="docutils literal">blank</tt> attribute simply doesn't work. Add this to your <tt class="docutils literal">Resource</tt> as a workaround:</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyResource</span><span class="p">(</span><span class="n">ModelResource</span><span class="p">):</span>
<span class="c1"># Workaround for this issue:</span>
<span class="c1"># https://github.com/toastdriven/django-tastypie/issues/518</span>
<span class="k">def</span> <span class="nf">hydrate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bundle</span><span class="p">):</span>
<span class="k">for</span> <span class="n">field_name</span><span class="p">,</span> <span class="n">field_obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">field_name</span> <span class="o">==</span> <span class="s1">'resource_uri'</span><span class="p">:</span>
<span class="k">continue …</span></pre></div><p>More Tastypie pain, documented in <a class="reference external" href="https://github.com/toastdriven/django-tastypie/issues/518">several issues</a>. Tastypie's <tt class="docutils literal">blank</tt> attribute simply doesn't work. Add this to your <tt class="docutils literal">Resource</tt> as a workaround:</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyResource</span><span class="p">(</span><span class="n">ModelResource</span><span class="p">):</span>
<span class="c1"># Workaround for this issue:</span>
<span class="c1"># https://github.com/toastdriven/django-tastypie/issues/518</span>
<span class="k">def</span> <span class="nf">hydrate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bundle</span><span class="p">):</span>
<span class="k">for</span> <span class="n">field_name</span><span class="p">,</span> <span class="n">field_obj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">field_name</span> <span class="o">==</span> <span class="s1">'resource_uri'</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">field_obj</span><span class="o">.</span><span class="n">blank</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">bundle</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">field_name</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ApiFieldError</span><span class="p">(</span><span class="s2">"The '</span><span class="si">%s</span><span class="s2">' field has no data and doesn't allow a default or null value."</span> <span class="o">%</span> <span class="n">field_name</span><span class="p">)</span>
<span class="k">return</span> <span class="n">bundle</span>
</pre></div>
Non-PK Identifiers for Tastypie URLs2012-10-10T00:00:00-04:002012-10-10T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-10-10:/2012/10/10/Non-PK-Identifiers-For-Tastypie-URLs/<p>I've been using <a class="reference external" href="http://tastypieapi.org/">Tastypie</a> at work for a few weeks now, and while it's been generally great, I've had my share of frustrations with it. The most recent one involved a <a class="reference external" href="http://django-tastypie.readthedocs.org/en/v0.9.11/cookbook.html#using-non-pk-data-for-your-urls">cookbook recipe</a> that didn't quite work. Following the recipe, I got Tastypie to resolve my URLs, but I couldn't …</p><p>I've been using <a class="reference external" href="http://tastypieapi.org/">Tastypie</a> at work for a few weeks now, and while it's been generally great, I've had my share of frustrations with it. The most recent one involved a <a class="reference external" href="http://django-tastypie.readthedocs.org/en/v0.9.11/cookbook.html#using-non-pk-data-for-your-urls">cookbook recipe</a> that didn't quite work. Following the recipe, I got Tastypie to resolve my URLs, but I couldn't for the life of me get it to return a non-blank <tt class="docutils literal">resource_uri</tt>. Because I am using <a class="reference external" href="https://github.com/amccloud/backbone-tastypie">Tastypie with Backbone</a>, the frontend code relies on these URIs.</p>
<p>If you are using Tastypie 0.9.11, you will have to override <tt class="docutils literal">get_resource_uri</tt>. The trick is to make sure you plug in all of the following into Django's urlresolver <tt class="docutils literal">resolve</tt>:</p>
<ol class="arabic simple">
<li><tt class="docutils literal">api_name</tt> - The name you used for Tastypie's <tt class="docutils literal">Api</tt> class. Put it in <tt class="docutils literal">Meta</tt> and grab it as <tt class="docutils literal">self._meta.api_name</tt>. This couples the API with the Resource. Oh well.</li>
<li><tt class="docutils literal">resource_name</tt> - Grab it as <tt class="docutils literal">self._meta.resource_name</tt></li>
<li>The new key that you defined as a replacement for <cite>pk</cite>. In the <a class="reference external" href="http://django-tastypie.readthedocs.org/en/v0.9.11/cookbook.html#using-non-pk-data-for-your-urls">cookbook example</a> it is called <tt class="docutils literal">username</tt>.</li>
</ol>
<p>ModelResource (Tastypie v0.9.11):</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CompanyResource</span><span class="p">(</span><span class="n">ModelResource</span><span class="p">):</span>
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
<span class="n">resource_name</span> <span class="o">=</span> <span class="s1">'companies'</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">Company</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">override_urls</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s2">"^(?P<resource_name></span><span class="si">%s</span><span class="s2">)/(?P<domain>[\w\d_.-]+)/$"</span> <span class="o">%</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">resource_name</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">wrap_view</span><span class="p">(</span><span class="s1">'dispatch_detail'</span><span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">"api_dispatch_detail"</span><span class="p">),</span>
<span class="p">]</span>
<span class="k">def</span> <span class="nf">get_resource_uri</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bundle_or_obj</span><span class="p">):</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'resource_name'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">resource_name</span><span class="p">,</span>
<span class="s1">'api_name'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">api_name</span>
<span class="p">}</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">bundle_or_obj</span><span class="p">,</span> <span class="n">Bundle</span><span class="p">):</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s1">'domain'</span><span class="p">]</span> <span class="o">=</span> <span class="n">bundle_or_obj</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">domain</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s1">'domain'</span><span class="p">]</span> <span class="o">=</span> <span class="n">bundle_or_obj</span><span class="o">.</span><span class="n">domain</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_reverse_url</span><span class="p">(</span><span class="s2">"api_dispatch_detail"</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="n">kwargs</span><span class="p">)</span>
</pre></div>
<p>If you are using a later version of Tastypie, you can simplify it further. I started off using Tastypie master, but had to go back to v0.9.11 because Validation was broken.</p>
<p>ModelResource (Tastypie master):</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CompanyResource</span><span class="p">(</span><span class="n">ModelResource</span><span class="p">):</span>
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
<span class="n">resource_name</span> <span class="o">=</span> <span class="s1">'companies'</span>
<span class="n">api_name</span> <span class="o">=</span> <span class="s1">'v1'</span>
<span class="n">detail_uri_name</span> <span class="o">=</span> <span class="s1">'domain'</span>
<span class="n">queryset</span> <span class="o">=</span> <span class="n">Company</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">prepend_urls</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s2">"^(?P<resource_name></span><span class="si">%s</span><span class="s2">)/(?P<domain>[\w\d_.-]+)/$"</span> <span class="o">%</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">resource_name</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">wrap_view</span><span class="p">(</span><span class="s1">'dispatch_detail'</span><span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">"api_dispatch_detail"</span><span class="p">),</span>
<span class="p">]</span>
</pre></div>
<p>Resource (Tastypie master):</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CompanyResource</span><span class="p">(</span><span class="n">Resource</span><span class="p">):</span>
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
<span class="n">resource_name</span> <span class="o">=</span> <span class="s1">'companies'</span>
<span class="n">api_name</span> <span class="o">=</span> <span class="s1">'v1'</span>
<span class="k">def</span> <span class="nf">obj_get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">return</span> <span class="n">Company</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">domain</span><span class="o">=</span><span class="n">kwargs</span><span class="p">[</span><span class="s1">'domain'</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">prepend_urls</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s2">"^(?P<resource_name></span><span class="si">%s</span><span class="s2">)/(?P<domain>[\w\d_.-]+)/$"</span> <span class="o">%</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">resource_name</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">wrap_view</span><span class="p">(</span><span class="s1">'dispatch_detail'</span><span class="p">),</span>
<span class="n">name</span><span class="o">=</span><span class="s2">"api_dispatch_detail"</span><span class="p">),</span>
<span class="p">]</span>
<span class="c1"># This (along with _meta.api_name and _meta.resource_name) will</span>
<span class="c1"># need to be plugged into the above URL</span>
<span class="k">def</span> <span class="nf">detail_uri_kwargs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bundle_or_obj</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">bundle_or_obj</span><span class="p">,</span> <span class="n">Bundle</span><span class="p">):</span>
<span class="k">return</span> <span class="p">{</span> <span class="s1">'domain'</span><span class="p">:</span> <span class="n">bundle_or_obj</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">domain</span> <span class="p">}</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{</span> <span class="s1">'domain'</span><span class="p">:</span> <span class="n">bundle_or_obj</span><span class="o">.</span><span class="n">domain</span> <span class="p">}</span>
</pre></div>
<p>I created a Tastypie <a class="reference external" href="https://github.com/toastdriven/django-tastypie/issues/687">issue</a>. Hope this saved you some frustration.</p>
<p>Cheers!</p>
My Progress on HSLuv2012-10-06T00:00:00-04:002012-10-06T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-10-06:/2012/10/06/My-Progress-On-HUSL/<p>About a year ago, while working on a super-secret project (that has since been stashed), I ran into a small UI problem: I needed to generate a set of 12 colors with a constant lightness and saturation, but with differing hues. HSL seemed like an obvious choice, but I quicly …</p><p>About a year ago, while working on a super-secret project (that has since been stashed), I ran into a small UI problem: I needed to generate a set of 12 colors with a constant lightness and saturation, but with differing hues. HSL seemed like an obvious choice, but I quicly discovered that <a class="reference external" href="/2012/03/26/Color-Spaces-for-Human-Beings/">it is completely inadequate</a>. So I started reading about colors.</p>
<p>After discovering perceptually-uniform color spaces, I made <a class="reference external" href="https://github.com/boronine/colorspaces.js">a JavaScript library</a> that allowed me to use these color spaces and <a class="reference external" href="http://en.wikipedia.org/wiki/CIELUV">CIELUV</a> in particular. I released the library and got back to my original project, using CIELCh<sub>uv</sub> to generate my 12 colors.</p>
<img alt="CIELCh(uv)" src="https://www.boronine.com/images/cielchuv.png" />
<p>Soon I ran into a limitation: as I raised the chroma value, my blue-green color would disappear as the coordinates stepped outside of the range of human vision and into the realm of impossible colors. See those dips in the plot above? CIELUV does not define a range of chroma, so the only way to find out if a color steps outside the boundary is to do an actual conversion. No good.</p>
<p>Out of sheer curiosity, I decided to derive a function that would find the most saturated color of a certain hue and lightness that is displayable by computers, one that would let me plot the boundary in the picture above. I used <a class="reference external" href="http://maxima.sourceforge.net/">Maxima</a> to build and solve some equations, the result was one long-ass function. I transcribed it into JavaScript and, to my great surprise, it worked.</p>
<p>Using this function, I could accept saturation as a percentage of the maximum chroma, eliminating the danger of stepping outside the boundary. Of course, it comes with a price: the chroma has to be distorted. Still, it was a huge improvement over HSL, so I released it as <a class="reference external" href="http://www.hsluv.org">HSLuv</a>.</p>
<p>A couple of weeks ago I updated HSLuv with a pastel variation, one that sacrifices saturated colors for a non-distorted chroma. Basically, it finds the lowest dips in the picture above and draws a horizontal line under it. The result is a rectangle that can be stretched with no distortion.</p>
<p>You can see a color picker, demos and technical details <a class="reference external" href="http://www.hsluv.org">on the project page</a>.</p>
<p>Also, check out a <a class="reference external" href="https://www.syntaxenvy.com">random syntax highlighting theme generator</a> that I made to demonstrate the advantages of using HSLuv for generating colors.</p>
<p>If you hate hard-coding as much as I do (let this project be my witness), you should really use HSLuv! Why hard-code what you can generate?</p>
HTML5: Less Committees, More Competition!2012-09-17T00:00:00-04:002012-09-17T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-09-17:/2012/09/17/HTML5-Less-Commitees-More-Competition/<p>As the HTML5 fever begins to wear off, I'm starting to see some bad tendencies in the development of the web as a platform. While I am excited for the low-level APIs that are making their way into our browsers (from playing audio to 3D to real-time communication), I hate …</p><p>As the HTML5 fever begins to wear off, I'm starting to see some bad tendencies in the development of the web as a platform. While I am excited for the low-level APIs that are making their way into our browsers (from playing audio to 3D to real-time communication), I hate to see trade-offs being made in favor of things that don't matter.</p>
<img alt="Picture of a fish" src="https://www.boronine.com/images/smelt.jpg" />
<div class="section" id="semantic-html-does-not-matter">
<h2>Semantic HTML Does Not Matter</h2>
<p>Let's fire up the grill for the sacred cow of the web: semantic HTML.</p>
<p>The idea is a noble one: use HTML to describe the meaning of the content and CSS to describe its presentational aspects. Semantics is to presentation as emphasis is to bold. This idea sounds very sensible from an armchair perspective, but it crashes and burns when faced with modern reality.</p>
<p><strong>HTML is a UI rendering engine, not a document markup language.</strong> To illustrate, I am not writing this document in HTML, I am writing it in <a class="reference external" href="http://daringfireball.net/projects/markdown/">Markdown</a>. Markdown is designed to be semantic (unlike HTML!), to have simple, intuitive syntax, and it's pretty damn good. HTML is its awkwardly high-level intermediate language. But that's just documents, in fact the majority of HTML tags are rendering not text, but layouts, buttons, menus! So, in this scary state of affairs, where does one find <em>meaning</em>?</p>
<p><strong>Machines should be extracting meaning from APIs.</strong> That's where the all the tasty raw data is. APIs worry about pleasing the machines so that human interface developers don't have to. <a class="reference external" href="http://blog.programmableweb.com/2012/05/22/6000-apis-its-business-its-social-and-its-happening-quickly/">API use is growing very fast</a> and I am psyched to see the information ecosystem that will develop. As demands for complexity grow, the separation of human and machine interface is inevitable. This is a good design decision particularly because it lets us use domain-specific technologies.</p>
<p><strong>If a semantic tag replaces a presentational one and nobody is there to see it, is it still semantic?</strong> Okay, blind people might notice. Still, extracting meaning from HTML in this day and age is bad design and piling more bad design on top of it is not the solution. I don't know what the solution is, but it probably uses an API to serve raw data, has a web app for sighted users and a separate app for blind users. The latter can probably be generated from some sort of spec.</p>
</div>
<div class="section" id="we-don-t-need-more-tags">
<h2>We Don't Need More Tags</h2>
<p>Take form elements. How did we make forms before HTML5?</p>
<ol class="arabic simple">
<li>Begin by using standard <tt class="docutils literal"><input></tt>.</li>
<li>Beat them with CSS until they look the same in all browsers.</li>
<li>The designer says we need placeholders.</li>
<li>Find a jQuery plugin, integrate it into the form.</li>
</ol>
<p>With HTML5, this is how we make forms:</p>
<ol class="arabic simple">
<li>Begin by using standard <tt class="docutils literal"><input></tt>.</li>
<li>Beat them with CSS until they look the same in all browsers.</li>
<li>The designer says we need placeholders.</li>
<li>Use the <tt class="docutils literal">placeholder</tt> tag.</li>
<li>Realize that some browsers hide the placeholder tag when input is focused while some keep it.</li>
<li>Get rid of <tt class="docutils literal">placeholder</tt> tag, find a jQuery plugin and integrate it.</li>
</ol>
<p>Case in point.</p>
</div>
<div class="section" id="committee-vs-competition">
<h2>Committee vs. Competition</h2>
<p>All of these problems come down to one: the HTML platform is being <a class="reference external" href="http://en.wikipedia.org/wiki/Design_by_committee">designed by people who think they know what's best for you</a>. Which means:</p>
<ol class="arabic simple">
<li>The standards are always playing catch-up with reality</li>
<li>Browsers are always playing catch-up with the standards</li>
<li>The stardards are made to appease everyone, including people you don't care about</li>
</ol>
<p>The open-source community can build its own technologies on top of the web platform's low-level APIs. Did we wait for CSS to implement variables? No, <a class="reference external" href="http://sass-lang.com/">we built an awesome CSS preprocessor</a>. Fast forward 5 years and a browser finally lands (a syntactically abominable) implementation of <a class="reference external" href="http://dev.w3.org/csswg/css-variables/">CSS variables</a>. So spectacularly little and so spectacularly late; there is absolutely no reason to use CSS variables over the vastly superior <a class="reference external" href="http://sass-lang.com/">Sass</a>, <a class="reference external" href="http://lesscss.org/">Less</a> or <a class="reference external" href="http://learnboost.github.com/stylus/">Stylus</a>. <strong>CSS variables were dead 5 years before they were born</strong>.</p>
</div>
<div class="section" id="an-alternative-vision">
<h2>An Alternative Vision</h2>
<p>The web platform is not immune to failure as it competes with mobile app platforms. HTML5 is still catching up with Flash, <a class="reference external" href="http://transitioning.to/2012/03/will-html5-ever-catch-up-to-flash-on-features/">and some have doubts that it ever will</a>. Things are changing so fast these days, HTML5 is bound to have some solid competition soon. In order to survive, the web platform has to embrace the kind of guys that build Sass and <a class="reference external" href="http://coffeescript.org/">CoffeeScript</a> instead of pretending they don't exist. How long until "HTML5 is dead"?</p>
<p>Here is my vision of a better future for the web platform:</p>
<ol class="arabic simple">
<li>Deprecate all non-presentational tags, perhaps everything but SVG</li>
<li>Double JavaScript's speed by replacing it with compatible bytecode X</li>
<li>Deprecate everything (from HTML and CSS) that can be efficiently replicated in X, provide it as a forkable open-source library. This includes but is not limited to: UI elements (previously known as form elements), all typesetting and the vast majority of CSS properties.</li>
<li>Things that can't be efficiently replicated in X should be provided as low-level APIs (WebGL, canvas etc.).</li>
</ol>
<p>This should be the extent of the web as a platform. Everything else will be determined by the free market. An insane proposal? Perhaps.</p>
<p>Time will tell.</p>
</div>
Cult of Logic-Less Templates2012-09-07T00:00:00-04:002012-09-07T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-09-07:/2012/09/07/Cult-Of-Logic-less-Templates/<p>Logic-less templates like <a class="reference external" href="http://mustache.github.com/">Mustache</a>, <a class="reference external" href="http://handlebarsjs.com/">Handlebars</a>, <a class="reference external" href="http://twitter.github.com/hogan.js/">Hogan</a> etc. have taken the JavaScript community by storm. I believe they promote bad practices and are perpetuated by dogmatic claims that don't correspond to reality.</p>
<div class="section" id="separation-of-concerns-my-ass">
<h2>Separation of Concerns My Ass</h2>
<p>Undoubtedly, business and presentational logic should be kept separate. The claim that logic-less templates …</p></div><p>Logic-less templates like <a class="reference external" href="http://mustache.github.com/">Mustache</a>, <a class="reference external" href="http://handlebarsjs.com/">Handlebars</a>, <a class="reference external" href="http://twitter.github.com/hogan.js/">Hogan</a> etc. have taken the JavaScript community by storm. I believe they promote bad practices and are perpetuated by dogmatic claims that don't correspond to reality.</p>
<div class="section" id="separation-of-concerns-my-ass">
<h2>Separation of Concerns My Ass</h2>
<p>Undoubtedly, business and presentational logic should be kept separate. The claim that logic-less templates keep business logic out of templates is true, but why does no one consider the other side of the story: keeping presentational logic out of business code? With lobotomized template systems like Mustache, you are forced to perform a bunch of "data-massaging" in your code before running it through the template system. Not only does it feel like stepping back into the iron age, this actually violates SoC!</p>
<p>The reality is: <strong>dividing business and presentational logic is a design problem that requires you to use your brain.</strong> Yes, you! You can't make the problem go away by redefining presentational logic as a simple JSON-to-string transformation. In fact, presentational logic doesn't give a damn about your lazy opinions, it just is. Your job is to find it and consolidate it.</p>
</div>
<div class="section" id="less-is-more">
<h2>Less is More</h2>
<p><strong>The less features you are given, the more code you will have to write on your own.</strong> Micro- this and minimalist that come at a price: you will inevitably find yourself reinventing the wheel. If your templating system doesn't support conditionals, or sorting or date formatting, you will have to implement it all yourself, in the god-awful data-massaging portion of your code. <strong>Data-massaging makes me want to pour salt on snails.</strong></p>
</div>
<div class="section" id="so-what-s-the-solution">
<h2>So, what's the solution?</h2>
<p>I think Django has a very good approach:</p>
<ol class="arabic simple">
<li>Your Controllers (or Views, whatever) pass the relevant Models into the template system</li>
<li>The template system handles all presentational logic, traversing model relationships by calling on the model system when necessary. This can be and often is part of presentational logic (e.g. showing the latest activity on a user's profile page). Of course, all operations should be read-only.</li>
<li>When multiple templates need the same data processing for a particular model, factor that processing into the model, and call this method from the template system (e.g. full name = first name + last name).</li>
<li>When multiple templates need the same data processing for different models, extend the template system.</li>
</ol>
<p>This calls for a real templating system, not a gimmick. It should:</p>
<ol class="arabic simple">
<li>Handle all kinds of presentational logic (even <tt class="docutils literal">if</tt> statements <em>gasp</em>)</li>
<li>Encourage Separation of Concerns</li>
<li>Be extensible, have a rich library of generic, useful functions such as date formatting, truncation, pluralization etc.</li>
<li>Support template inheritance (if used for website layouts).</li>
</ol>
<p>Designing such a template system is a real challenge, but it really pays off. I have a good deal of experience with the <a class="reference external" href="https://docs.djangoproject.com/en/dev/ref/templates/">Django template system</a>, I think it really rocks. For JavaScript, <a class="reference external" href="https://github.com/visionmedia/jade">Jade</a> looks very good, it also seems to be the only JavaScript templating language to support template inheritance.</p>
<p>Be wary of technological solutions to design problems, more often than not they are a scam!</p>
</div>
Strong Password Hashing with Node.js Standard Library2012-08-30T00:00:00-04:002012-08-30T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-08-30:/2012/08/30/Strong-Password-Hashing-with-Node-Standard-Library/<p>Cracking your users' hashed and salted password is pretty damn easy these days. To make it a bit harder for the bad guys, you should use something like <a class="reference external" href="http://en.wikipedia.org/wiki/PBKDF2">PBDFK2</a>, which hashes the password thousands of times before giving you back the result. This is called <a class="reference external" href="http://en.wikipedia.org/wiki/Key_stretching">key-stretching</a> and it helps simply …</p><p>Cracking your users' hashed and salted password is pretty damn easy these days. To make it a bit harder for the bad guys, you should use something like <a class="reference external" href="http://en.wikipedia.org/wiki/PBKDF2">PBDFK2</a>, which hashes the password thousands of times before giving you back the result. This is called <a class="reference external" href="http://en.wikipedia.org/wiki/Key_stretching">key-stretching</a> and it helps simply by making your passwords more computationally expensive to crack.</p>
<p>Here's a neat little function you can use to hash (and then verify) your passwords in Node.js, using its <a class="reference external" href="http://nodejs.org/api/crypto.html">crypto</a> module.</p>
<div class="highlight"><pre><span></span><span class="nv">crypto</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="w"> </span><span class="s">'crypto'</span><span class="w"></span>
<span class="nv">hasher</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">(opts, callback) -></span><span class="w"></span>
<span class="w"> </span><span class="c1"># Generate a random 8-character base64 password if none provided</span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">not</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">plaintext</span><span class="w"></span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">crypto</span><span class="p">.</span><span class="nx">randomBytes</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span><span class="w"> </span><span class="nf">(err, buf) -></span><span class="w"></span>
<span class="w"> </span><span class="nx">callback</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"></span>
<span class="w"> </span><span class="nv">opts.plaintext</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">buf</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'base64'</span><span class="w"></span>
<span class="w"> </span><span class="nx">hasher</span><span class="w"> </span><span class="nx">opts</span><span class="p">,</span><span class="w"> </span><span class="nx">callback</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Generate random 512-bit salt if no salt provided</span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">not</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">salt</span><span class="w"></span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">crypto</span><span class="p">.</span><span class="nx">randomBytes</span><span class="w"> </span><span class="mi">64</span><span class="p">,</span><span class="w"> </span><span class="nf">(err, buf) -></span><span class="w"></span>
<span class="w"> </span><span class="nx">callback</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"></span>
<span class="w"> </span><span class="nv">opts.salt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">buf</span><span class="w"></span>
<span class="w"> </span><span class="nx">hasher</span><span class="w"> </span><span class="nx">opts</span><span class="p">,</span><span class="w"> </span><span class="nx">callback</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Node.js PBKDF2 forces sha1</span><span class="w"></span>
<span class="w"> </span><span class="nv">opts.hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">'sha1'</span><span class="w"></span>
<span class="w"> </span><span class="nv">opts.iterations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">iterations</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="mi">10000</span><span class="w"></span>
<span class="w"> </span><span class="nx">crypto</span><span class="p">.</span><span class="nx">pbkdf2</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">plaintext</span><span class="p">,</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">salt</span><span class="p">,</span><span class="w"> </span><span class="nx">opts</span><span class="p">.</span><span class="nx">iterations</span><span class="p">,</span><span class="w"> </span><span class="mi">64</span><span class="p">,</span><span class="w"> </span><span class="nf">(err, key) -></span><span class="w"></span>
<span class="w"> </span><span class="nx">callback</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"></span>
<span class="w"> </span><span class="nv">opts.key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="nx">Buffer</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="nx">callback</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="nx">opts</span><span class="w"></span>
</pre></div>
<p><tt class="docutils literal">opts</tt> is an object with a number of optional components:</p>
<ul class="simple">
<li><tt class="docutils literal">plaintext</tt>: The password to be hashed. If it is not provided, an 8 character base64 password will be randomly generated.</li>
<li><tt class="docutils literal">iterations</tt>: How many times should the hash function be applied. Defaults to 10000. <a class="reference external" href="http://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pkbdf2-sha256">Strong enough?</a></li>
<li><tt class="docutils literal">salt</tt>: A string or <a class="reference external" href="http://nodejs.org/api/buffer.html">Buffer</a> with the salt. If not provided, a 512-bit salt will be randomly generated.</li>
</ul>
<p>Your callback should accept an object similar to the above, but with an additional component: <cite>key</cite> - the resulting 512-bit hash in the form of a Buffer.</p>
<div class="section" id="hashing-a-password">
<h2>Hashing a password</h2>
<div class="highlight"><pre><span></span><span class="nx">hasher</span><span class="w"> </span><span class="p">{</span><span class="nv">plaintext</span><span class="o">:</span><span class="w"> </span><span class="s">'secret'</span><span class="p">},</span><span class="w"> </span><span class="nf">(err, result) -></span><span class="w"></span>
<span class="w"> </span><span class="c1"># Save as hex strings</span><span class="w"></span>
<span class="w"> </span><span class="nv">user.salt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">salt</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="w"> </span><span class="nv">user.key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">save</span><span class="p">()</span><span class="w"></span>
</pre></div>
</div>
<div class="section" id="verifying-a-password">
<h2>Verifying a password</h2>
<div class="highlight"><pre><span></span><span class="c1"># Hex string to Binary</span><span class="w"></span>
<span class="nv">salt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="nx">Buffer</span><span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">salt</span><span class="p">,</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="nx">hasher</span><span class="w"> </span><span class="p">{</span><span class="nv">plaintext</span><span class="o">:</span><span class="w"> </span><span class="s">'secret'</span><span class="p">,</span><span class="w"> </span><span class="nv">salt</span><span class="o">:</span><span class="w"> </span><span class="nx">salt</span><span class="p">},</span><span class="w"> </span><span class="nf">(err, result) -></span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="w"> </span><span class="s">'Success!'</span><span class="w"></span>
</pre></div>
</div>
<div class="section" id="generating-a-password">
<h2>Generating a password</h2>
<div class="highlight"><pre><span></span><span class="nx">hasher</span><span class="w"> </span><span class="p">{},</span><span class="w"> </span><span class="nf">(err, result) -></span><span class="w"></span>
<span class="w"> </span><span class="c1"># Save as hex strings</span><span class="w"></span>
<span class="w"> </span><span class="nv">user.salt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">salt</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="w"> </span><span class="nv">user.key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">toString</span><span class="w"> </span><span class="s">'hex'</span><span class="w"></span>
<span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">save</span><span class="w"> </span><span class="nf">-></span><span class="w"></span>
<span class="w"> </span><span class="nx">postmark</span><span class="p">.</span><span class="nx">send</span><span class="w"></span>
<span class="w"> </span><span class="nv">From</span><span class="o">:</span><span class="w"> </span><span class="s">"you@example.com"</span><span class="w"></span>
<span class="w"> </span><span class="nv">To</span><span class="o">:</span><span class="w"> </span><span class="nx">user</span><span class="p">.</span><span class="nx">email</span><span class="w"></span>
<span class="w"> </span><span class="nv">Subject</span><span class="o">:</span><span class="w"> </span><span class="s">"Thank you for signing up with Example.com"</span><span class="w"></span>
<span class="w"> </span><span class="nv">TextBody</span><span class="o">:</span><span class="w"> </span><span class="s">"Your temporary password is </span><span class="si">#{</span><span class="nx">result</span><span class="p">.</span><span class="nx">plaintext</span><span class="si">}</span><span class="s">"</span><span class="w"></span>
</pre></div>
<p>Let's end on a troubling note, courtesy of <a class="reference external" href="http://www.tarsnap.com/scrypt/scrypt.pdf">scrypt</a> and <a class="reference external" href="http://stackoverflow.com/questions/4433216/password-encryption-pbkdf2-using-sha512-x-1000-vs-bcrypt">this StackOverflow answer</a>.</p>
<img alt="Prices for password cracking" src="https://www.boronine.com/images/cracking_prices.png" />
<p>Hash, rinse, repeat!</p>
</div>
Asynchronous Form Field Validation with Ember2012-08-09T00:00:00-04:002012-08-09T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-08-09:/2012/08/09/Asynchronous-Form-Field-Validation-With-Ember/<p>I've been playing around with Ember.js recently. Here is my approach at implementing synchronous (username length) and asynchronous (username availability) validation, encapsulated in an Ember.js View. The code is a bit long, but it is more declarative and thus predictable than its jQuery spaghetti counterpart. Here's the <a class="reference external" href="https://gist.github.com/3301728">gist …</a></p><p>I've been playing around with Ember.js recently. Here is my approach at implementing synchronous (username length) and asynchronous (username availability) validation, encapsulated in an Ember.js View. The code is a bit long, but it is more declarative and thus predictable than its jQuery spaghetti counterpart. Here's the <a class="reference external" href="https://gist.github.com/3301728">gist</a> and here's the <a class="reference external" href="http://jsfiddle.net/zkbfE/">fiddle</a>.</p>
<div class="highlight"><pre><span></span><span class="nb">window</span><span class="p">.</span><span class="nv">App</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Ember</span><span class="p">.</span><span class="nx">Application</span><span class="p">.</span><span class="nx">create</span><span class="p">()</span><span class="w"></span>
<span class="nv">App.Focusable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Ember</span><span class="p">.</span><span class="nx">Mixin</span><span class="p">.</span><span class="nx">create</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Don't let events spoil your Kool-Aid!</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Let's get these out of the way by turning them</span><span class="w"></span>
<span class="w"> </span><span class="c1"># into a magical property:</span><span class="w"></span>
<span class="w"> </span><span class="nv">focused</span><span class="o">:</span><span class="w"> </span><span class="kc">false</span><span class="w"></span>
<span class="w"> </span><span class="nv">focusIn</span><span class="o">:</span><span class="w"> </span><span class="nf">(event) -></span><span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'focused'</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="w"></span>
<span class="w"> </span><span class="nv">focusOut</span><span class="o">:</span><span class="w"> </span><span class="nf">(event) -></span><span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'focused'</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="w"></span>
<span class="nv">App.AsyncValidation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Ember</span><span class="p">.</span><span class="nx">Mixin</span><span class="p">.</span><span class="nx">create</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Set up an observer that will watch when the field is</span><span class="w"></span>
<span class="w"> </span><span class="c1"># in and out of focus.</span><span class="w"></span>
<span class="w"> </span><span class="nv">valid</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nf">-></span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">@get</span><span class="w"> </span><span class="s">'focused'</span><span class="w"></span>
<span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'code'</span><span class="p">,</span><span class="w"> </span><span class="s">''</span><span class="w"></span>
<span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'message'</span><span class="p">,</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="w"> </span><span class="k">else</span><span class="w"></span>
<span class="w"> </span><span class="nv">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">@get</span><span class="w"> </span><span class="s">'value'</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Call the specific validation function, passing the</span><span class="w"></span>
<span class="w"> </span><span class="c1"># value to validate and a callback to which the function</span><span class="w"></span>
<span class="w"> </span><span class="c1"># must pass the result of the validation.</span><span class="w"></span>
<span class="w"> </span><span class="nx">@validate</span><span class="w"> </span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nf">(code, message) =></span><span class="w"></span>
<span class="w"> </span><span class="c1"># If everything's okay, we can show this result</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Make sure that the value hasn't changed and that</span><span class="w"></span>
<span class="w"> </span><span class="c1"># the field isn't being edited</span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">value</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">@get</span><span class="p">(</span><span class="s">'value'</span><span class="p">)</span><span class="w"> </span><span class="o">and</span><span class="w"> </span><span class="o">not</span><span class="w"> </span><span class="nx">@get</span><span class="p">(</span><span class="s">'focused'</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'code'</span><span class="p">,</span><span class="w"> </span><span class="nx">code</span><span class="w"></span>
<span class="w"> </span><span class="nx">@set</span><span class="w"> </span><span class="s">'message'</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="w"></span>
<span class="w"> </span><span class="p">).</span><span class="nx">observes</span><span class="w"> </span><span class="s">'focused'</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Dummy validation function</span><span class="w"></span>
<span class="w"> </span><span class="nv">validate</span><span class="o">:</span><span class="w"> </span><span class="nf">(value, next) -></span><span class="w"> </span><span class="nx">next</span><span class="w"> </span><span class="s">''</span><span class="p">,</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="nv">App.TextField</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="w"> </span><span class="nx">App</span><span class="p">.</span><span class="nx">Focusable</span><span class="p">,</span><span class="w"> </span><span class="nx">App</span><span class="p">.</span><span class="nx">AsyncValidation</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="nv">classNames</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="s">'control-group'</span><span class="p">]</span><span class="w"></span>
<span class="w"> </span><span class="nv">type</span><span class="o">:</span><span class="w"> </span><span class="s">'text'</span><span class="w"></span>
<span class="w"> </span><span class="c1"># This is the value of the field:</span><span class="w"></span>
<span class="w"> </span><span class="nv">value</span><span class="o">:</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="w"> </span><span class="c1"># And its placeholder:</span><span class="w"></span>
<span class="w"> </span><span class="nv">placeholder</span><span class="o">:</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Validation status. One of '', 'error' or 'success'</span><span class="w"></span>
<span class="w"> </span><span class="nv">code</span><span class="o">:</span><span class="w"> </span><span class="s">''</span><span class="w"></span>
<span class="w"> </span><span class="nv">classNameBindings</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="s">'code'</span><span class="p">]</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Error or success message</span><span class="w"></span>
<span class="w"> </span><span class="nv">message</span><span class="o">:</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="w"> </span><span class="nv">template</span><span class="o">:</span><span class="w"> </span><span class="nx">Ember</span><span class="p">.</span><span class="nx">Handlebars</span><span class="p">.</span><span class="nx">compile</span><span class="w"> </span><span class="s">"""</span>
<span class="s"> <div class="controls"></span>
<span class="s"> {{view Ember.TextField</span>
<span class="s"> placeholderBinding = "view.placeholder"</span>
<span class="s"> valueBinding = "view.value"</span>
<span class="s"> typeBinding = "view.type"</span>
<span class="s"> }}</span>
<span class="s"> <span class="help-inline">{{view.message}}</span></span>
<span class="s"> </div></span>
<span class="s"> """</span><span class="w"></span>
<span class="nv">App.EmailField</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">App</span><span class="p">.</span><span class="nx">TextField</span><span class="p">.</span><span class="nx">extend</span><span class="w"></span>
<span class="w"> </span><span class="nv">placeholder</span><span class="o">:</span><span class="w"> </span><span class="s">"Email"</span><span class="w"></span>
<span class="w"> </span><span class="nv">validate</span><span class="o">:</span><span class="w"> </span><span class="nf">(value, status) -></span><span class="w"></span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">value</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"></span>
<span class="w"> </span><span class="nx">status</span><span class="w"> </span><span class="s">''</span><span class="p">,</span><span class="w"> </span><span class="s">""</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Might catch the occasional typo</span><span class="w"></span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">value</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s">'@'</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="w"> </span><span class="o">or</span><span class="w"> </span><span class="nx">value</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s">'.'</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="w"></span>
<span class="w"> </span><span class="nx">status</span><span class="w"> </span><span class="s">'error'</span><span class="p">,</span><span class="w"> </span><span class="s">"Please enter a valid email"</span><span class="w"></span>
<span class="w"> </span><span class="k">else</span><span class="w"></span>
<span class="w"> </span><span class="c1"># Insert AJAX call here:</span><span class="w"></span>
<span class="w"> </span><span class="nx">setTimeout</span><span class="p">((</span><span class="nf">-></span><span class="w"></span>
<span class="w"> </span><span class="nx">status</span><span class="w"> </span><span class="s">'success'</span><span class="p">,</span><span class="w"> </span><span class="s">"Email address available"</span><span class="w"></span>
<span class="w"> </span><span class="p">),</span><span class="w"> </span><span class="mi">1000</span><span class="p">)</span><span class="w"></span>
</pre></div>
CoffeeScript Indentation for Sublime Text 22012-04-10T00:00:00-04:002012-04-10T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-04-10:/2012/04/10/CoffeeScript-Indentation-for-Sublime-Text-2/<p>If you haven't already, first install the <a class="reference external" href="http://wbond.net/sublime_packages/package_control/installation">Sublime Package Control</a>.</p>
<p>Next — if you haven't already — install the CoffeeScript plugin. After restarting Sublime, press <tt class="docutils literal"><span class="pre">Ctrl-Shift-P</span></tt> to open up the Command Palette, select the newly added command "Install Package" and use it to install the package "CoffeeScript".</p>
<p>To permanently save your indentation …</p><p>If you haven't already, first install the <a class="reference external" href="http://wbond.net/sublime_packages/package_control/installation">Sublime Package Control</a>.</p>
<p>Next — if you haven't already — install the CoffeeScript plugin. After restarting Sublime, press <tt class="docutils literal"><span class="pre">Ctrl-Shift-P</span></tt> to open up the Command Palette, select the newly added command "Install Package" and use it to install the package "CoffeeScript".</p>
<p>To permanently save your indentation settings as <a class="reference external" href="https://github.com/polarmobile/coffeescript-style-guide#tabs_or_spaces">2 spaces</a>, open <strong>Preferences > Settings - More > Syntax Specific - User</strong>. In the opened file, insert the following:</p>
<div class="highlight"><pre><span></span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="s2">"translate_tabs_to_spaces"</span><span class="o">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="s2">"tab_size"</span><span class="o">:</span><span class="w"> </span><span class="mf">2</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="s2">"use_tab_stops"</span><span class="o">:</span><span class="w"> </span><span class="kc">true</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>
<p>Happy coding!</p>
Color Spaces for Human Beings2012-03-26T00:00:00-04:002012-03-26T00:00:00-04:00Alexei Boroninetag:www.boronine.com,2012-03-26:/2012/03/26/Color-Spaces-for-Human-Beings/<p>A color space is a mathematical model for describing color as a tuple of values. Some color spaces, like RGB and CMYK, are based on display technology. Some are based on human physiology, some are derived for certain useful characteristics. In this post I will briefly explain how humans see …</p><p>A color space is a mathematical model for describing color as a tuple of values. Some color spaces, like RGB and CMYK, are based on display technology. Some are based on human physiology, some are derived for certain useful characteristics. In this post I will briefly explain how humans see color, why HSL is often the wrong tool for the job as well as provide an alternative to HSL.</p>
<div class="section" id="cones-and-waves">
<h2>Cones and Waves</h2>
<p>Light starts off as a fairly even mixture of waves of different wavelengths. When it bounces off an object, some wavelengths are absorbed, while others are reflected into your eye. Which ones? You'll never know for sure, but you can get <em>some</em> useful information by asking your three photoreceptors: S-, M- and L-cones. Each of them is sensitive to a certain range of wavelengths.</p>
<div class="figure">
<img alt="Cone response" src="https://www.boronine.com/images/cone-response.png" />
<p class="caption"><a class="reference external" href="http://en.wikipedia.org/wiki/File:Cone-response.svg">Picture credit</a></p>
</div>
<p>What is the definition of green? Green is when the M-cones are being stimulated more than the L-cones, while the S-cones are hardly stimulated at all. Reverse that relationship and you get red. Add some S-cone stimulation and you get purple. <strong>Colors are defined by cone stimulation, not wavelengths</strong>. In fact, <a class="reference external" href="http://en.wikipedia.org/wiki/Line_of_purples">there is no single wavelength that will produce the color purple</a>.</p>
<p>The more types of cones you have, the more colors you can see. 1% of males don't have any L-cones. Red and green light stimulates their remaining cones in an identical way, so to them they are the same color. Similarly, an alien with four types of cones will consider all of humanity color blind.</p>
</div>
<div class="section" id="rgb-and-hsl">
<h2>RGB and HSL</h2>
<p>It is easy to see from the above that a single color can be created in many different ways. In fact, we can choose just three primaries and combine them to create most humanly visible colors. Define red, green and blue to be within the [0, 1] range and you get the RGB color space, which can be naturally visualized as a cube.</p>
<p>RGB is used ubiquitously in computing because it happens to be the way most monitors output color. Even though its primaries correspond somewhat to our three types of cones, RGB is meaningless for us. Naturally, we tend to think of color in terms of hue, saturation and lightness — turns out there is a simple way to get these out of RGB.</p>
<div class="figure">
<img alt="HSL" src="https://www.boronine.com/images/hsl.png" />
<p class="caption">Image derived from <a class="reference external" href="http://en.wikipedia.org/wiki/File:Hsl-and-hsv.svg">Jacob Rus' original work</a></p>
</div>
<p>Behold, HSL. A cylindrical color space, hue represented by angle around the center vertical axis, saturation by distance from the axis and lightness by distance along the axis.</p>
</div>
<div class="section" id="hsl-is-a-lemon">
<h2>HSL is a Lemon</h2>
<p>Do these colors <em>really</em> have the same lightness?</p>
<div class="color-demo" style="background-color:hsl(250,100%,50%)">
<div class="black">HSL(250, 100%, 50%)</div>
<div class="white">HSL(250, 100%, 50%)</div>
</div>
<div class="color-demo" style="background-color:hsl(60,100%,50%)">
<div class="black">HSL(60, 100%, 50%)</div>
<div class="white">HSL(60, 100%, 50%)</div>
</div>
<div class="clearing"></div><p>HSL's lightness is only meaningful for a single color. If you try to compare the lightness of one color with the lightness of another using HSL, you will get terrible results. Please don't do it.</p>
<p>And these, are they really equally saturated?</p>
<div class="color-demo" style="background-color:hsl(0,90%,40%)">
<div class="black">HSL(0, 90%, 40%)</div>
<div class="white">HSL(0, 90%, 40%)</div>
</div>
<div class="color-demo" style="background-color:hsl(0,90%,80%)">
<div class="black">HSL(0, 90%, 80%)</div>
<div class="white">HSL(0, 90%, 80%)</div>
</div>
<div class="clearing"></div><p>HSL's saturation has the same problem. When you change the hue or the lightness of a color, its saturation measurement changes. Do not try to extract any meaning from comparing the saturation values of two different colors using HSL.</p>
<p>To make things even worse, HSL's hue value is not very perceptually uniform. To illustrate, HSL says that the hue difference between these colors</p>
<div class="color-demo" style="background-color:hsl(30,100%,50%)">
<div class="black">HSL(30, 100%, 50%)</div>
<div class="white">HSL(30, 100%, 50%)</div>
</div>
<div class="color-demo" style="background-color:hsl(50,100%,50%)">
<div class="black">HSL(50, 100%, 50%)</div>
<div class="white">HSL(50, 100%, 50%)</div>
</div>
<div class="clearing"></div><p>... is the same as the hue difference between these two colors.</p>
<div class="color-demo" style="background-color:hsl(230,100%,50%)">
<div class="black">HSL(230, 100%, 50%)</div>
<div class="white">HSL(230, 100%, 50%)</div>
</div>
<div class="color-demo" style="background-color:hsl(250,100%,50%)">
<div class="black">HSL(250, 100%, 50%)</div>
<div class="white">HSL(250, 100%, 50%)</div>
</div>
<div class="clearing"></div><p>Let's take a step back and list a few things you <em>should not</em> do with HSL:</p>
<ul class="simple">
<li>Find contrast between two colors</li>
<li>Find complementary colors</li>
<li>Adjust the lightness of an image</li>
<li>Adjust the saturation of an image</li>
<li>Shift the hue of an image</li>
</ul>
<p>In summary, HSL sucks. The reason it sucks is its simplicity, this is also the reason it grew popular in the 70s, when a more sophisticated model would have been too computationally expensive.</p>
</div>
<div class="section" id="good-news-everyone">
<h2>Good News Everyone!</h2>
<p>Let's go back to the late 20s, when W. David Wright and John Guild independently conducted a series of experiments on human sight. They showed their test subjects colors and asked them to match these colors by combining three primaries. If you plot how much of each primaries it took to duplicate the color of pure single-wavelength light, you get the RGB <em>color matching functions</em>.</p>
<div class="figure">
<img alt="RGB functions" src="https://www.boronine.com/images/rgb_functions.png" />
</div>
<p>In 1931, the International Commission on Illumination used these color matching functions to create a new color space, <a class="reference external" href="http://en.wikipedia.org/wiki/CIE_1931_color_space">CIE XYZ</a>. It was designed in such a way that its Y component represented the brightness of the color.</p>
<p>In 1976, CIE presented two color spaces derived from CIE XYZ: <a class="reference external" href="http://en.wikipedia.org/wiki/Lab_color_space">CIE Lab</a> and <a class="reference external" href="http://en.wikipedia.org/wiki/CIELUV">CIE LUV</a>, both attempting <em>perceptual uniformity</em>. They were adopted simultaneously when no consensus was formed in favor of one or the other. Some recommend CIE Lab for printing purposes and CIE LUV for light-emitting displays.</p>
<p>If we take CIE LUV and convert it to polar coordinates, we get CIE LCh<sub>uv</sub>, an alternative to HSL, with L representing lightness, C representing chroma (saturation) and h representing hue.</p>
</div>
<div class="section" id="in-conclusion">
<h2>In Conclusion...</h2>
<p>Update (May 18, 2012): Since writing this blog post, I've created a color space designed as an alternative to HSL: <a class="reference external" href="http://www.hsluv.org/">HSLuv</a>.</p>
<p>Know your color spaces! Do not use any of HSL's components as an absolute value, do not use HSL to compare colors or to manipulate images unless you need real-time speed. If you want to use CIE LCh<sub>uv</sub> or one of many other color spaces in your CoffeeScript of JavaScript projects, check out <a class="reference external" href="https://github.com/boronine/colorspaces.js">colorspaces.js</a>, my tiny Node.js and jQuery library.</p>
<div class="figure">
<img alt="Crayons" src="https://www.boronine.com/images/crayons.jpg" />
</div>
</div>