Wednesday, June 4, 2014

Liar Paradoxes and Godel Numbering: An Introduction to Incompleteness

The previous post on recursion had an ulterior motive: laying the groundwork for an explanation of Gödel's Incompleteness Theorems.  It took me a long while to fully grok the underlying logic, but through no fault of the theorems themselves.  Rather, I've noticed a dearth of good online explanations.  The Wikipedia artile is obtuse to say the least, Gödel Escher Bach and Gödel's Proof cost money, and neither of them is web-based anyway.  So let's fix that, shall we?
Just a short prewarning: the different parts of this post will feel somewhat disconnected at first, but it'll all come together by the end.

The Liar Paradox
Ah, the Liar Paradox - we've all encountered it in one form or another, but the one most useful to us is this:

> This sentence is a lie

Or, if you like recursive acronym's:

> INIAL's name is a lie

Which expands to

> "INIAL's name is a lie" is a lie

On and on to infinity.  The interesting thing about this sentence is that, while it doesn't make sense to call it true, it doesn't really mean anything to call it false either.  It is instead stuck in a strange oscillating limbo of contradiction where it's not clear the statement has any meaning at all.  In a word, the statement is inconsistent, as is any system that can prove it.  This notion isn't yet all that useful, but what we'll find by the end of this article is that it's actually quite portable.


Gödel Numbering
Let's first take a short detour though.  At some level, we know we can represent any string of characters with a string of bits - after all, this is exactly what computers do to store text.  And, similarly, it's pretty trivial to interpret a string of bits as a number.  Now, in and of itself this doesn't seem that revolutionary, but the reducibility of strings to numbers actually leads to an incredibly important result in mathematics - namely, that you can reason about arithmetic from within itself.  After all, for any string \(\sigma\), "\(\sigma\) is a valid theorem in Peano Arithmetic" becomes a valid predicate, as does "\(\sigma\) is a true statement of number theory".  Suddenly, we've found a way to get arithmetic to swallow its own tail and can begin to use it for metamathematical reasoning.
Indeed, all axiomatic systems can be embedded in some manner similar to this - all it takes is some sufficiently clever ways of doing typographical manipulations of numbers.

A Short Interlude: MIU Gödelized
You may or may not remember my post on the MIU System, but in case you don't, here are the axioms again (note: I use lowercase characters for placeholders, and upper case for MIU characters)

- If we can construct x, we can construct xU
- If we can construct Mx, we can construct Mxx
- If we can construct xIIIy, we can construct xUy
- If we can construct xUUy, we can construct xy
- We can construct MI

A very primitive way to encode this is to make a number, where every M is a 3, every I is a 1, and every U is a 0.  If we do this, we can rephrase the axioms in terms of numerical operations:

- If we can construct x, we can construct \( x \cdot 10 \)
- If we can construct \( 3 \cdot 10^n + x \), we can construct \( 3 \cdot 10^{2n} + x \cdot 10^n + x \)
- If we can construct \( x \cdot 10^{n+3} + 111 \cdot 10^n + y\), we can construct \(x \cdot 10^{n+1} + y \)
- If we can construct \( x \cdot 10^{n+2} + y\), we can construct \(x \cdot 10^n + y \)
- We can construct \( 31 \)

Of course, this method of encoding is relatively primitive and hard to reason about, but it's more than sufficient as a proof-of-concept.  And, importantly, it demonstrates one of the most important facts of positional notation - typographical operations become as simple as separating the positions out and doing funny operations on the individual pieces.  But, as much as I'd love to delve into a long rant about number and string encoding, we have a topic to get back to.

Bringing it all together
So, where are we going with all this nonsense?  Well, we've already seen how simple it is to embed statements like "\(\sigma\) is a valid theorem in Peano Arithmetic", so why not use the weaker notion "\(\sigma\) is provable in Peano Arithmetic"?  (Or, more formally, "\(\exists\lambda\) such that \(\lambda\) is a valid proof of \(\sigma\)").  Or, similarly, "\(\sigma\) is not provable in Peano Arithmetic".  Now, this notion itself isn't that useful, but we can construct a true statement \(\epsilon\) that reads "\(\epsilon\) is not provable in Peano Arithmetic" - suddenly, the statement is talking directly about its own provability.  And, in a similar vein to the liar paradox, it can't be proven without also showing inconsistency.  So, either we can prove both \(\sigma\) and \(\neg\sigma\) or we can't prove \(\sigma\) (and therefore \(\sigma\) is true).  And, if we can't prove \(\sigma\), then we've just constructed a statement that is both true and can't be proven.  This creates a dichotomy: either a formal system is inconsistent, or it's incomplete.  And so ends Hilbert's Program.

Monday, April 28, 2014

Recursion Explained

This is the first in a series of posts with a specific, targeted audience, which means there's going to be a relatively wide variation in level-of-explanation. Some of the posts are going to very clearly be me-writing-for-someone-who-already-knows-lots-of-relevant-information, and some (like today's) will be me-writing-for-someone-who-wouldn't-normally-read-this-blog. Anyway, today's topic is what recursion is and why we should care. If you already think recursion is important, this post'll be pretty surface-y and review-heavy. So, let's get started, shall we?


Recursive-Xzibit thinks Recursive-Xzibit thinks Recursive-Xzbit thinks ... that recursion is fun

