Simply, not all applications are compiled 32bit or 64bit binaries.
- Most Python libraries scripts are "compiled" at runtime by the native Python binary (which will be running in 32 bit or 64bit mode, depending on the system). Same with Java.
- Some packages are just resources for another package and can be shared between 32bit and 64bit packages (eg Kernel source packages).
The packages that are separated into architecture are either compiled to machine code, rely too much on architecture-related dependencies or otherwise have architecture-dependent code inside (seems unlikely though).
"Fat" packages and binaries are something that has been toyed with in the past but you're really talking about doubling the size of most binaries and libraries, as well as introducing unforeseen bugs. It's simply not an advantage worth the cost.
It's also worth considering that in most cases developers don't really have to do anything to get architecture specific packages. They'll push them to a build platform like Launchpad and Launchpad will return a bunch of 32bit, 64bit and ARM variant packages.