diff --git a/.gitignore b/.gitignore
index b6659a698d711f6b6af858c2308ce3a2f6821277..43d92ee10bec5ebd233964e5af74e6d5d431fa50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,6 +61,7 @@ instance/
 
 # Scrapy stuff:
 .scrapy
+docs/
 
 # Sphinx documentation
 docs/_build/
diff --git a/README.md b/README.md
index 22d5de5c8d7e85ef801afdaf33d70f66c2ba5771..d891ca742832c82346793f0fb91166e6677f87bb 100644
--- a/README.md
+++ b/README.md
@@ -9,21 +9,57 @@
 [![PyPI](https://img.shields.io/pypi/wheel/firanka.svg)]()
 [![license](https://img.shields.io/github/license/mashape/apistatus.svg)]()
 
-Calculations on continuous, domain-being-a-single-interval, real domain
-functions.
+firanka is a Python library to perform calculations on particular kinds of
+functions. These functions have a domain, which is a single continuous subset
+of the real number line. These functions can have any values.
 
-Functions of index: float -> any;
+firanka allows you do define two classes of such functions or series.
 
+First are the _DiscreteSeries_. _DiscreteSeries_ further divide the function
+domain into slices (left-closed, right-open) that have constant values.
+Manipulating _DiscreteSeries_ and performing calculations on them is cheap.
 
+Then you have _FunctionSeries_. These are simply defined by user-supplied
+Python callable.
 
-You can:
+Best part is, you can join series together (given a joining operator),
+slice them and so on.
 
-* join two series with a single operation
-* use a function on each value
+
+# Usage
+## Ranges
+
+```python
+from firanka.series import Range
+```
+
+Range would have been better called an **interval**. It is a continuous subset
+of the real number line.
+
+You can create Ranges as follows:
+
+```python
+Range(-5, 5, True, False) == Range('<-5;5)')
+```
+
+First boolean argument signifies whether the interval is left-closed,
+and second whether it is right-closed.
+
+Range's are immutable and hashable. They can be sliced:
 
 ```python
-from firanka.series import DiscreteSeries, FunctionBasedSeries
+Range('<-5;5>')[0:] == Range('<0;5>')
+```
 
-ds = DiscreteSeries(list of tuple(index, value), '<-20;4)')
+You can check whether a range contains a point
+
+```python
+5 not in Range('<-1;5)')
+```
+
+Or you can check for strict inclusion
+
+```python
+Range('<-1;1>') in Range('<-2;2>')
+```
 
-```
\ No newline at end of file
diff --git a/firanka/series/__init__.py b/firanka/series/__init__.py
index ea3c4b2092c52f9f4f2de02c2f306fdc26f74c12..fb30d506acd788a3a4732b98ef5fd2da58ee8fb3 100644
--- a/firanka/series/__init__.py
+++ b/firanka/series/__init__.py
@@ -5,7 +5,7 @@ import logging
 
 from .exceptions import NotInDomainError, FirankaError
 from .range import Range, REAL_SET
-from .series import DiscreteSeries, FunctionBasedSeries, ModuloSeries, Series
+from .series import DiscreteSeries, FunctionSeries, ModuloSeries, Series
 
 
 __all__ = [
@@ -13,7 +13,7 @@ __all__ = [
     'FirankaError',
     'NotInDomainError',
     'Range',
-    'FunctionBasedSeries',
+    'FunctionSeries',
     'DiscreteSeries',
     'ModuloSeries',
     'Series',
diff --git a/firanka/series/range.py b/firanka/series/range.py
index 1dc63237a22a231deedc8bac7dcf8bb9499be539..a5e45697951116cf71186d71cd5267970866af8f 100644
--- a/firanka/series/range.py
+++ b/firanka/series/range.py
@@ -32,7 +32,9 @@ class Range(object):
             if isinstance(rs, type(self)):
                 args = rs.start, rs.stop, rs.left_inc, rs.right_inc
             elif isinstance(rs, slice):
-                args = rs.start, rs.stop, True, True
+                start = rs.start if rs.start is not None else float('-inf')
+                stop = rs.stop if rs.stop is not None else float('+inf')
+                args = start, stop, not math.isinf(start), not math.isinf(stop)
             else:
                 if rs[0] not in '<(': raise ValueError('Must start with ( or <')
                 if rs[-1] not in '>)': raise ValueError('Must end with ) or >')
@@ -84,6 +86,12 @@ class Range(object):
     def __repr__(self):
         return 'Range(%s, %s, %s, %s)' % (repr(self.start), repr(self.stop), repr(self.left_inc), repr(self.right_inc))
 
+    def __getitem__(self, item):
+        if not isinstance(item, slice):
+            raise ValueError('must be a slice')
+
+        return self.intersection(Range(item))
+
     def __str__(self):
         return '%s%s;%s%s' % (
             '<' if self.left_inc else '(',
diff --git a/firanka/series/series.py b/firanka/series/series.py
index 31f15d2b56a7d3969129e5e1772eeae67bbbd6e9..b4a18e7b668c51791e07dc5cf1559c8e3a303005 100644
--- a/firanka/series/series.py
+++ b/firanka/series/series.py
@@ -230,12 +230,12 @@ class DiscreteSeries(Series):
         return DiscreteSeries(nd, self.domain)
 
 
-class FunctionBasedSeries(Series):
+class FunctionSeries(Series):
     """
     Series with values defined by a function
     """
     def __init__(self, fun, domain):
-        super(FunctionBasedSeries, self).__init__(domain)
+        super(FunctionSeries, self).__init__(domain)
         self.fun = fun
 
     def _get_for(self, item):
diff --git a/tests/test_series/test_range.py b/tests/test_series/test_range.py
index 068b0b846948ca31cfd0ec8f9aa88c8c7ab63d39..4476b083c6260967955f36e4db92af193146600d 100644
--- a/tests/test_series/test_range.py
+++ b/tests/test_series/test_range.py
@@ -17,6 +17,9 @@ class TestRange(unittest.TestCase):
             self.assertEqual(Range(a).intersection(b), Range(val))
             self.assertEqual(Range(b).intersection(a), Range(val))
 
+    def test_slicing(self):
+        self.assertTrue(Range('<-5;5>')[0:] == Range('<0;5>'))
+
     def test_isempty(self):
         self.assertTrue(Range(-1,-1,False,False).is_empty())
         self.assertFalse(Range(-1,-1,False,True).is_empty())
diff --git a/tests/test_series/test_series.py b/tests/test_series/test_series.py
index c7451f87dc30218cb728d0874e661db370513a78..f7ea5b1dc7b19f1f48792ee8f8a58a7ae65c794e 100644
--- a/tests/test_series/test_series.py
+++ b/tests/test_series/test_series.py
@@ -2,7 +2,7 @@
 from __future__ import print_function, absolute_import, division
 import six
 import unittest
-from firanka.series import DiscreteSeries, FunctionBasedSeries, Range, ModuloSeries, NotInDomainError
+from firanka.series import DiscreteSeries, FunctionSeries, Range, ModuloSeries, NotInDomainError
 
 
 class TestDiscreteSeries(unittest.TestCase):
@@ -60,7 +60,7 @@ class TestDiscreteSeries(unittest.TestCase):
 
     def test_eval2(self):
         sa = DiscreteSeries([[0, 0], [1, 1], [2, 2]])
-        sb = FunctionBasedSeries(lambda x: x, '<0;2>')
+        sb = FunctionSeries(lambda x: x, '<0;2>')
 
         sc = sa.join_discrete(sb, lambda a, b: a+b)
         self.assertEqual(sc.eval_points([0,1,2]), [0,2,4])
@@ -73,8 +73,8 @@ class TestDiscreteSeries(unittest.TestCase):
         self.assertEquals(sa.data, [(0,1),(1,2),(2,3)])
 
     def test_eval3(self):
-        sa = FunctionBasedSeries(lambda x: x**2, '<-10;10)')
-        sb = FunctionBasedSeries(lambda x: x, '<0;2)')
+        sa = FunctionSeries(lambda x: x**2, '<-10;10)')
+        sb = FunctionSeries(lambda x: x, '<0;2)')
 
         sc = sa.join(sb, lambda a, b: a*b)
 
@@ -86,20 +86,20 @@ class TestDiscreteSeries(unittest.TestCase):
 
     def test_discretize(self):
         PTS = [0,1,2,3,4,5]
-        sa = FunctionBasedSeries(lambda x: x**2, '<-10;10)').discretize(PTS, '(-1;6)')
+        sa = FunctionSeries(lambda x: x**2, '<-10;10)').discretize(PTS, '(-1;6)')
         self.assertIsInstance(sa, DiscreteSeries)
         self.assertEqual(sa.data, [(i, i**2) for i in PTS])
 
-        sa = FunctionBasedSeries(lambda x: x**2, '<-10;10)').discretize(PTS)
+        sa = FunctionSeries(lambda x: x**2, '<-10;10)').discretize(PTS)
         self.assertIsInstance(sa, DiscreteSeries)
         self.assertEqual(sa.data, [(i, i**2) for i in PTS])
 
-        empty = FunctionBasedSeries(lambda x: x**2, '<-10;10)').discretize([])
+        empty = FunctionSeries(lambda x: x**2, '<-10;10)').discretize([])
         self.assertTrue(empty.domain.is_empty())
 
-class TestFunctionBasedSeries(unittest.TestCase):
+class TestFunctionSeries(unittest.TestCase):
     def test_slice(self):
-        series = FunctionBasedSeries(lambda x: x, '<0;2>')
+        series = FunctionSeries(lambda x: x, '<0;2>')
         sp = series[0.5:1.5]
 
         self.assertEqual(sp[0.5], 0.5)
@@ -111,7 +111,7 @@ class TestFunctionBasedSeries(unittest.TestCase):
 
     def test_apply(self):
         PTS = [-1,-2,-3,1,2,3]
-        series = FunctionBasedSeries(lambda x: x, '<-5;5>').apply(lambda x: x*2)
+        series = FunctionSeries(lambda x: x, '<-5;5>').apply(lambda x: x*2)
 
         self.assertEqual(series.eval_points(PTS), [x*2 for x in PTS])
 
@@ -125,8 +125,8 @@ class TestModuloSeries(unittest.TestCase):
         self.assertEquals(series[-1], 3)
 
     def test_comp_discrete(self):
-        ser1 = ModuloSeries(FunctionBasedSeries(lambda x: x**2, '<0;3)'))
-        ser2 = FunctionBasedSeries(lambda x: x, '<0;3)')
+        ser1 = ModuloSeries(FunctionSeries(lambda x: x**2, '<0;3)'))
+        ser2 = FunctionSeries(lambda x: x, '<0;3)')
 
         ser3 = ser1.join(ser2, lambda x, y: x*y)