  The compiler attempts to insert omitted applications of the V (ValueOf)
operation, omitted applications of functions with no argument, certain
kinds of omitted arguments to function applications, and omitted selections
for identifiers.  If x is a Boolean variable, the expression
         
                    x and True

would normally be converted by the compiler to

          Boolean$V[x] Boolean$and Boolean$True[]

  In addition, the compiler deduces when forgetting operations on types
are called for.
  Omitted applications of V, and omitted applications of functions with
no arguments are inserted whenever an expression has signature var T
or func[] val T, and it would be signature correct only with a signature
of val T.  (In the case of an application of an identifier, the compiler
first looks for instances of the identifier which will the arguments
to match without coercion.)
  Selections are inserted whenever no declared identifier with appropriate
signature can be found.  The first attempt is to select from one of the
argument types.  (The argument type of an operand with val or var signature
is the type in the signature.  For a function the result type is used.)
This is done in left-to-right order.  If this fails, various surrounding
use-blocks are tried, inside-out, left-to-right.
  Omitted arguments are inferred only at the end of an argument list.
This will happen in 3 distinct cases:

        1) The arguments can be inferred by unification of non-type argument
	   and parameter signatures.

	2) The parameter type is var Void.  (The innermost parameter
	   with this signature is used.)

        3) The first three parameters have val signature, and two
           arguments, both of which are unquoted strings, and the name of
           the operator is '.'
           The third argument will be inferred to be the length of the second
           string. (Technically a string which is the decimal representation
           of the length.  Its type will be inferred using the usual
           approaches.) This makes it possible for small floating point
           constants to be recognized.  (This rule is applied before (1).)

  The compiler attempts to insert omitted selections wherever an identifier
occurs in an expression.  Omitted argument inference is attempted for any
application.  Applications to no arguments, and applications of the V
operation are inserted wherever they are found to be necessary as a
result of signature matching.  This occurs in guards for do- or if-
-expressions, on the right side of an if-expression, for a function body
if an explicit result signature is given, and in an application.  Forgetting
of type components is allowed in applications and function bodies, but not
currently in conditionals.
  It is worth noting that the compiler has to infer this information in
conjunction with assigning signatures to expressions in the program.  The
general "algorithm" it uses to accomplish this is to sort all subexpressions
occurring in the program by the dependence of the signature of one sub-
expression on those of other subexpressions.  It then assigns signatures
and adds coercions, starting with those subexpressions which do not
depend on other parts of the program.  This will fail if there are circular
dependencies between subexpressions (as in let a == func[]{a[]} ...).
The compiler will issue an error message if this happens.  It should always
be possible to remedy such a situation by inserting more explicit signature
information (let a == func[]val Short{a[]} ...).
  Unfortunately, the "algorithm" used is sufficiently complicated, that
it may not be apparent why a circularity did, or did not, arise.  In
particular, the compiler has to consider the signature of an application
to be dependent on the signature of the arguments, since they are likely
to be used to infer selections for the operator.  Similar "extra"
dependencies arise elsewhere.
  Almost none of the preceding is done for expressions which appear
inside signatures.  Only selections are inferred, and that is done
solely on the basis of identifier names, and not their signatures.
  In spite of all of this, this mechanism appears to rarely cause serious
problems.  It is safe to experiment, since it is virtually guaranteed that
the compiler will either infer correct information, complain about a
circularity, or, on rare occasions, make an inappropriate inference which
will result in a signature matching error.

See also: float

Note: If you make any discoveries which contradict the last paragraph,
please send mail to boehm@washington.

