I understand that 32 bit programs are limited to 4gb of ram because their pointers are 32bit. Buy why are their pointers 32bit long even in a 64bit system why can't the pointers store memory addresses in a long datatype for example instead of unsigned int?
You have a few questions here:
Why aren't C pointers longs: because a long is actually two memory locations more or less glued together. Now your pointer is really two pointers which, in addition to throwing away more of your precious working memory, is more complex to deal with. This is more or less the way that support for more memory was added to old 8 and 16 bit computers. This is used in some special cases, like on old 32 bit versions of Windows Server.
Why aren't 32 bit applications on 64 bit systems "promoted" to 64 bit: because while it might work on small, simple programs it could very well break custom data structures and various hacks the programmer put in place. It's technically doable to take a binary and 'recompile' it for 64 bit but the odds of it working perfectly are pretty low for various reasons. We don't really do that because the application was certainly designed to max out at 4gb so the programmer at the time should've prepared for that.
This is a really complicated architecture issue and I've had to simplify a ton of things. Best to leave this at "because it works that way"