What are the differences?
First of all, terminology: it's "Ada", not "ADA" -- it's named after "Ada Lovelace"; it is not an acronym.
A subtype is compatible with its base type, so you can mix operands of the base type with operands of the base type. For example:
subtype Week_Days is Integer range 1..7;
Since this is a subtype, you can (for example) add 1
to a weekday to get the next weekday.
A derived type is a completely separate type that has the same characteristics as its base type. You cannot mix operands of a derived type with operands of the base type. If, for example, you used:
type Week_Day is new Integer range 1..7;
Then you would not be able to add an integer to a weekday to get another weekday. To do manipulations on a derived type, you'd normally define those manipulations yourself (e.g., create a package). At the same time, a derived type does "inherit" all the operations of its base type (even some that may not make sense) so you do still get addition.
From Wikibooks:
Subtypes of a given type will be compatible with each other.
A derived type is a new, full-blown type created from an existing one. Like any other type, it is incompatible with its parent; however, it inherits the primitive operations defined for the parent type.
The basic difference is that a derived type is a different type. You cannot just assign one to the other, or use them together in an expression. A subtype on the other hand is assignment-compatible with its original type. You use them together without having to enter any type-munging code.
The subtype will have a narrower range than the base type though, so there may be range checks (from which I believe Constraint_Error can be rasied). So you do still have to be careful.