diff --git a/Sound/Tidal/Dirt.hs b/Sound/Tidal/Dirt.hs
--- a/Sound/Tidal/Dirt.hs
+++ b/Sound/Tidal/Dirt.hs
@@ -32,7 +32,9 @@
                             F "resonance" (Just 0),
                             F "accellerate" (Just 0),
                             F "shape" (Just 0),
-                            I "kriole" (Just 0)
+                            I "kriole" (Just 0),
+                            F "gain" (Just 0),
+                            I "cutgroup" (Just 0)
                           ],
                  timestamp = True
                 }
@@ -98,6 +100,8 @@
 resonance    = makeF dirt "resonance"
 accellerate  = makeF dirt "accellerate"
 shape        = makeF dirt "shape"
+gain         = makeF dirt "gain"
+cutgroup     = makeI dirt "cutgroup"
 
 ksymbol      = makeF kriole "ksymbol"
 kpitch       = makeF kriole "kpitch"
diff --git a/Sound/Tidal/Pattern.hs b/Sound/Tidal/Pattern.hs
--- a/Sound/Tidal/Pattern.hs
+++ b/Sound/Tidal/Pattern.hs
@@ -16,14 +16,24 @@
 import Sound.Tidal.Time
 import Sound.Tidal.Utils
 
+-- | The pattern datatype, a function from a time @Arc@ to @Event@
+-- values. For discrete patterns, this returns the events which are
+-- active during that time. For continuous patterns, events with
+-- values for the midpoint of the given @Arc@ is returned.
+
 data Pattern a = Pattern {arc :: Arc -> [Event a]}
 
+-- | @show (p :: Pattern)@ returns a text string representing the
+-- event values active during the first cycle of the given pattern.
+
 instance (Show a) => Show (Pattern a) where
   show p@(Pattern _) = show $ arc p (0, 1)
-  
+
 instance Functor Pattern where
   fmap f (Pattern a) = Pattern $ fmap (fmap (mapSnd f)) a
 
+-- | @pure a@ returns a pattern with an event with value @a@, which
+-- has a duration of one cycle, and repeats every cycle.
 instance Applicative Pattern where
   pure x = Pattern $ \(s, e) -> map 
                                 (\t -> ((t%1, (t+1)%1), x)) 
@@ -37,10 +47,13 @@
                  (xs (s,e))
                 )
 
+-- | @mempty@ is a synonym for @silence@.
+-- | @mappend@ is a synonym for @overlay@.
 instance Monoid (Pattern a) where
     mempty = silence
     mappend x y = Pattern $ \a -> (arc x a) ++ (arc y a)
 
+
 instance Monad Pattern where
   return = pure
   p >>= f = 
@@ -53,50 +66,79 @@
                    (arc p a)
              )
 
+-- | @atom@ is a synonym for @pure@.
 atom :: a -> Pattern a
 atom = pure
 
+-- | @silence@ returns a pattern with no events.
 silence :: Pattern a
 silence = Pattern $ const []
 
+-- | @mapQueryArc f p@ returns a new @Pattern@ with function @f@
+-- applied to the @Arc@ values passed to the original @Pattern@ @p@.
 mapQueryArc :: (Arc -> Arc) -> Pattern a -> Pattern a
 mapQueryArc f p = Pattern $ \a -> arc p (f a)
 
+-- | @mapQueryTime f p@ returns a new @Pattern@ with function @f@
+-- applied to the both the start and end @Time@ of the @Arc@ passed to
+-- @Pattern@ @p@.
 mapQueryTime :: (Time -> Time) -> Pattern a -> Pattern a
 mapQueryTime = mapQueryArc . mapArc
 
+-- | @mapResultArc f p@ returns a new @Pattern@ with function @f@
+-- applied to the @Arc@ values in the events returned from the
+-- original @Pattern@ @p@.
 mapResultArc :: (Arc -> Arc) -> Pattern a -> Pattern a
 mapResultArc f p = Pattern $ \a -> mapFsts f $ arc p a
 
+-- | @mapResultTime f p@ returns a new @Pattern@ with function @f@
+-- applied to the both the start and end @Time@ of the @Arc@ values in
+-- the events returned from the original @Pattern@ @p@.
 mapResultTime :: (Time -> Time) -> Pattern a -> Pattern a
 mapResultTime = mapResultArc . mapArc
 