So yeah, recursion.  The basic idea is something that acts on itself, or something with multiple different levels.  And oh, the places you can go with self reference!
The most recent/significant pop-cultural example I can think of is the movie Inception, where dreams could occur within dreams within dreams, and what happened in one level would bleed down into all the levels below it (e.g. when gravity stopped in the hotel because the truck they were dreaming in was falling off a bridge).  
Recursion comes in a few different classes, and I've yet to hear any good terms to differentiate them, so I'm going to make some up:

  • Unidirectional recursion
    • Feedback only goes in only one direction
    •  Example 1: The Fibonacci Sequence (each element is the sum of the previous two elements, the first few are \(0, 1, 1, 2, 3, 5, 8, 13, 21...\)) - the later parts of the list are completely unimportant in figuring out the first few
    • Example 2: Sorting a list (using quicksort) - one simple and efficient way to sort a list is a monotonic recursion - you pick the first number off the list, split the rest of it in two by putting all the numbers smaller than the first one on one side and bigger on the other, then sort each of those sublists

  • Bidirectional recursion
    • Feedback can go in either direction
    • Example: Inception - the environment you're dreaming in influences the dream, but the events within the dreams have lasting influence in the outside world (e.g. planting an idea in someone's head, taking useful information, etc)
    • Example 2: INT - this graph is sorta strange.  It's constructed entirely out of smaller versions of itself - any single point contains the whole graph.  The lower levels are exactly the same as the higher ones.  Cool, right?
    •  

  • Mutual recursion
    • Two things that are defined, each one in terms of the other
    • This one's generally a bit more complicated than the other two
    • One set of good examples can be found in Hofstadter Sequences - specifically, the Figure-Figure sequence
    • It's pretty neatly defined in terms of itself and its complement (the set of all numbers not in the sequence)
    • The first number of the sequence (\(R(0)\), if you will) is \(1\)
    • The first number not in the sequence (Let's call it \(S(0)\)) is \(2\)
    • The rest of the sequence is defined \(R(n) = R(n-1) + S(n-1)\)
    • So, for example, \(R(1) = R(0) + S(0) = 3\), and \(R(2) = R(1) + S(1) = (R(0) + S(0)) + S(1) = (2+1) + S(1) = 3 + S(1) = 3 + 4 = 7\)
    • Let's write out another one just for kicks: 
    •  \(R(3) = R(2) + S(2) =  (R(1) + S(1)) + S(2)\)
    • \(= ((R(0)+S(0))+S(1))+S(2) = (3+4)+5 = 12\)

     So, why should we care exactly?  Why does this fancy "recursion" thing even matter?  Well, it's by far the most elegant (and sometimes the only) way to define all those things up there, but let's say you didn't care about any of those.  Why recursion?

    Well, given that the target audience here is into music theory, let's start with the immediately relevant example: fugues.  Fugues are recursive - you start from a relatively well defined structure, then modify it according to various rules and weave the modifications together, and, if you know what you're doing, beautiful music comes out.



    Convinced you care yet?  No?  What was that?  "More examples"?  Great.

    Well, recursion is useful in understanding language.  I'd go into it, but Guy Steele did a presentation on this a while ago, and it's one of my favourite talks on the internet, so I'll link to that instead.


    That brings me to my next point pretty nicely actually - recursion is extremely important in programming.
    I'll summarize a bit, but recursion-in-programming really deserves its own post
    A relatively common idiom is to define a base case and a way to reduce anything else to said base case.  We saw a few examples of that earlier, with the Fibonacci and Figure-Figure sequences - we defined \(F(0)\), \(S(0)\), and \(R(0)\), then gave rules for computing the rest of the sequences in terms of the first element.
    But, to take a more programming-y example, let's say you've got some operation (we'll call it f) and you want to apply it to each element of a list. How would you go about that?
    Well, you'd probably start by applying the operation to the first result of the list, then start again with the rest of the list, until you've f'd every element.

    So, we've seen that recursion gives us pretty ways to define seemingly messy things, but the discussion is still incomplete.  Why?
    Simple.
    I haven't pulled out the pretty colors.
    A discussion of recursion always has to end with fractals, so we'll start with a joke, then follow up with a pretty picture:

    I recently saw someone post a question on Quora, "What's the prettiest image ever found by zooming in on the Mandelbrot set?" - The best answer was, of course, "The Mandelbrot set".
    The Mandelbrot set is defined by doing some funky things with complex numbers, and the trick is that it ends up containing infinitely many smaller versions of itself - Just about anywhere along the boundary, if you zoom in enough, you'll find a (often very slightly deformed) copy of the whole set.

    So, without further ado, pretty colors

Monday, April 7, 2014

Playing with Probabilities

MDists.lhs

The Header

Imports, pragmas, and the module declaration

> {-# LANGUAGE TupleSections #-}
> module MDists where
> import Data.Map (Map, (!))
> import qualified Data.Map as M
> import Data.Function
> import Data.List
> import Data.Ratio

The Code

> type P = Rational
> type PDist a = Map a P

Hypotheses are getting represented as probability distributions with a probability attached to them

> data Hypothesis a = H {conditionals :: PDist a,
>                          chance :: P} deriving (Show)

Next, the distribution over hypotheses - let’s make strings our labels, just because strings are easy to use

> data HDist a = HD {hps :: Map String (Hypothesis a)} deriving (Show)

Helpers

First, we want to implement a few basic funcitons that will allow the rest of these to work nicely For example, we’ll want to be able to apply some function [0, 1] → [0, 1] to the probabilities we’re juggling here

> applyToProbability :: (P -> P) -> Hypothesis a -> Hypothesis a
> applyToProbability f (H d p) = H d $ f p

That one’s pretty simple, but on its own not that useful. Instead, let’s wrap it up so we don’t have to deal with the individual hypotheses - instead, we’ll map it over a the hypothesis distribution

> applyToProbs :: (P -> P) -> HDist a -> HDist a
> applyToProbs f (HD hps) = HD $ M.map (applyToProbability f) hps

Now, the main reason we’re defining those two functions is to write a function renormalize that takes a distribution and makes sure the probabilities actually sum to 1 without changing any of the ratios between probabilities

> renormalize :: HDist a -> HDist a
> renormalize h@(HD dist) = applyToProbs (/normalizer) h
>   where normalizer = M.foldl' (+) 0 . M.map chance $ dist

Our basic guess function is just a small wrapper around M.lookup - it fetches the likelihood of a hypothesis on its identifier If we don’t have a hypothesis in our distribution, it assigns it a probability of 0, but otherwise just fetches the probability from the hypothesis

> guess :: Ord a => HDist a -> String -> P
> guess (HD hps) str = case M.lookup str hps of Nothing -> 0
>                                               Just h -> chance h

Updating!

Now, our not-so-secret goal here was to model Bayesian updates If you’re not familiar with Bayes’ Theorem, here it is:

$$p(H|D)=p(D|H)\frac{p(H)}{p(D)}$$

To explain: the probability of a hypothesis being true, on some data, is the probability of that data given the hypothesis (p(DH)) multiplied by the probability we had previously assigned the hypothesis (our “prior”, or p(H)), then divided by the probability of that data under all hypotheses (p(D)). We don’t deal directly with the probability of the data under all hypotheses - instead preferring to renormalize the distribution after the fact

Of course, we want to automate this adjustment. The first step is to multiply each probability by the numerator - p(DH) ⋅ p(H)

> pAndCond :: Ord a => a -> Hypothesis a -> Hypothesis a
> pAndCond event (H dist prior) = H dist $ prior * likelihood
>   where likelihood = M.findWithDefault 0 event dist

With that done, we just renormalize, effecitvely dividing by p(D) We know this works because if we divided by anything other than the renormalizer, the ending probabilities would sum to some number other than 1, so, on pain of contradiction,
p(D) = renormalizer

> updateOnEvent :: Ord a => HDist a -> a -> HDist a
> updateOnEvent (HD dist) event = renormalize . HD . M.map (pAndCond event) $ dist

Of course, we want to be able to update on a series of events, so we fold over a list of events This fold ends up being fully strict, so instead of a foldr we use foldl' (hooray tail recursion!)

> update :: Ord b => HDist b -> [b] -> HDist b
> update = foldl' updateOnEvent

Construction helpers

We’ll use these utilities to construct and solve some toy problems a little further down First, a few more helpers that’ll be really important for constructing the toy problems

This one just normalizes a hypothesis, so we can think of it in terms of allocating odds instead of probabilities

> normalizeHyp :: Hypothesis a -> Hypothesis a
> normalizeHyp (H m p) = if totalP == 1 then (H m p) else H (M.map (/totalP) m) p
>   where totalP = M.foldl' (+) 0 m

Next, this one just makes a hypothesis distribution from a list

> fromList :: [(String, Hypothesis a)] -> HDist a
> fromList = renormalize . HD . M.fromList

Toy Problems

Monty Hall

We’ll start out by getting a list of doors

> drs = "abc"

Next, our function for generating a hypothesis for which door gets opened based on our guess and the correct answer

> isIn :: Char -> Char -> Hypothesis Char
> isIn guess correct = normalizeHyp . flip H 1 . M.fromList $
>                      [(dr,1) | dr <- drs, dr /= guess, dr /= correct]

And, finally, the problem itself! The identifiers are each just the single character name of the door (a, b, or c) The hypotheses are each generated assuming the identifier is the correct door according to the isIn function

> montyHall :: Char -> HDist Char
> montyHall guess = fromList [([dr],isIn guess dr) | dr <- drs]
> shouldYouSwitch = guess (update (montyHall 'a') "b") "a" < 1 % 2

And there you go! The boolean shouldYouSwitch starts from you picking door a, then Monty opens b, and checks if you have worse than even chances of it being behind a

Cookies

We’ve got two bools of chocolate and vanilla cookies The first bowl is three quarters vanilla and one quarter chocolate, while the other is half and half

> bowl1 = normalizeHyp $ flip H 1 $ M.fromList [('v',3),('c',1)]
> bowl2 = normalizeHyp $ flip H 1 $ M.fromList [(a,1) | a <- "vc"]

Next we’ll make a distribution from both the bowls

> bowls = fromList  [("b1",bowl1),("b2",bowl2)]

From this, given a stream of cookies, it’ll guess the chance you were drawing from one of the bowls

M&M’s

Some background: The mixture of M&M’s has been changed a few times In 1995, blue M&M’s were introduced Given a bundle of M&M’s, what’s the probability it came from a 1994 mix vs a 1996 mix?

color percentage in ’94 percentage in ’96
brown 30 24
green 10 20
orange 10 16
yellow 20 14
red 20 13
tan 10 0
blue 0 13

Now, let’s encode that into hypotheses

> mix94 = normalizeHyp . flip H 1 $ M.fromList
>         [("brown",30),("green",10),("orange",10),("yellow",20),("red",20),("tan",10)]
> mix96 = normalizeHyp . flip H 1 $ M.fromList
>         [("brown",24),("green",20),("orange",16),("yellow",14),("red",13),("blue",13)]

And, finally, our hypothesis distribution

> bag = fromList [("94",mix94),("96",mix96)]

Thursday, March 13, 2014

Exporting Literate Haskell With HSColour and Pandoc

In yesterday's post I said I would detail the workflow from literate Haskell + markdown to postable html, so here we go:

Requirements: You need to have Haskell installed somehow. I generally recommend the Haskell Platform installed through your OS's package manager (pacman, apt-get, homebrew...). At a minimum, you need ghc and cabal-install Next, you need hscolour and pandoc installed. If you already have them, great! If not, run these commands:

cabal install hscolour
cabal install pandoc

Once you have those installed, it's relatively simple - just run this script:

There you go! Now you've highlighted the code bits, and left the rest to be formatted as markdown!

Isomorphism, Equality, PQ, and Other Ways of Saying the Same Thing

Note: this whole document is literate code generated by a workflow I'll talk a bit more about tomorrow.  It's a short shell script that's quite useful.  You can find the program as a gist on github.

So we’ll first take as an axiom that math is based on axioms. So far so good? Well, an important thing to note with this is that it’s really easy for axioms to have different significance - it all comes down to what metaphor you use in your brain to describe the axiomset
For example, MIU seems wholly abstract, but it turned out to be isomorphic to some operations on the integers modulo 3. And that isomorphism allowed some things to be made clear about it that weren’t otherwise.
In Chapter 2, Hofstadter defines some axioms that he calls the “PQ system”. These axioms are:
  1. The only valid characters are -, P, and Q
  2. -P-Q-- is a theorem
  3. x. xP -Q -x is a theorem
  4. xyz. if xP yQ z is a theorem, then xP -yQ -z is a theorem
First lets define our types Hyphen strings are essentially equivalent to natural numbers, so we’ll make that explicit

> data Nat = Zero | S Nat deriving (Show, Read)
> data Str = PQ Nat Nat Nat deriving (Show, Read)

Next we’ll define a few numbers for convenience

> one = S Zero
> two = S one

And this is all we really need Now let’s define the basic axiomset

> a1 = PQ one one two
> a2 (PQ a1 a2 s) = PQ (S a1) a2 (S s)
> a3 (PQ a1 a2 s) = PQ a1 (S a2) (S s)

Now we generate a list of all the theorems by iterating a2 starting from a1, and then mapping and iterating a3 over that list. Isn't it wonderful what you can do with lazy evaluation?

> theorems = map (iterate a3) $ iterate a2 a1

Now this is great if we just want the list of all axioms, but not really that useful if we want to check if something’s in there. You know, given the infinite axiom space and all. So right now checking for theoremhood is actually really computationally difficult - you have to produce all axioms and just check if something’s in there. Now, there are some strings where it’s obvious that it’s not a theorem - P-Q-PPP is malformed, like 3$&*(! So, how would we go about making a deterministic test that finishes in finite time?
This is your cue to try and solve the problem yourself before spoilers.
So, to review:
  • We’ve got an infinite list of theorems, generated by some recursive rules
  • Our job is to somehow figure out if any given (valid) string is going to be somewhere in that list
  • There are two recursive rules doing the generating, so we can’t even do a linear scan through the infinite set
  • And, most algorithms to do diagonal scans are annoyingly complicated for what should be a simple test
  • Neither of those “full scan” approaches can ever give us certainty that something is a nontheorem - just that we haven’t found it yet
Well, the simplest way is to exploit an isomorphism between PQ and arithmetic. You can see this if you interpret xP yQ z as "\(x + y = z\)". Hofstadter tried to make it clear with the suggestive names P and Q. I tried to make the hint stronger, by defining PQ in terms of natural numbers. But, to do a good theoremhood check, we first need to actually write out the code for natural number arithmetic
Just for kicks, lets actually implement the Peano Axioms, or at least the ones we need.
First, let’s define equality

> instance Eq Nat where

First, m = n iff S(m) = S(n) (Peano Axiom 8) An equivalent to the above is that S(m) = S(n) iff m = n

>     (S n1) == (S n2) = n1 == n2

Equality is reflexive (Peano Axiom 1)

>     Zero == Zero     = True

Now that we’ve defined both our truth patterns, we can rest assured that every other case will turn out false

>     _ == _           = False

Next we’ll define all the arithmetic required by the Num typeclass

> instance Num Nat where

Zero is the additive identity, and this definition of addition actually looks about the same as Peano Addition If we’re adding Zero, then we can just return the other number And, S(n) + a = S(n + a). The pattern match to S(n1) + S(n2) is just a way of increasing the speed at which the recursion terminates

>   (S n1) + (S n2) = S . S $ n1 + n2
>   n + Zero = n
>   Zero + n = n

Next we’ve got multiplication, if only because it’s required by the typeclass. It’s just repeated addition, so this is pretty simple. The first rule is that anything multiplied by Zero is Zero.  The second rule is that for any n1*S(n2) = n1 + n1*n2.

>   n1 * (S n2) = n1 + n1 * n2
>   Zero * _ = Zero
>   _ * Zero = Zero

More num class fillers

>   negate = undefined
>   abs = id
>   signum _ = one
>   fromInteger 0 = Zero
>   fromInteger n = S $ fromInteger $ n - 1

So now we’ve got the tools to create a function that would test axiomhood, but it’d be horribly inefficient. It’d look something like this:
isTheorem (PQ a1 a2 s) = a1 + a2 == s
Now, that’s all well and good, but it first has to do the O(n) addition of a1 and a2, then the O(n) equality of a1 + a2 and s. Surely we can make this into one n, instead of two? Well, the way to do so is actually really easy - we just exploit the isomorphism between addition and subtraction.
First, we define our recursive rule

>   (S n1) - (S n2) = n1 - n2

Next, our base cases. Subtracting Zero from anything is just a null op, and we don’t have a clear definition in PQ of negative numbers - you can’t have -5 hyphens

>   n - Zero = n
>   Zero - _ = undefined

So from there our work is really easy - we can just recurse down once The algorithm below will take exactly (a1 + a2) iterations to check for theoremhood

> isTheorem (PQ a1 a2 s) = s - a1 - a2 == Zero

And with that we’re done - we’ve defined the PQ system, written out something to list all the theorems, discovered some novel properties of it, and leveraged those to write a quick theoremhood tester.  Not bad, eh?

Wednesday, March 12, 2014

An Important Note About LaTeX In The Browser

I'm going to be doing more and more mathy posts, and I want to be able to use LaTeX in them
If you use Chrome, you're in luck - Tex Renderer is an extension that will do exactly what you need it to.
Another solution is Tex The World

On Firefox, on the other hand, there's a Greasemonkey script that works about as well as Tex Renderer

If you don't know what LaTeX is, that's a whole different article - but a quick search brought up this

Some samples to test with:
$\forall$
$\frac{a}{b}$
$\sqrt{2\pi}$
$\int_1^{\infty} \frac{1}{x}$

Thursday, March 6, 2014

MIU Haskellized

Note: crosspost from here, I originally planned to keep that blog separate but on thinking more about it I realized that's stupid.

One of the first formal systems that Hofstadter introduces in the book is the so-called MIU system. It consists of four rules that can be used to transform a string of M's, I's, and U's:
Add a U to the end of any string ending in I. For example: MI to MIU.
Double the string after the M (that is, change Mx, to Mxx). For example: MIU to MIUIU.
Replace any III with a U. For example: MUIIIU to MUUU.
Remove any UU. For example: MUUU to MU.
  1. MU contains no I's
  2. MU contains no I's
  3. Lemma: You can only eliminate all I's from a string if the number of I's is a multiple of three
    • the only way to remove I's is to convert them to U's
    • I's can only be converted to U's in groups of 3
    • ∴ You can only eliminate all I's if the number of I's ≡ 0 (mod 3)
  4. Lemma: There is no string of multiplications by 2 and subtractions of 3
    • ∀ x. x - 3 ≡ x (mod 3)
    • 0 * 2 ≡ 0 (mod 3)
    • 1 * 2 ≡ 2 (mod 3)
    • 2 * 2 ≡ 1 (mod 3)
    • ∴ by exhaustion, there is no string of multiplications by 2 and subtractions of 3 that will generate a multiple of 3
  5. ∴ There is no combination of rule applications that will eliminate all I's from a string
  6. ∴ MU is underivable in the MIU system
Anyway, here's my code for manipulating MIU strings. Have fun!

A Comparison Of The Three Browsers Most Of You Use

So by now I've gotten a few hundred page views, and I've noticed something:
10% of you are using IE
Which has me realizing that a post talking about the advantages of different browsers was probably worth writing.  So here's a comparison of the three browsers at least 10% of you use:


Mozilla's Firefox, built from the ashes of Netscape, could not-all-that-inaccurately be called the Emacs of web browsers.  It's free, open source, and it's been called an OS.  Of course, for me that's not the killer feature; that role is filled by the amazing tab handling.  It's not that it does anything exceptionally well (except for tab groups - those are awesome) but that everyone else does something horribly wrong.
That being said, if you don't suffer from tab overload, it will be slower than Chrome, so you're probably better off moving on.  That being said, there are a few extensions for Firefox that no one's done a good Chrome port of yet

Pros:
Cons:
  • Bad at clearing memory during continued use
  • Only third best html5 support
  • Slow startup

 
Google's browser, you've probably already heard of it.  44% of you, actually, use Chrome.  It doesn't really need much introduction, so there won't be.  If you're using it, I'd recommend taking a look at this post.  I'd recommend using it unless you're super concerned about ethical software, privacy, or you simply have too many tabs.

Pros:
Cons:
  • Proprietary
  • Weak tab handling without extensions
  • Overall heavier memory usage by making each tab (and each extension!) its own process 

Don't use it.  Please switch.  It's slow, has bad html5 support, and relatively insecure.  While recent versions have definitely improved this situation, exploits are being created for it faster than any other browser just because most of the least tech savvy users are using it.  It's also proprietary, completely closed source (Chrome at least has Chromium behind it), and it's not customizable.  So yeah.  Switch, save yourself the headache.  If you can't bring yourself to switch, at least update to IE 11.  There are still people out there using IE6.  That one's been completely broken since it was first made in 2001.  Don't be one of those people.

Monday, February 17, 2014

Why Programmers Should Exercise

I was told that this article should be retitled, and I should make the target audience a bit more explicit.  So I did.

IF reader.alreadyExercises()
  THEN GOTO 5
ELSE GOTO 10

5
You can skip to the part where you get happy signals from someone reinforcing your beliefs and you share this on your Facebook/Twitter/other networking site.  You probably won't find much new in this article, though feel free to read on.


10
Now that that's dealt with, I'll get to the meat of this post, namely, why you should want to be in shape, whether or not your occupation / hobbies are physically involved.

First, I'll lay out some of the research around this:
1) Fitness (especially aerobic exercise) substantially lowers the risk of Alzheimer's, dementia, and, of course, heart disease.  You can expect serious longevity increases just from those, though there are other things it helps with (e.g. likelihood of dying from infectious disease, ability to handle chemotherapy).

2) Study after study after study suggests that exercise improves all sorts of cognitive processes.  Your code will almost definitely be improved, either in elegance or number of problems solved / time.  Just because your job doesn't directly involve physical activity doesn't mean it's not helpful.

To inject some anecdotal evidence, I used to never exercise.  I made all sorts of excuses.  "Oh, that's all well and good, but I don't have time!"  "I'm in good enough shape <runs around the block /> <hyperventilating> see? </hyperventilating>."  "I can't afford to be tired."  Rationalization is probably the most unfortunately-rooted word in the English language, and most reasons not to exercise fall into that bucket.  I've noticed a few major benefits that I was quasi-deliberately underaccounting for:

1) Time - my level of physical activity seems to have a strong causal link to clarity and speed of cognition.  I tend to get the same amount of (or even more) work done as I was previously, but in time_awake - time_exercising instead of time_awake.

2) Energy - exercising has, oddly enough, left me feeling less tired, not more.  There is a relatively established link between physical activity and awakeness/energy/whatever-you-wish-to-call-it.  Finding relevant papers is left as an exercise for the reader.

