Make dict use ==? instead of trying to reimplement.
Special-case implementation of ==? for arrays and heaps.

To be used when `==` is not defined for all the elements. This is more
efficient than recursing once for `==`, failing, then recursing again
(in C) for `===`. More importantly, it gives better results when `==` is
defined for some but not all of the elements.

To prevent the prelude's general case rule from shadowing these
defintions, though, we need to add special-case checks for these
types to prelude.pure. Since we only have a small number of collections
in the stdlib, this seems tolerable.

If we're going to end up wanting special-case implementations of ==? for
more and more collections though, it might become less tolerable. In
that case, we may want to have a convention where, say, a module
declares the result of ``tuple2 x y`` as belonging to the type
``egalable`` (a better name would be nice) if the module knows how to
provide an implementation of ==? for that x and y. Then the prelude's
general case ==? would just apply when ``tuple2 x y`` is not egalable.

(I call it a "convention", but one might arguably characterize it
as "magic".)

The dynamic extensibility of Pure's types would make this work
correctly. Until module X was loaded, its special-case rules for ==?
would be ignored, and the general rule in the prelude would apply
(if operands of the appropriate type were even constructable before
module X was loaded). After module X was loaded, it would take over
for the operands it wants.

But I'm not sure how much of a performance hit there would be: all those
function calls to check operand types every time ==? is applied. *Plus*
building then discarding all those tuple2s.

But let's cross that bridge if and when we have to. With the scheme presented
here, we do have more operand type-checking, but we at least avoid
building lots of temporary tuple2s.
Make optimized cat behave the same as reverse-based.
Optimize list _::list.

Perhaps there's some subtle reason I'm missing why the list needed to
be accumulated and reversed, but on the face of it, traversing
then returning the original suffices.
Add catmap,listmap for collections.
Move catstream and *_onto behind-the-scenes.

The programmer shouldn't have to deliberate about whether to use map or
map_onto, and so on. Let's make them compile-time optimizations instead,
on the same model as Pure's compile time optimizations for ``xs!!(i..j)``.

The patterns have to be visible to the compiler. So these will be
optimized:

    map f xs + base;
    cat [map f xs, more, stillmore];

but these won't:

    ys + base when ys = map fs xs end;
    plus (map f xs) base when plus = (+) end;

Also, we make the optimizations only available when --enable=list-opt.

Changes implemented in this commit:

* Move reverse_onto into __std__; it's not intended to be called directly
  outside a few core stdlibs. Instead users should just use
  ``reverse xs + base``, it will automatically be optimized. The
  optimization handles the detection of string bases properly.

* Move map_onto and revmap_onto into __std__; these also are not
  intended to be called directly, but will automatically be invoked
  as optimizations for ``map f xs + base`` and so on.

* Don't expose `zip*_onto`, but also invoke these as compile-time
  optimizations.

* Eliminate catmap_onto. The semantics of this was especially hard to
  remember. Was it equivalent to ``catmap f xs + base``, so that
  `cat` is not applied to `base`? Or to: ``cat (map_onto f base xs)``,
  so that `cat` *is* applied to base? In fact the reverse-based and
  skip-ahead implementations I had committed earlier diverged in that
  respect.

* Move catstream into __std__. This will automatically be invoked
  when the user says ``stream xs + ...`` or ``cat [stream xs, ...]``
  or ``cat(map stream xs + ...)`` and so on.

  To get this optimization, operands have to be literally wrapped with
  ``stream`` in the source, not just be streams. But the semantics
  should be the same even if the slower, existing handling of
  stream concatenation in the definitions of `+` and `cat` is used.

The implementations of some of these optimizations are interleaved.

For the macro optimizations, as far as I can see there
is no feasible way to avoid declaring ``stream`` a nonfix. But note again
that we only do this when --enable=list-opt.

Note also that with regard to the stream handling, we make some
assumptions about the semantics of list and stream operations. For
example, we assume that (+) is associative with respect to those
arguments and (+[]) is a right identity. These are of course true for
actual lists and streams. But we further assume them to be true for
expressions like ``stream xs`` and ``map stream xs``, even when
those expressions don't reduce further.

So for example, we count: ``cat(map stream xs) + cat ys`` as equivalent
to ``cat(map stream xs + ys)``, for any ``xs``. We also count
``(stream xs + stream ys) + zs`` as equivalent to
``stream xs + (stream ys + zs)``.

We *don't* assume that (+) is associative or (+[]) is an identity for
arbitrary arguments.

The assumptions made here seem reasonable ones, especially given the
elegant way they enable us to move these optimizations behind the
scenes. But we should carefully review them, and keep them in mind
in case they introduce problems elsewhere.

(Fewer assumptions would be needed if (+) were infixr rather than
infixl, or if we could implement the optimizations making (+) a
--quoteargs macro. I tried the latter, but in order to recurse on the
operands while keeping a (+) applied to them, yet suppressing its
macro definitions, the only way I can see is to use a const
proxy for (+), and consts can't also be infix operators. So the result
is that when one says ``:show my_code`` in the interpreter, everything
would always look like:

    (+) x y

instead of:

    x + y

I don't know if that implementation strategy would in all other respects
be as good or better than the one pursued here. I'm just reporting what
persuaded me not to pursue it further.)
Rename __std__::notfound to __std__::missing.
Fix run-tests when there are multiple prelude failures.
Add test094, test095 for list catstream/*_onto optimizations.