+-- | @overlay@ combines two @Pattern@s into a new pattern, so that
+-- their events are combined over time.
 overlay :: Pattern a -> Pattern a -> Pattern a
 overlay p p' = Pattern $ \a -> (arc p a) ++ (arc p' a)
-
 (>+<) = overlay
 
+-- | @stack@ combines a list of @Pattern@s into a new pattern, so that
+-- their events are combined over time.
 stack :: [Pattern a] -> Pattern a
 stack ps = foldr overlay silence ps
 
-cat :: [Pattern a] -> Pattern a
-cat ps = density (fromIntegral $ length ps) $ slowcat ps
+-- | @append@ combines two patterns @Pattern@s into a new pattern, so
+-- that the events of the second pattern are appended to those of the
+-- first pattern, within a single cycle
 
 append :: Pattern a -> Pattern a -> Pattern a
 append a b = cat [a,b]
 
+-- | @append'@ does the same as @append@, but over two cycles, so that
+-- the cycles alternate between the two patterns.
 append' :: Pattern a -> Pattern a -> Pattern a
 append' a b  = slow 2 $ cat [a,b]
 
-slowcat' ps = Pattern $ \a -> concatMap f (arcCycles a)
+-- | @cat@ returns a new pattern which interlaces the cycles of the
+-- given patterns, within a single cycle. It's the equivalent of
+-- @append@, but with a list of patterns.
+cat :: [Pattern a] -> Pattern a
+cat ps = density (fromIntegral $ length ps) $ slowcat ps
+
+{-slowcat' ps = Pattern $ \a -> concatMap f (arcCycles a)
   where l = length ps
         f (s,e) = arc p (s,e)
           where p = ps !! n
-                n = (floor s) `mod` l
+                n = (floor s) `mod` l-}
 
 -- Concatenates so that the first loop of each pattern is played in
 -- turn, second loop of each pattern, and so on..
 
+-- | @slowcat@ does the same as @cat@, but maintaining the duration of
+-- the original patterns. It is the equivalent of @append'@, but with
+-- a list of patterns.
+
 slowcat :: [Pattern a] -> Pattern a
 slowcat [] = silence
 slowcat ps = Pattern $ \a -> concatMap f (arcCycles a)
@@ -108,76 +150,143 @@
                 offset = (fromIntegral $ r - ((r - n) `div` l)) :: Time
                 (s', e') = (s-offset, e-offset)
 
+-- | @listToPat@ turns the given list of values to a Pattern, which
+-- cycles through the list.
 listToPat :: [a] -> Pattern a
 listToPat = cat . map atom
 
-run n = listToPat [0 .. n-1]
-
+-- | @maybeListToPat@ is similar to @listToPat@, but allows values to
+-- be optional using the @Maybe@ type, so that @Nothing@ results in
+-- gaps in the pattern.
 maybeListToPat :: [Maybe a] -> Pattern a
 maybeListToPat = cat . map f
   where f Nothing = silence
         f (Just x) = atom x
 
+-- | @run@ @n@ returns a pattern representing a cycle of numbers from @0@ to @n-1@.
+run n = listToPat [0 .. n-1]
+
+-- | @density@ returns the given pattern with density increased by the
+-- given @Time@ factor. Therefore @density 2 p@ will return a pattern
+-- that is twice as fast, and @density (1%3) p@ will return one three
+-- times as slow.
 density :: Time -> Pattern a -> Pattern a
 density 0 p = p
 density 1 p = p
 density r p = mapResultTime (/ r) $ mapQueryTime (* r) p
 
+-- | @slow@ does the opposite of @density@, i.e. @slow 2 p@ will
+-- return a pattern that is half the speed.
 slow :: Time -> Pattern a -> Pattern a
 slow 0 = id
 slow t = density (1/t) 
 
+
+-- | The @<~@ operator shift (or rotate) a pattern to the left (or
+-- counter-clockwise) by the given @Time@ value. For example 
+-- @(1%16) <~ p@ will return a pattern with all the events moved 
+-- one 16th of a cycle to the left.
 (<~) :: Time -> Pattern a -> Pattern a
 (<~) t p = filterOffsets $ mapResultTime (+ t) $ mapQueryTime (subtract t) p
 
+-- | The @~>@ operator does the same as @~>@ but shifts events to the
+-- right (or clockwise) rather than to the left.
 (~>) :: Time -> Pattern a -> Pattern a
 (~>) = (<~) . (0-)
 
