But when you think about it it is kind of logical: inner loops and low level code tend to be fairly static and are often re-used so it pays of to write them in a language that maximizes for that use-case, but structure can be executed much slower and re-use is relatively low when going from one application to the next so it pays of to write that in another language.
So we get this split roughly halfway down the application stack where we switch from interactive and interpreted high level language to compiled low level language.
It's a very interesting optimum.