All the source code I could find (to date) has declared transfer, transferFrom, approve, approveAndCall as public and not external.
Although external can be used, what is the reason behind not using it ?
The ERC20 specification states that they should be public instead of external. It does violate the ERC20 specification if you mark them as external.
However, in practice this should not be an issue. The difference between external and public functions are that in public functions, the call data is copied to memory first. In external functions, the data is read directly from the call data. Hence the gas savings if you change from public to external is that in the external function you do not have the extra logic to copy the data to memory. In practice this only saves a few gas units (in most cases less than 100 gas).
The downside of using external functions is that you cannot call them from within the contract (in the same call frame). The reason is that an external function reads it from the call data which you cannot change in the current call frame.