(#22574) Add defaults and other features to the lookup function.

The lookup function can be called in one of these ways:

    lookup(name)
    lookup(name, type)
    lookup(name, type, default)
    lookup(options_hash)
    lookup(name, options_hash)

The function may optionally be called with a code block / lambda with
the following signatures:

    lookup(...) |$result| { ... }
    lookup(...) |$name, $result| { ... }
    lookup(...) |$name, $result, $default| { ... }

The longer signatures are useful when the block needs to raise an error
(it can report the name), or
if it needs to know if the given default value was selected.
The `$name` is the last name that was looked up.
The `$result` is the looked up value (or the default value if not
found). 
The `$default` is the given default value (`undef` if not given).

The block, if present, is called with the result from the lookup. The
value produced by the block is also what is produced by the `lookup`
function.
When a block is used, it is the users responsibility to call `error` if
the result does not meet additional criteria, or if an undef value is
not acceptable. If a value
is not found, and a default has been specified, the default value is
given to the block.

The content of the options hash is:

* `name` - The name to lookup.args. (Mutually exclusive with
`first_found`)
* `type` - The type to assert (a type specification in string form)
* `default` - The default value if there was no value found (must comply
with the data type)
* `first_found` - An array of names to search, the value of the first
found is used. (Mutually 
  exclusive with `name`).
* `accept_undef` - (default `false`) An `undef` result is accepted if
this options is set to `true`.

When the call is on the form `lookup(name, options_hash)`, the given
name argument wins over the
`options_hash['name']`.

The type specification is one of:

  * The basic types; 'Integer', 'String', 'Float', 'Boolean', or
'Pattern' (regular expression)
  * An Array with an optional element type given in '[]', that when not
given defaults to '[Data]'
  * A Hash with optional key and value types given in '[]', where key
type defaults to 'Literal' and value to 'Data', if
    only one type is given, the key defaults to 'Literal'
  * The abstract type 'Literal' which is one of the basic types
  * The abstract type 'Data' which is 'Literal', or type compatible with
Array[Data], or Hash[Literal, Data]
  * The abstract type 'Collection' which is Array or Hash of any element
type.
  * The abstract type 'Object' which is any kind of type

If the function is called without specifying a default value, and
nothing is bound to the given name 
an error is raised unless the option `accept_undef` is true. If a block
is given it must produce an acceptable value (or call `error`). If the
block does not produce an acceptable value an error is
raised.