Port changed() function to master

Port the `changed()` forward from #530 to `master`.

Attempting to add a test but I'm hitting an obstacle here. Anyone mind taking a look at this?

```python
$ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig PATH=$PATH:/usr/local/opt/pkg-config/bin:/usr/local/Cellar/libffi/3.0.13/lib/pkgconfig tox -e py26-django14
GLOB sdist-make: /Users/jdixon/Projects/graphite-web/setup.py
py26-django14 recreate: /Users/jdixon/Projects/graphite-web/.tox/py26-django14
py26-django14 installdeps: cairocffi, django-tagging, pytz, mock, git+git://github.com/graphite-project/whisper.git#egg=whisper, git+git://github.com/graphite-project/ceres.git#egg=ceres, Django<1.5, django-discover-runner, pyparsing
py26-django14 inst: /Users/jdixon/Projects/graphite-web/.tox/dist/graphite-web-0.10.0-alpha.zip
py26-django14 runtests: PYTHONHASHSEED='1567628275'
py26-django14 runtests: commands[0] | django-admin.py test
Could not import graphite.local_settings, using defaults!
/Users/jdixon/Projects/graphite-web/webapp/graphite/settings.py:225: UserWarning: SECRET_KEY is set to an unsafe default. This should be set in local_settings.py for better security
  warn('SECRET_KEY is set to an unsafe default. This should be set in local_settings.py for better security')
Creating test database for alias 'default'...
...........F................................
======================================================================
FAIL: test_changed (tests.test_functions.FunctionsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jdixon/Projects/graphite-web/webapp/tests/test_functions.py", line 355, in test_changed
    self.assertEqual(result, expected)
AssertionError: Lists differ: [TimeSeries(name=changed(colle... != [TimeSeries(name=changed(colle...

First differing element 0:
TimeSeries(name=changed(collectd.test-db1.load.value), start=0, end=1, step=1)
TimeSeries(name=changed(collectd.test-db1.load.value), start=0, end=1, step=1)

  [TimeSeries(name=changed(collectd.test-db1.load.value), start=0, end=1, step=1)]

----------------------------------------------------------------------
Ran 44 tests in 1.184s

FAILED (failures=1)
Destroying test database for alias 'default'...
ERROR: InvocationError: '/Users/jdixon/Projects/graphite-web/.tox/py26-django14/bin/django-admin.py test'
______________________________________________________ summary ______________________________________________________
ERROR:   py26-django14: commands failed
```