Now, to directly address some common rebuttals:
Exercise is boring! - I thought that too.  If you're finding it boring, you're doing the wrong kind of exercise.  Running on a treadmill not working for you?  Run while watching TV, or run outside so you have things to look at.  Road biking got you down?  Get a mountain bike.  Most worries about boring exercise can be solved by sitting and actually thinking about third alternatives for 5 whole minutes.  I started to get into shape with a combination of rock climbing and miming.  I'd be willing to bet neither of those were in your first two options.  THINK OF A THIRD ALTERNATIVE.

Exercise is hard! - Yes.  Yes it is.  Sorry, but downsides exist to policies in complex systems.  I tend to get a positive feeling of accomplishment from doing difficult things, but your mileage may vary.  The benefits are still probably going to outweigh the cost of some willpower though.


Other things worth noting:
There's already some pretty good material on optimal exercise out there, if you're concerned with getting the most bang for your metaphorical buck.

As with any health-related-lifestyle-changes, your mileage may vary.  That's not an excuse to give up after one day.  If the "this is hard" part goes for months, something's probably up, but don't reach that conclusion much earlier.

Another important thing to pay attention to is diet.  Not dieting, diet.  Exercise without eating healthy is like a high IQ without any conscientiousness.  It's worth something, but you won't get much done.  Finding a diet that works for you and sticking to it probably deserves its own post, but I'll try to summarize a bit here:
Paleo and its variants seem to have very mixed results, though they match up pretty effectively with my understanding of human metabolism.  Eating a diet more similar in contents to what you'd find in the ancestral environment seems like a good heuristic, if not a perfect one. 

