That was my thought. If anything the software ecosystem around Arduinos and Raspberry Pis is much improved compared to what came before (e.g. PICs).
Partially it comes down to the constraints you're working under. When everything, program, data, and all has to fit in a few K of RAM, you use "ugly" hacks to make sure that everything fits, while leaving you the maximum amount of space needed for your data. While modern embedded system' capabilities have grown to the point where those practices aren't needed any more, the software development practices for those systems are slower to change.
I think another big reason is that, compared to desktop and web based software, embedded applications are almost always completely custom. There are common hardware specs on every PC, and three big operating systems. So you end up having huge developer communities that build all kinds of utilities, tools, and other building blocks that you can easily reuse. Usually embedded systems have a fairly simple operating system, and custom hardware, which means there isn't much reusable code, and it's up to the developer to provide a much larger portion of the functionality.
Partially it comes down to the constraints you're working under. When everything, program, data, and all has to fit in a few K of RAM, you use "ugly" hacks to make sure that everything fits, while leaving you the maximum amount of space needed for your data. While modern embedded system' capabilities have grown to the point where those practices aren't needed any more, the software development practices for those systems are slower to change.