Random array creation takes distribution

Refactor the client-side array-creation methods to take a `Distribution` object instead of the `shape`, `dist`, `grid_shape` arguments directly.  A user can create a `Distribution` object many ways, including with those arguments.  This allows all array-creation routines to create all of our supported distribution types.

I modified all `random.py` functions to take a `Distribution` as a required argument, whereas before, some of them could be called without `shape`/`dist`/`grid_shape` parameters to return a single scalar.  This didn't seem to be an important use-case (one could just use the appropriate `numpy` function for that), so I omitted it.