Conclusion:
Changing habits around physical activity is probably one of the simplest lifestyle changes you can make with really established benefits.  You'll think more clearly, write better code, feel healthier, and almost definitely live longer.  Yes, it's hard.  Do it anyway.  You won't regret it.

Wednesday, February 5, 2014

A Few Essential Vim Tweaks for Working in Haskell

One of the things I found most annoying about Haskell when I started working with it was the lack of a real IDE.  I searched around for a while and found nothing all that good (except maybe FP Haskell Center, but I like being able to work offline).  At first I worked with Sublime Text 2, for which there are several very useful packages available through the package manager.  And that was fine for a while.  But there were still a few things missing.  It didn't have good command line integration, and SublimeREPL just wasn't cutting it.  Around the time that this was becoming most annoying, I had also gotten to an introduction to Vim in a Unix course I was taking.  This got me investigating different editors again, this time focusing mainly on Vim and Emacs (though others were considered), and I ended up settling on Vim (though I'm considering trying to switch to Emacs again).  For some reason the modal interface seems more natural, though your mileage may vary.

Anyway, after installing Vim, I wasn't quite done - I still needed to add a few packages to make editing convenient.

Pathogen makes plugin management a whole lot easier.  Install it before anything else here to preempt headaches.

2) A Good Color Scheme
While it isn't specific to Haskell, you should care about your color schemes.  I plan to write a full post on this at some point, but for today I'm just going to assume you agree that pretty colors are important.  Anyway, there are lots of good ones to choose from.  As you might be able to tell from the colors on the blog, I'm a fan of Ethan Schoonover's Solarized, though there are plenty of others worth looking at.  A good color scheme will make it much easier to read your code at a glance while greatly reducing eye strain.

