/*
 * $Id$
 */

/* $DOC$
   $TEMPLATE$
      Document
   $NAME$
      Strong Typing
   $CATEGORY$
      Document
   $SUBCATEGORY$
      Compiler
   $ONELINER$
      Compile-Time type checking
   $DESCRIPTION$
      Strong Type Checking could also be described as "Compile-Time Type
      Checking".

      CA-Cl*pper generates a Run-Time Error
      ("Type Mismatch") at an attempt to perform some operations with
      the wrong type of Variable.

      Examples:

      LOCAL Var1 := "A"

      ? Var1 * 3 // Error here.

      @ Var1, 7 SAY "Hello" // Error here.

      ? SubStr( "Hello", Var1 ) // Error here.

      The above 3 lines would all result in Run-Time Error, because Var1 is
      of type CHARACTER but the above lines used it as if it was of type
      NUMERIC.

      Using Strong Type Checking, or Compile-Time Type Checking, the above
      problem would have been discovered and reported in COMPILE-TIME,
      rather than waiting for the inevitable problem to be discovered when
      we finally execute the program.

      Strong Typed Languages allow the programmer to "tell" the compiler (declare)
      what is the type of a each Variable, so that the Compiler in return can warn
      the programmer, when ever such Declared (Strong Typed) Variable, is used in
      a context which is incompatible with its declared type.

      For instance, if we "told" the compiler that Var1 above is of type
      CHARACTER (LOCAL Var1 AS CHARACTER) the Harbour Compiler could, in
      return, warn us if we attempted to perform the calculation:

      Var1 * 3

      because the Compiler knows we can't perform a multiplication of a
      Character. (we might allow it in some context, but this is beyond
      the scope of this discussion). Similarly we would have been warned
      when attempting to use Var1 as a Row Number ( @ Var1 ), or as the
      2nd operand of the SubStr() function SubStr( "Hello", Var1) ),
      because the Compiler knows that these operations require a NUMERIC
      rather than CHARACTER type.

      The above may save us lots of time, by pointing a problem, we can not
      escape, since such code will never perform correctly once executed.
      So rather than wait to the testing cycle, for such problems to be
      discovered, (and some times even later, after we may have
      distributed our applications) instead we may know of such problems
      as soon as we type HARBOUR ProgName -w3

      Harbour also offers a hybrid mode, where it can report such type
      mismatch problems, even without requiring the programmer to declare
      the type of variables. This feature, is referred to as Adaptive Type
      Checking. The programmer is not required to make any changes in his
      code to take advantage of this feature. All of the above 3 errors
      would have been reported just as effectively as if the programmer
      Strong Typed (declared) Var1. Harbour would have been able to report
      such problems at compile time because the assignment Var1 := "A"
      implied that Var1 is of type CHARACTER,until it will be assigned
      another value. Therefore Harbour will "remember" that Var1 "adapted"
      type CHARACTER, and thus the subsequent multiplication Var1 * 3, will
      be reported as an error, as soon as you attempt to compile such code.

      The nice aspect of this hybrid mode, is that unlike Strong Typed
      Variables,you don't have to declare the type, so no code changes
      are need, the Type instead is assumed by implication (type of the
      assigned value). The other benefit, is that it is completely OK to
      assign a new value of different type, any time, to such undeclared
      (variant) variable. As soon as we assign a new type, the Compiler
      will than protect us from using the Variable in an incompatible
      context, since the variable "adapted" this type as soon as we
      assigned a value which implies a type.

      While Adapted Type Checking may be fairly effective in reporting many
      common mistakes, to take full benefits of such Compile-Time checking,
      it is recommended to do declare the Type of Variables, when ever
      possible.

      The Harbour Strong Type features, also allows the declaration of the
      expected parameters (including optionals) of User Defined Functions,
      as well as their return Type. Similarly, you may declare the Type of
      any Class Variables, Methods, and Methods Parameters.
   $END$
 */