+-- | @rev p@ returns @p@ with the event positions in each cycle
+-- reversed (or mirrored).
 rev :: Pattern a -> Pattern a
 rev p = Pattern $ \a -> concatMap 
                         (\a' -> mapFsts mirrorArc $ 
                                 (arc p (mirrorArc a')))
                         (arcCycles a)
 
+-- | @palindrome p@ applies @rev@ to @p@ every other cycle, so that
+-- the pattern alternates between forwards and backwards.
+palindrome p = append' p (rev p)
+
+-- | @when test f p@ applies the function @f@ to @p@, but in a way
+-- which only affects cycles where the @test@ function applied to the
+-- cycle number returns @True@.
 when :: (Int -> Bool) -> (Pattern a -> Pattern a) ->  Pattern a -> Pattern a
 when test f p = Pattern $ \a -> concatMap apply (arcCycles a)
   where apply a | test (floor $ fst a) = (arc $ f p) a
                 | otherwise = (arc p) a
 
+-- | @every n f p@ applies the function @f@ to @p@, but only affects
+-- every @n@ cycles.
 every :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 every 0 f p = p
 every n f p = when ((== 0) . (`mod` n)) f p
 
-palindrome :: Pattern a -> Pattern a
-palindrome p = slowcat [p, rev p]
-
+-- | @sig f@ takes a function from time to values, and turns it into a
+-- @Pattern@.
 sig :: (Time -> a) -> Pattern a
 sig f = Pattern f'
   where f' (s,e) | s > e = []
                  | otherwise = [((s,e), f s)]
 
+-- | @sinewave@ returns a @Pattern@ of continuous @Double@ values following a
+-- sinewave with frequency of one cycle, and amplitude from -1 to 1.
 sinewave :: Pattern Double
 sinewave = sig $ \t -> sin $ pi * 2 * (fromRational t)
+-- | @sine@ is a synonym for @sinewave.
 sine = sinewave
-ratsine = fmap toRational sine
+-- | @sinerat@ is equivalent to @sinewave@ for @Rational@ values,
+-- suitable for use as @Time@ offsets.
+sinerat = fmap toRational sine
+ratsine = sinerat
 
+-- | @sinewave1@ is equivalent to @sinewave@, but with amplitude from 0 to 1.
 sinewave1 :: Pattern Double
 sinewave1 = fmap ((/ 2) . (+ 1)) sinewave
+
+-- | @sine1@ is a synonym for @sinewave1@.
 sine1 = sinewave1
-ratsine1 = fmap toRational sine1
 
-sinePhase1 :: Double -> Pattern Double
-sinePhase1 offset = (+ offset) <$> sinewave1
+-- | @sinerat1@ is equivalent to @sinerat@, but with amplitude from 0 to 1.
+sinerat1 = fmap toRational sine1
 
-triwave1 :: Pattern Double
-triwave1 = sig $ \t -> mod' (fromRational t) 1
-tri1 = triwave1
-rattri1 = fmap toRational tri1
+-- | @sineAmp1 d@ returns @sinewave1@ with its amplitude offset by @d@.
+sineAmp1 :: Double -> Pattern Double
+sineAmp1 offset = (+ offset) <$> sinewave1
 
+-- | @sawwave@ is the equivalent of @sinewave@ for sawtooth waves.
+sawwave :: Pattern Double
+sawwave = ((subtract 1) . (* 2)) <$> sawwave1
+
+-- | @saw@ is a synonym for @sawwave@.
+saw = sawwave
+
+-- | @sawrat@ is the same as @sawwave@ but returns @Rational@ values
+-- suitable for use as @Time@ offsets.
+sawrat = fmap toRational saw
+
+sawwave1 :: Pattern Double
+sawwave1 = sig $ \t -> mod' (fromRational t) 1
+saw1 = sawwave1
+sawrat1 = fmap toRational saw1
+
+-- | @triwave@ is the equivalent of @sinewave@ for triangular waves.
 triwave :: Pattern Double
 triwave = ((subtract 1) . (* 2)) <$> triwave1
+
+-- | @tri@ is a synonym for @triwave@.
 tri = triwave
-rattri = fmap toRational tri
+
+-- | @trirat@ is the same as @triwave@ but returns @Rational@ values
+-- suitable for use as @Time@ offsets.
+trirat = fmap toRational tri
+
+triwave1 :: Pattern Double
+triwave1 = append sawwave1 (rev sawwave1)
+
+tri1 = triwave1
+trirat1 = fmap toRational tri1
+
+
+-- todo - triangular waves again
 
 squarewave1 :: Pattern Double
 squarewave1 = sig $ 
diff --git a/Sound/Tidal/Strategies.hs b/Sound/Tidal/Strategies.hs
--- a/Sound/Tidal/Strategies.hs
+++ b/Sound/Tidal/Strategies.hs
@@ -91,7 +91,7 @@
 
 spin16 step p = stack $ map (\n -> ((toRational n)/16) <~ p |+| pan (pure $ n)) [0,step .. 15]
 
-triwave4 = ((*4) <$> triwave1)
+sawwave4 = ((*4) <$> sawwave1)
 sinewave4 = ((*4) <$> sinewave1)
 rand4 = ((*4) <$> rand)
 
@@ -105,3 +105,4 @@
   where flt = f . cyclePos . fst . fst
 
 inside n f p = density n $ f (slow n p)
+
diff --git a/Sound/Tidal/Stream.hs b/Sound/Tidal/Stream.hs
--- a/Sound/Tidal/Stream.hs
+++ b/Sound/Tidal/Stream.hs
@@ -157,7 +157,7 @@
 makeS = make string
 makeF = make float
 
-makeI = make int32
+makeI = make (int32 . fromIntegral)
 
 param :: OscShape -> String -> Param
 param shape n = head $ filter (\x -> name x == n) (params shape)
diff --git a/Sound/Tidal/Time.hs b/Sound/Tidal/Time.hs
--- a/Sound/Tidal/Time.hs
+++ b/Sound/Tidal/Time.hs
@@ -1,41 +1,64 @@
 module Sound.Tidal.Time where
 
+-- | Time is represented by a rational number. Each natural number
+-- represents both the start of the next rhythmic cycle, and the end
+-- of the previous one. Rational numbers are used so that subdivisions
+-- of each cycle can be accurately represented.
 type Time = Rational
+
+-- | @(s,e) :: Arc@ represents a time interval with a start and end value.
+-- @ { t : s <= t && t < e } @
 type Arc = (Time, Time)
+
+-- | An Event is a value that occurs during the given @Arc@
 type Event a = (Arc, a)
 
+-- | The starting point of the current cycle. A cycle occurs from each
+-- natural number to the next, so this is equivalent to @floor@.
 sam :: Time -> Time
 sam = fromIntegral . floor
 
+-- | The end point of the current cycle (and starting point of the next cycle)
 nextSam :: Time -> Time
 nextSam = (1+) . sam
 
+
+-- | The position of a time value relative to the start of its cycle.
 cyclePos :: Time -> Time
 cyclePos t = t - sam t
 
+-- | @isIn a t@ is @True@ iff @t@ is inside 
+-- the arc represented by @a@.
 isIn :: Arc -> Time -> Bool
 isIn (s,e) t = t >= s && t < e
 
--- chop arc into arcs within unit cycles
+-- | Splits the given @Arc@ into a list of @Arc@s, at cycle boundaries.
 arcCycles :: Arc -> [Arc]
 arcCycles (s,e) | s >= e = []
                 | sam s == sam e = [(s,e)]
                 | otherwise = (s, nextSam s) : (arcCycles (nextSam s, e))
 
+
+-- | @subArc i j@ is the arc that is the intersection of @i@ and @j@.
 subArc :: Arc -> Arc -> Maybe Arc
 subArc (s, e) (s',e') | s'' < e'' = Just (s'', e'')
                       | otherwise = Nothing
   where s'' = max s s'
         e'' = min e e'
 
+-- | Map the given function over both the start and end @Time@ values
+-- of the given @Arc@.
 mapArc :: (Time -> Time) -> Arc -> Arc
 mapArc f (s,e) = (f s, f e)
 
+-- | Returns the `mirror image' of an @Arc@, used by @Sound.Tidal.Pattern.rev@.
 mirrorArc :: Arc -> Arc
 mirrorArc (s, e) = (sam s + (nextSam s - e), nextSam s - (s - sam s))
 
+-- | The start time of the given @Event@
 eventStart :: Event a -> Time
 eventStart = fst . fst
 
+-- | The midpoint of an @Arc@
 midPoint :: Arc -> Time
 midPoint (s,e) = s + ((e - s) / 2)
diff --git a/doc/tidal.md b/doc/tidal.md
--- a/doc/tidal.md
+++ b/doc/tidal.md
@@ -1,5 +1,7 @@
-% Tidal -- Domain specific language for live coding of pattern 
+<img src="https://raw2.github.com/yaxu/Tidal/master/doc/tidal.png" />
 
+# Tidal: Domain specific language for live coding of pattern 
+
 Homepage and mailing list: <http://yaxu.org/tidal/>
 
 Tidal is a language for live coding pattern, embedded in the Haskell
@@ -11,104 +13,14 @@
 
 # Installation
 
-Tidal is developed under Linux, and although some have got it to work
-under Macs, the process hasn't been fully documented, and Dirt
-synthesiser has not yet been ported to Windows. Feel free to ask
-questions and share problems and success stories on the mailing list.
-
-## Installing Dirt
-
-Tidal does not include a synthesiser, but instead communicates with an
-external synthesiser using the Open Sound Control protocol. It has
-been developed for use with a particular software sampler called
-"dirt". You'll need to run it with "jack audio". Here's an example of
-the commands needed to compile it under a debian-derived linux
-distribution (including ubuntu and mint):
-
-~~~~
-    sudo apt-get install build-essential libsndfile1-dev libsamplerate0-dev \
-                         liblo-dev libjack-jackd2-dev qjackctl jackd git
-    git clone https://github.com/yaxu/Dirt.git
-    cd Dirt
-    make clean; make
-~~~~
-
-Then you'll have to start jack, using the 'qjackctl' app under Linux,
-or otherwise from the commandline:
-
-~~~~
-    jackd -d alsa &
-~~~~
-
-(On MacOS X, you would do this instead: jackd -d coreaudio & )
-
-If that doesn't work, you might well have something called
-"pulseaudio" in control of your sound. In that case, this should work:
-
-~~~~
-    /usr/bin/pasuspender -- jackd -d alsa &
-~~~~
-
-And finally you should be able to start dirt with this:
-
-~~~~
-    ./dirt &
-~~~~
-
-If you have problems with jack, try enabling realtime audio, and
-adjusting the settings by installing and using the "qjackctl"
-software. Some more info is here: <https://help.ubuntu.com/community/HowToJACKConfiguration>
-
-
-## Tidal
-
-Tidal is embedded in the Haskell language, so you'll have to install
-the haskell interpreter and some libraries, including tidal
-itself. Under debian, you'd install haskell like this:
-
-~~~~
-   sudo apt-get install ghc6 cabal-install
-~~~~
-
-Or otherwise you could grab it from <http://www.haskell.org/platform/>
-
-Once Haskell is installed, you can install tidal like this:
-
-~~~~
-   cabal update
-   cabal install tidal
-~~~~
-
-## Emacs
-
-Currently about the only interface to Tidal is the emacs
-editor. Debian users can install emacs, along with its haskell
-front-end, this way:
-
-~~~~
-    sudo apt-get install emacs24 haskell-mode
-~~~~
-
-To install the emacs interface to tidal, you'll need to edit a
-configuration file in your home folder called `.emacs`. If it doesn't
-exist, create it. Then, add the following, replacing
-`~/projects/tidal` with the location of the `tidal.el` file.
-
-~~~~
-    (add-to-list 'load-path "~/projects/tidal")
-    (require 'tidal)
-~~~~
-
-If tidal.el did not come with this document, you can grab it here: <https://raw.github.com/yaxu/Tidal/master/tidal.el>
-
-## Testing, testing...
+Linux installation:
+<https://github.com/yaxu/Tidal/blob/master/doc/install-linux.md>
 
-Now start emacs, and open a new file called something like
-"helloworld.tidal". Once the file is opened, you still have to start
-tidal, you do that by typing `Ctrl-C` then `Ctrl-S`.
+Mac OS X installation:
+<https://github.com/yaxu/Tidal/blob/master/doc/install-osx.md>
 
-All being well you should now be able to start making some sounds,
-lets start with some simple sequences.
+Feel free to ask questions and share problems and success stories on
+the mailing list.
 
 # Sequences
 
@@ -219,6 +131,22 @@
 d1 $ sound "[bd sn sn*3]/2 [bd sn*3 bd*4]/3"
 ~~~~
 
+# Peace and quiet with silence and hush
+
+An empty pattern is defined as `silence`, so if you want to 'switch
+off' a pattern, you can just set it to that:
+
+~~~~ {#mycode .haskell}
+d1 silence
+~~~~
+
+If you want to set all the connections (from `d1` to `d9`) to silence
+at once, there's a single-word shortcut for that:
+
+~~~~ {#mycode .haskell}
+hush
+~~~~
+
 # Beats per second
 
 You can change the beats per second (bps) like this:
@@ -370,12 +298,18 @@
 
 # Pattern transformers
 
+In the following, functions are shown with their Haskell type and a
+short description of how they work.
+
 ## brak
 
-~~~~
-brak <pattern>
+~~~~ {#mycode .haskell}
+brak :: Pattern a -> Pattern a
 ~~~~
 
+(The above means that `brak` is a function from patterns of any type,
+to a pattern of the same type.)
+
 Make a pattern sound a bit like a breakbeat
 
 Example:
@@ -384,18 +318,36 @@
 d1 $ sound (brak "bd sn kurt")
 ~~~~
 
-## Beat rotation
+## Reversal
 
+~~~~ {#mycode .haskell}
+rev :: Pattern a -> Pattern a
 ~~~~
-<number> <~ <pattern>
+
+Reverse a pattern
+
+Examples:
+
+~~~~ {#mycode .haskell}
+d1 $ every 3 (rev) $ sound (density 2 "bd sn kurt")
 ~~~~
 
-or
+## Beat rotation
 
+~~~~ {#mycode .haskell}
+(<~) :: Time -> Pattern a -> Pattern a
 ~~~~
-<number> ~> <pattern>
+
+or
+
+~~~~ {#mycode .haskell}
+(~>) :: Time -> Pattern a -> Pattern a
 ~~~~
 
+(The above means that `<~` and `~>` are functions that are given a
+time value and a pattern of any type, and returns a pattern of the
+same type.)
+
 Rotate a loop either to the left or the right.
 
 Example:
@@ -404,70 +356,260 @@
 d1 $ every 4 (0.25 <~) $ sound (density 2 "bd sn kurt")
 ~~~~
 
-## Reversal
+## Increase or decrease density
 
+~~~~ {#mycode .haskell}
+density :: Time -> Pattern a -> Pattern a
 ~~~~
-rev <pattern>
+
+or
+
+~~~~ {#mycode .haskell}
+slow :: Time -> Pattern a -> Pattern a
 ~~~~
 
-Reverse a pattern
+Speed up or slow down a pattern.
 
-Examples:
+Example:
 
 ~~~~ {#mycode .haskell}
-d1 $ every 3 (rev) $ sound (density 2 "bd sn kurt")
+d1 $ sound (density 2 "bd sn kurt")
+   |+| slow 3 (vowel "a e o")
 ~~~~
 
-## Increase/decrease density
+## Every nth repetition, do this
 
+~~~~ {#mycode .haskell}
+every :: Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
 ~~~~
-density <number> <pattern>
+
+(The above means `every` is a function that is given an integer number, a
+function which transforms a pattern, and an actual pattern, and
+returns a pattern of the same type.)
+
+Transform the given pattern using the given function, but only every
+given number of repetitions.
+
+Example:
+
+~~~~ {#mycode .haskell}
+d1 $ sound (every 3 (density 2) "bd sn kurt")
 ~~~~
 
-or
+~~~~ {#mycode .haskell}
+whenmod :: Int -> Int -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+~~~~
 
+(The above has a similar form to `every`, but requires an additional
+number.)
+
+Similar to `every`, but applies the function to the pattern, when the
+remainder of the current loop number divided by the first parameter,
+is less than the second parameter.
+
+For example the following makes every other block of four loops twice
+as dense:
+
+~~~~ {#mycode .haskell}
+d1 $ whenmod 8 4 (density 2) (sound "bd sn kurt")
 ~~~~
-slow <number> <pattern>
+
+# Interlace
+
+~~~~ {#mycode .haskell}
+interlace :: OscPattern -> OscPattern -> OscPattern
 ~~~~
 
-Speed up or slow down a pattern.
+(A function that takes two OscPatterns, and blends them together into
+a new OscPattern. An OscPattern is basically a pattern of messages to
+a synthesiser.)
 
+Shifts between the two given patterns, using distortion.
+
 Example:
 
 ~~~~ {#mycode .haskell}
-d1 $ sound (density 2 "bd sn kurt")
-   |+| slow 3 (vowel "a e o")
+d1 $ interlace (sound  "bd sn kurt") (every 3 rev $ sound  "bd sn/2")
 ~~~~
 
-## Every nth repetition, do this
+# Spread
 
+~~~~ {#mycode .haskell}
+spread :: (a -> t -> Pattern b) -> [a] -> t -> Pattern b
 ~~~~
-every <number> <function> <pattern>
+
+(The above is difficult to describe, if you don't understand Haskell,
+just read the description and examples..)
+
+The `spread` function allows you to take a pattern transformation
+which takes a parameter, such as `slow`, and provide several
+parameters which are switched between. In other words it 'spreads' a
+function across several values.
+
+Taking a simple high hat loop as an example:
+
+~~~~ {#mycode .haskell}
+d1 $ sound "ho ho/2 ho/3 hc"
 ~~~~
 
-Applies <function> to <pattern>, but only every <number> repetitions.
+We can slow it down by different amounts, such as by a half:
 
-Example:
+~~~~ {#mycode .haskell}
+  d1 $ slow 2 $ sound "ho ho/2 ho/3 hc"
+~~~~
 
+Or by four thirds (i.e. speeding it up by a third; `4%3` means four over
+three):
+
 ~~~~ {#mycode .haskell}
-d1 $ sound (every 3 (density 2) "bd sn kurt")
+  d1 $ slow (4%3) $ sound "ho ho/2 ho/3 hc"
 ~~~~
 
-# Interlace
+But if we use `spread`, we can make a pattern which alternates between
+the two speeds:
 
+~~~~ {#mycode .haskell}
+d1 $ spread slow [2,4%3] $ sound "ho ho/2 ho/3 hc"
 ~~~~
-interlace <pattern> <pattern>
+
+There's a version of this function, `spread'` (pronounced "spread prime"), which takes a *pattern* of parameters, instead of a list:
+
+~~~~ {#mycode .haskell}
+d1 $ spread' slow "2 4%3" $ sound "ho ho/2 ho/3 hc"
 ~~~~
 
-Shifts between two patterns, using distortion.
+This is quite a messy area of Tidal - due to a slight difference of
+implementation this sounds completely different! One advantage of
+using `spread'` though is that you can provide polyphonic parameters, e.g.:
 
-Example:
+~~~~ {#mycode .haskell}
+d1 $ spread' slow "[2 4%3, 3]" $ sound "ho ho/2 ho/3 hc"
+~~~~
 
+# Striate
+
 ~~~~ {#mycode .haskell}
-d1 $ interlace (sound  "bd sn kurt") (every 3 rev $ sound  "bd sn/2")
+striate :: Int -> OscPattern -> OscPattern
 ~~~~
 
-Plus more to be discovered!
+Striate is a kind of granulator, for example:
+
+~~~~ {#mycode .haskell}
+d1 $ striate 3 $ sound "ho ho/2 ho/3 hc"
+~~~~
+
+This plays the loop the given number of times, but triggering
+progressive portions of each sample. So in this case it plays the loop
+three times, the first time playing the first third of each sample,
+then the second time playing the second third of each sample, etc..
+With the highhat samples in the above example it sounds a bit like
+reverb, but it isn't really.
+
+You can also use striate with very long samples, to cut it into short
+chunks and pattern those chunks. This is where things get towards
+granular synthesis. The following cuts a sample into 128 parts, plays
+it over 8 cycles and manipulates those parts by reversing and rotating
+the loops.
+
+~~~~ {#mycode .haskell}
+d1 $  slow 8 $ striate 128 $ sound "bev"
+~~~~
+
+The `striate'` function is a variant of `striate` with an extra
+parameter, which specifies the length of each part. The `striate'`
+function still scans across the sample over a single cycle, but if
+each bit is longer, it creates a sort of stuttering effect. For
+example the following will cut the bev sample into 32 parts, but each
+will be 1/16th of a sample long:
+
+~~~~ {#mycode .haskell}
+d1 $ slow 32 $ striate' 32 (1/16) $ sound "bev"
+~~~~
+
+# Smash
+
+~~~~ {#mycode .haskell}
+smash :: Int -> [Time] -> OscPattern -> OscPattern
+~~~~
+
+Smash is a combination of `spread` and `striate` - it cuts the samples
+into the given number of bits, and then cuts between playing the loop
+at different speeds according to the values in the list.
+
+So this:
+
+~~~~ {#mycode .haskell}
+  d1 $ smash 3 [2,3,4] $ sound "ho ho/2 ho/3 hc"
+~~~~
+
+Is a bit like this:
+
+~~~~ {#mycode .haskell}
+  d1 $ spread (slow) [2,3,4] $ striate 3 $ sound "ho ho/2 ho/3 hc"
+~~~~
+
+This is quite dancehall:
+
+~~~~ {#mycode .haskell}
+d1 $ (spread' slow "1%4 2 1 3" $ spread (striate) [2,3,4,1] $ sound
+"sn/2 sid/3 cp sid/4")
+  |+| speed "[1 2 1 1]/2"
+~~~~
+
+# Combining patterns
+
+Because Tidal patterns are defined as something called an "applicative
+functor", it's easy to combine them. For example, if you have two
+patterns of numbers, you can combine the patterns by, for example,
+multiplying the numbers inside them together, like this:
+
+~~~~ {#mycode .haskell}
+d1 $ (brak (sound "bd sn/2 bd sn"))
+   |+| pan ((*) <$> sinewave1 <*> (slow 8 $ "0 0.25 0.75"))
+~~~~
+
+In the above, the `sinewave1` and the `(slow 8 $ "0 0.25 0.75")`
+pattern are multiplied together. Using the <$> and the <*> in this way
+turns the `*` operator, which normally works with two numbers, into a
+function that instead works on two *patterns* of numbers.
+
+Here's another example of this technique:
+
+~~~~ {#mycode .haskell}
+d1 $ sound (pick <$> "kurt mouth can*3 sn" <*> slow 7 "0 1 2 3 4")
+~~~~
+
+The `pick` function normally just takes the name of a set of samples
+(such as `kurt`), and a number, and returns a sample with that
+number. Again, using <$> and <*> turns `pick` into a function that
+operates on patterns, rather than simple values. In practice, this
+means you can pattern sample numbers separately from sample
+sets. Because the sample numbers have been slowed down in the above,
+an interesting texture results.
+
+By the way, "0 1 2 3 4" in the above could be replaced with the
+pattern generator `run 5`.
+
+# Juxtapositions
+
+The `jux` function creates strange stereo effects, by applying a
+function to a pattern, but only in the right-hand channel. For
+example, the following reverses the pattern on the righthand side:
+
+~~~~ {#mycode .haskell}
+d1 $ slow 32 $ jux (rev) $ striate' 32 (1/16) $ sound "bev"
+~~~~
+
+When passing pattern transforms to functions like `jux` and `every`,
+it's possible to chain multiple transforms together with `.`, for
+example this both reverses and halves the playback speed of the
+pattern in the righthand channel:
+
+~~~~ {#mycode .haskell}
+d1 $ slow 32 $ jux ((|+| speed "0.5") . rev) $ striate' 32 (1/16) $ sound "bev"
+~~~~
+
+# Plus more to be discovered!
 
 You can find a stream of minimal cycles written in Tidal in the
 following twitter feed:
diff --git a/doc/tidal.pdf b/doc/tidal.pdf
Binary files a/doc/tidal.pdf and b/doc/tidal.pdf differ
diff --git a/tidal.cabal b/tidal.cabal
--- a/tidal.cabal
+++ b/tidal.cabal
@@ -1,5 +1,5 @@
 name:                tidal
-version:             0.2.9
+version:             0.2.10
 synopsis:            Pattern language for improvised music
 -- description:         
 homepage:            http://yaxu.org/tidal/
diff --git a/tidal.el b/tidal.el
--- a/tidal.el
+++ b/tidal.el
@@ -55,7 +55,7 @@
      tidal-interpreter-arguments)
     (tidal-see-output))
   (tidal-send-string ":set prompt \"\"")
-  (tidal-send-string ":module Sound.Tidal.Context")
+  (tidal-send-string ":load Sound.Tidal.Context")
   (tidal-send-string "d1 <- dirtstream \"d1\"")
   (tidal-send-string "d2 <- dirtstream \"d2\"")
   (tidal-send-string "d3 <- dirtstream \"d3\"")