This package consists of a few plugins aimed at making Haskell development easier - GHC support, syntax highlighting, the works.  It doesn't do everything, but it sure does a lot.  You could start working in Haskell with just this and a color scheme.

Syntastic is another one that's not Haskell specific, but adds enough general functionality that it's definitely worth getting - it'll add some type checking capability to vim before you hit the compile button.  Speaking of...

I threw those lines into my .vimrc for one very simple reason:
GHC gives very useful information when you compile
Going to a different tab in iTerm and typing out ghc (filename) is annoying.
So I just nmapped F5-F7 to ghc, ghci, and ghc --make respectively

File management.  'Nuff said.  I personally prefer to use Vifm for most things, but it's really a difference of preference.  From what I understand, NERDTree is a bit more powerful, but I also find it a bit less elegant.

Better support for quick commenting - not much more to say really.  A useful feature, really strangely lacking from vim.  Much faster than 0i--.  It makes debugging a good bit easier (you can quickly comment out different pattern matches and recompile to test where the bug is, things like that).

YankRing improves copying and pasting in a lot of ways -
It allows you to copy and paste across buffers.  It essentially emulates Emacs' "kill ring" while adding a few other nice features.  


Anyway, those are the main tweaks that I use.  I've heard many times that I should use SHIM, but I've never really seen the need for it.  This may turn out to be isomorphic to the blub paradox, but until I get around to testing it I won't know.

Wednesday, January 29, 2014

My Functional Programming Story

