It's a hack left over from the early days when AT&T UNIX became BSD. Under pre-BSD UNIX systems, a program was started by forking a new process, which meant sharing the code and copying the data. Then the new process did an exec, which loaded a new code segment and wiped the data segment that had just been copied. Copying the data segment and immediately overwriting it was inefficient, so several new flavors of "exec" were developed to get around that.
There probably should have just been a "run" call, which started a subprocess given the indicated executable. Some UNIX-like operating systems have that. It has the nice property that it scales to clusters; there's no reason a subprocess can't run on another machine. QNX, for example, supports that.
> Copying the data segment and immediately overwriting it was inefficient, so several new flavors of "exec" were developed to get around that.
The several different flavors of exec are just convenience functions that lead to an execve syscall (execl* makes the vector out of some of its args; exec*p searches the path first, etc). Maybe you're thinking of vfork (a restricted fork), which seems to have gone away about when copy-on-write came in.
There probably should have just been a "run" call, which started a subprocess given the indicated executable. Some UNIX-like operating systems have that. It has the nice property that it scales to clusters; there's no reason a subprocess can't run on another machine. QNX, for example, supports that.