Why do Unix-like systems execute a new process when calling a function rather than a dynamic library? Creating a new process is costly in terms of performance when compared to calling a dynamic library.
Unix-like systems don't "call functions by executing new processes". They (now) have shared libraries like pretty much all other relatively modern operating systems.
Shells on the other hand do execute other processes to do certain tasks. But not all. They have build-in functions,implemented directly in the shell (or via shared libraries) for the most common and simple tasks (
Creating a process in modern Unix-like systems is certainly more expensive than doing an in-process function call, but not by such a huge margin. Kernels are optimized for fast forking, using techniques like copy on write for address space management to speed up "cloning" of processes, and sharing the text (code) pages of dynamic libraries.
If every executable on your machine that could be called from a shell script was implemented as a shared library, either:
So you probably would not gain much for typical usage, and stability/complexity becomes more of an issue.
Another thing is that the separate process model isolates each task very effectively (assuming virtual memory management & protection). In the "everything is a library" model, a bug in any utility library could pollute (i.e. corrupt) the entire shell. A bug in some random utility could kill your shell process completely.
Something else: lower coupling. When I look at what's in my
... and I probably don't have the most fancy system out there. You simply can't mix the first two types in the same process. Having an interpreter in-process for all the other ones simply isn't practical.
There are things for which in-process calls do make a lot of sense performance wise, and those are already, very often, done as built-ins by the shells. For the rest, the separate processes model works very effectively, and its flexibility is a great advantage.