The most honest thing I can say about my dabbling with functional programming is that it was all spawned out of boredom.  Towards the end of last year, I was getting very rapidly bored of the computer science curriculum at my previous school, which I had been following for the preceding two years.  Java is (compared to many) an inherently boring language, and progress in both classes I had taken in it was slow.  I decided that I had had enough of that, and started to search for something more interesting.  A close friend recommended I work through MIT's Structure and Interpretation of Computer Programs, aka SICP.  I started it, and quickly became obsessed.  You see, SICP is a book written for learning Scheme, a LISP dialect and a functional programming language.

The difference was profound.  I was used to specifying algorithms as a sequence of instructions.  I would try to generalize, as that instinct had been pushed thoroughly into my brain earlier on through some means I don't quite know.  But there was always something missing.  Object orientation did lots, but getting globs of code to fit together the right way was still arduous, and I always had to be careful that I didn't mess up some fact of the global state in setting it up.

What's more, there was recursion.  I was an absolute novice in the world of recursion.  Having only seen recursion in a world without first class functions or tail call optimization, it seemed to me to simply be a memory-expensive way to solve problems that probably would be better solved by a well placed loop.  Functional programming was a breath of fresh air.

So I started working in Scheme, and I enjoyed it.  But, in the process of learning Scheme, I found myself reading a lot of blog/forum posts talking about functional programming and this weird other language called "Haskell".  At first I dismissed it.  It reminded me too much of working with Java (static typing seemed arduous and horrible, and it had *gasps* SYNTAX).  When I started to reach a more stale part of SICP (dealing with mutable state), I found myself looking into tutorials for it and thought "eh, might as well give it a try".  After a bit of trouble at the start, I actually found myself enjoying Haskell even more than I had enjoyed Scheme.  Typeclasses and the Hindley-Milner system made static typing less painful, and the difference in amount of testing required pushed it to being a net positive.

So I played around with Learn You a Haskell and a few other sources for practice problems, and before I knew it I was solving some relatively simple problems in Haskell.  But that wasn't all.  I needed a project, something to work on for more than a few afternoons.  I was starting to get interested in compilers, but knew I was nowhere near ready for writing one of those, so I decided an interpreter was the next best thing to make.  And, whaddaya know, writing a Scheme interpreter turned out to be a common way of transitioning out of the beginner stage of Haskell development.  So that was fun.

So I guess this is the part where I compare my experience with Scheme and Haskell as forays into the functional.  I'm certainly glad I started with Scheme.  Sure, it's not as "pure" but the lack of syntax allowed me to think only about the program logic, which was a big enough transition from the kind of reasoning I was used to doing while programming.  I’m not sure I’d have taken to Haskell anywhere near as readily at first.  In addition to that, Scheme has the advantage of being eagerly evaluated.  While I might prefer lazy evaluation now, it would have been yet another thing to understand before I could effectively reason about what was going on.  So I would definitely recommend learning Scheme or some other Lisp first.  That being said, if you want to get good at programming, here’s the most important part: make sure it never stops being fun.

Lastly, I feel this concept must be addressed in any discussion about learning Haskell: Monads.  I don't really understand what all the hullabaloo is about.  They're honestly not that difficult.  That moment when you really *get* monads is a fun one, and really changes the way you look at computing from then on, but it doesn't seem like they really deserve the altogether nasty reputation they've gained.  I remember, when I was but a schemer and not a haskeller as well, thinking that Haskell was actively against being useful.  Why did I think this?  Because everyone I had ever heard writing about monads said they were silly constructs that just made everything more difficult.
Simon Peyton Jones often likes to say that the biggest mistake they made in developing monadic I/O was to use the word “monad”.  Taking terms from category theory leaves lots of people scared that they’ll have to understand difficult math to do anything useful in Haskell.  This isn’t true, and don’t let anyone trick you into thinking it is.  Understanding category theory will enrich your understanding of Haskell’s type system, but it certainly isn’t necessary!

Another thing worth noting is that Haskell is what really forced me to understand package managers and command line tools.  The lack of any serious IDE or similar batteries-included setup had me stuck wandering around trying to find different ways to fix everything as it broke.  I think I went through three different installs of the Haskell Platform.  If you're on OS X, install it with Homebrew.  Seriously.  When you're trying to fix whatever cabal-install broke this time, you'll thank me.  It also forced me into using general purpose text editors like Sublime (my first editor) and later Vim.  If it weren't for working in a language without an IDE, I might never have switched.  Boy, was I missing out.  Learning a general-purpose editor makes it so much easier to just take a language and go, whereas if you felt too bound to your IDE you might spend the first several days trying to find one that you considered satisfactory.

This is a story in progress, as I haven't stopped coding and I don't see myself abandoning functional languages anytime soon.  My most recent endeavor is to start playing around with making a (relatively rudimentary) computer algebra system.  Expect updates on that as I work more on it (and maybe even a bit of literate code!)

Friday, January 24, 2014

The 4 Best Languages To Learn For An Experienced Programmer

In a previous article I wrote about which programming languages to learn first.  Those were the "simple" ones.  Now for the... let's say, advanced, languages.
Important caveat:
These are on my advanced languages post for a reason.  Any IDE's they have tend to be on the weak side, so you should be comfortable working in a text editor.  Vim and Emacs are the classics, or one of those silly graphical editors if you really must (though their support will generally be weaker).  The previous post was not meant for the faint of heart.  That applies triply to this one.

Haskell
Those of you who've talked to me in the past 6 months knew this one was coming.  This wonderful language is known for three things:
1) Elegance - Lazy evaluation and a few bits of sugar make code ridiculously simple looking
Quicksort has never been simpler
The Sieve of Eratosthenes (that operates on infinite lists) in 3 lines
2) The ridiculously rich (though also absurdly rigid) type system.  Typeclasses provide a safe way to do overloading.  The Hindley-Milner type inference system allows you to have the full assurance that static typing grants you without bogging your code down in excessive type declarations.  That being said, while it's possibly the best part of Haskell, it's also often the most infuriating.
3) Being difficult to learn.  Now, I'm not convinced this reputation is deserved.  But, given that monads appear to be the most tutorialized subject in programming, your mileage may vary.  Monads essentially function to encapsulate different bits of programming where the sequencing is important in a lazily evaluated language.  Once it clicks it seems absurdly elegant, but it could take a bit of time.

How to install:
On Debian: sudo apt-get install haskell-platform
On Arch: pacman -S ghc cabal-install haddock happy alex
On Mac OS X: First, install homebrew - if you didn't already have it, you definitely should.  I'm going to write another post about it later.  Then it's as simple as "brew install haskell-platform"
Anything else: Go to this page

IDE/Editor support:
This page should have all the info you need.

Recommended tutorials:
I'd explain my recommendations at length, but someone on Stack Overflow already did it for me

Racket:
Now, I know what you're thinking: "You recommended Racket last time!"  But I only talked about it in an introductory context.  Now, I'm recommending something different:  Read the last few chapters of SICP.  Work through The Seasoned Schemer.  But, whatever you do, learn macros.  When you do, you'll understand all the fuss over Lisp's parentheses.  Their biggest benefit is that their use essentially means that Lisp has no syntax.  And that makes metaprogramming as easy as normal programming in many other languages!  This is ridiculously important.  Macros allowed the Racket developers to graft a static type system on top of the base language, and added async to Javascript.  The first one I have some vague sense of how it was done.  The second one, though, strikes me as black magic.  All the more reason to learn!

How to install:
I'd recommend working from here if you want to use the racket IDE.  But, if you want to use Vim or Emacs there's support for those too.  I'd recommend searching your favorite package manager for racket.
Mac OS X: brew install plt-racket
Debian-based OS':

sudo add-apt-repository ppa:plt/racket
sudo apt-get update
sudo apt-get install racket


Racklog:
The best thing about Racket is that it comes with a bunch of other languages built on the same syntax and editor using macros.  Racklog is a great example (as is Typed Racket, and Lazy Racket).  If that doesn't compel you to learn more about macros I don't know what will.  That being said, the reason to learn Racklog as well is to get used to yet another programming paradigm: logic programming.  I would recommend prolog, but given that it isn't used anywhere, there's no real reason to learn it beyond just getting used to the paradigm, and Racklog will be more than adequate for that.

Logic programming feels even more like magic than functional programming.  You don't specify computations at all.  You specify a few characteristics of the answer you're looking for, and out pops the answer!  I'd swear it was magic if I hadn't spent time looking at the source code for Racklog.

Recommended Learning Resources:
I linked to the official Racklog tutorial above, though you can also learn much of it (with slightly different syntax) in The Reasoned Schemer


APL:
Now, don't get me wrong, I don't expect you to ever use APL for anything.  You probably won't even use too many ideas from it elsewhere.  So why do I say you should learn APL?
Simple.
It's fun.
More specifically, I recommend learning J, a modern implementation of APL that thankfully only uses the ASCII character set.
Now, if you've never heard of APL, I guess it needs some introduction.   APL (A Programming Language) was originally designed by Kenneth Iverson as a system of mathematical notation for array manipulation (the name APL obviously had yet to be dreamt up).  When he was working with IBM in the 60's, he realized that it was also a useful structure for describing program operations.  And thus APL was born.
Array programming is... interesting to say the least.  You can write just about any (purely numerical) computation in one line.  But, APL has also been called the world's first and only write only programming language, and probably rightly so.  Reading old programs is often damn hard, as the syntax provides little to no redundant information.  Write it once, hope it works.  That being said, I'm pretty sure J is turing complete, so it'll still do.

Monday, January 20, 2014

The Best 3 Languages for Learning to Code

It seems like everyone's writing articles about different silly little ways to learn programming.  "Learn to code in 24 hours!", "Become a Software Developer in 30 Minutes", and of course the so-called "Hour of Code".  Now, I may have my gripes about these programs, but they're really great for their target audience, and that is NOT PEOPLE WHO WANT A CAREER IN SOFTWARE.  Maybe they want a basic understanding.  They want to be able to listen to developers talk and understand it at a deeper level than they understand magic.  And that's fine.  That's not this post's target audience.  If you want to learn to be good at coding, these are the languages you should learn, in order:

Javascript
Reasoning:
Along with some really basic HTML/CSS anyway.  Why Javascript, you ask?  Because web programming is simple.  Or, more accurately, because web programming has been optimized to let you do a few simple, introductory things really easily.  When I was learning Javascript, I was building some simple interactivity into a (admittedly sparse / primitive) website in no time.  It's probably easier to get started with Javascript than just about any other language.

Recommended tutorials:
Codeacademy's Javascript Track alongside its Web Track
Also, a good html tutorial if you don't want to use Codeacademy can be found here

Topic Checklist:
Basic I/O and control flow, making coding feel not-scary

Python
Reasoning:
After getting your feet wet with Javascript, I'd recommend learning in Python.  The reason I suggest switching so soon (rather than getting more thoroughly acquainted with Javascript) is that there are simply more (and overall better quality) resources for learning Python.  You have O'Reilly's Think Python, Codeacademy's Python Track, and MIT's OCW Course and their course on EDX (which there are apparently multiple instances of), and many, many more.  Working in Python will help you get used to thinking in the more structured way that is required to code effectively, and will start to teach you some good habits in a relatively natural way.

In addition to that, significant whitespace is a great thing.  Sure, it can create funny situations, but for the most part what it does is enforce clean code.  And trust me, you want to teach novices to write clean code.  I've seen abominations produced by those who weren't instructed in how-to-write-code-that-others-can-read, and I'd prefer not to have any personal responsibility in that.  Granted, it's still possible to write unreadable code in Python, but it takes way more effort.

Recommended tutorials:
I'd recommend all of the tutorials I mentioned above.  They're all really good, just go with whichever makes the most sense for your learning style.

Topic Checklist:
More control flow, 
Loops, 
More involved IO,
Basic Object-Oriented coding,
Thinking in code

Scheme
Reasoning:
Here's the one I might take some heat for.  That being said, whenever you read about what some of the developer-"celebrities" (e.g. most of those interviewed in Peter Seibel's Coders At Work), almost always you find that they worked with Scheme (or some other Lisp dialect) early on in their coding-education, and did a lot of work with it and other functional languages from then on.  The nice thing about functional programs is that they're much easier to reason about.  Some of the tools feel way more powerful (functions as data being the main one about functional programming as a whole, alongside macros in Lisp specifically), but in my mind the chief benefit of relatively pure functional languages is what they *don't* have much of.  Working with mutable state is much more of a hassle than in the previous few languages.  The emphasis on linked lists instead of arrays.  Now, why would I say that working with so much less is helpful?  The reason is simple.  Good code is easily maintainable code is easy to reason about code.  And being restricted to the purely functional tools makes it way easier to figure out exactly what's going on with your program / where it's going wrong.

One important caveat though is that I have a very specific Scheme implementation in mind when I make this recommendation: Racket.  Think of it as a batteries-included version of Scheme.  Most of the tutorials for Scheme, unlike the languages above, don't talk much about the specific way to run it on your computer.  The reason for this is that when you're working in Scheme (or other functional languages) you're not supposed to be thinking too much about the low level details of what the machine is doing.  Instead, you think of the basic algorithmic efficiency, and reason about the program in a more abstract way.  This emphasis on abstraction allows you to create lots of easily reusable code, that can be thrown at all sorts of different problems.

Recommended tutorials:
There's also about as many really good resources for Scheme as there are for Python.  My personal favorites:
The old classic, still probably the best around, but not for the faint of heart: The Structure and Interpretation of Computer Programs
Slightly lighter but still on the tough side: How to Design Programs
Another great resource, for those who found the first two too dense: Realm of Racket
And, on a similar level with Realm of Racket: The Little Schemer

Topic Checklist:
Thinking recursively,
Functions-as-data /  higher order functions,
Data structures,
Big-O efficiency,
Higher order everything,
String processing,
Making reusable code,
Some basic algorithms (sorting algorithms being the classic case)

Conclusion:
There are lots of languages worth learning (or at least getting familiar with), but I'd say these are easily the best three for getting started programming.  That being said, I'm curious, for any programmers reading this, what were your first three languages?  What order did you learn them in and why?

Saturday, January 18, 2014

10 Chrome Extensions to Change the Way You Browse

Browser extensions.  They add a great layer of customizability to an otherwise bland browsing experience, but they come with a cost, namely, memory and cpu time.  I myself am guilty of overextending, and both Chrome and Firefox make it very easy to do this, so I often have to run through my extensions page and disable them all then reenable.  Here are the ones that always make the cut.

First, blockers that'll remove things you didn't want to be there in the first place:

1) AdBlock - this one's a must.  Anyone who uses browser extensions knows to get this one.  Now, there's a bit of confusion over whether to get this or AdBlock Plus.  I personally prefer AdBlock because
a) Lighter memory footprint - it used anywhere from 10-100 mb less memory when I checked Chrome's task manager
b) Better customizability - AdBlock makes it way easier to add your own filters, which is useful if you ever find anything it didn't catch

2) Disconnect - probably the best of the different tracker-blocking addons.  It runs in the background, nabbing as many trackers as it can and stopping them from collecting data about you.  Now, from a privacy standpoint this may not be ideal, but from a speed standpoint it definitely is.  That's a lot of scripts that your browser no longer has to run and load, and a lot of cookies that don't get stored.  And, speaking of not running scripts...

3) ScriptBlock - Sure, it's not quite as nice as Firefox's NoScript, but it does essentially all of the same things, and having a good script blocker is a must for any good hacker.  But why would you want to block scripts anyway?  Well, the biggest reason is speed.  My browser loads pages without scripts up to 90% faster.  Another good reason is quality control.  There is a strong inverse correlation between number of different domains you have to enable scripts for and the quality of the content of the site.  If they require me to enable scripts from more than 5 different sites just to read an article, chances are I don't actually want to read that article.  If nothing else, you also build up some funny bits of knowledge by having to explicitly allow any domains for scripts.  Some sites seem to show up everywhere.  Learning why is sometimes a fun puzzle (I'm looking at you, Amazon!).

4) Web Of Trust - I have yet to find a more extensive website-rating service.  Web Of Trust takes reports form users all around the world about different websites, and collects them in a total rating, as well as some specific ones depending on the site (vendor reliability, for example).  It'll alert you before you accidentally end up in the sketchy parts of the internet (most download sites, for example).

5) StayFocusd - This addon has probably done more for my productivity than all the others combined.  It lets you set time limits for different websites in different timeframes (e.g. "only 10 minutes on Facebook from 9 -19:00 a day").  There are various ways to configure it so it's annoying to change settings, and attempts to guilt you back into work whenever you try to add time on websites you've listed as distracting.  You can also go as far as to completely block certain websites in different times, if even 5 minutes is  too many.

6)  FooTab - Compared to the others here, this one's simple, but still incredibly useful.  FooTab prevents all tabs that aren't in focus from loading for about 20 seconds after launch, so the first page you want to load can start up that much faster.


Now, the things that add to the experience of web browsing rather than just subtracting:

7) OneTab - this has become my tab manager of choice for Chrome -  it puts a button in your navigation bar that will close all the tabs in your current window and store the url's for later recovery.  Think of it as a slightly less powerful (but also lighter on resources) version of Firefox's tab groups

8) Vimium - adds vim-style shortcuts to Chrome.  If you are or want to become a user of vim I can't recommend this addon highly enough.  It adds standard hjkl scrolling, J/K tab navigation, H/L for the back and forward buttons, and a few other really useful ones.  Once you get good at using it, you'll wonder how you ever browsed without it.

9) FastestFox for Chrome - here be automations that you didn't realize you wanted.  It will automatically load the next page of an article / blog you're scrolling through when you get near the bottom of the page, will instantly look up definitions when you highlight a word, instantly reports how popular a link is, improves google results, and much more.

10) ZenMate - makes it incredibly easy to work with a proxy.  It will run all your traffic through any of their locations (US, England, Germany, Switzerland, and Hong Kong) and encrypt it, increasing anonymity and allowing you to access content that's normally blocked in your country. They're in an early stage so offering unlimited bandwidth for anyone who makes an account now, though that may change down the line.  It's not as secure as TOR, but it's one hell of a lot faster, so unless you really need that extra security I'd use this.
DISCLAIMER: I do not support or advocate any way that you use this addon to break the law.  If you're using it to do something illegal and get caught, that's your problem not mine.

Anyway, that's my top 10.  What are yours?

Friday, January 17, 2014

Hack Your Sleep Habits with f.lux

There is a lot of literature on the subject of color temperature and its effects on the human circadian rhythm and melatonin production.  Here's the summary:
"Many are familiar with the "rods and cones" that provide our visual capabilities, but it was only about 15 years ago that retinal ganglion cells containing melanopsin, which are sensitive to a narrow band of blue light in the 460-480nm range, were discovered, and their unique effect on sleep was investigated.
The experimental research suggests that an average person reading on a tablet for a couple hours before bed may find that their sleep is delayed by about an hour."

Another important thing to note is that human circadian rhythms evolved in a world where artificial lighting wasn't a thing except occasionally for a fire, which was a warm light.  Sunset and fire-light were signals that it would soon be time to sleep.  Daylight (which your screen emulates by default) is a cue for staying awake.  Your body does a whole awful lot to halt melatonin production when blasted with something it thinks is sunlight.

So yes, that ominous blue glow of the midnight hacker is actually as negative as it looks.  But, thankfully, there is a way to solve it.  Just get f.lux.  F.lux is a free, cross-platform utility that figures out when sunset is by checking your location and warms the color temperature.  For the first few weeks it'll seem remarkably orange, but after a little while you'll get used to it.  I can't think of a single tweak I recommend more highly to anyone who likes to use their computer late into the night.

Note 1: if you think you don't need to worry about getting enough sleep, think again.  Literally every study disagrees.  Type "sleep deprivation cognitive" or "sleep deprivation performance" into google scholar and you'll find study after study saying that you need to sleep if you want to have the best possible performance at whatever you do.

Note 2: if you have an iOS device, you can't get f.lux without jailbreaking.  That being said, I'll probably post a guide to doing so relatively soon, though it's not as if others haven't already done that.