Low-level languages have for a long time dominated the field of embedded systems due to their rapidity and flexibility. As high level languages are becoming faster and faster, might the situation get reversed soon? Can high-level languages become frequent in embedded systems in a near (or not so near) future? What would it take for a high-level language to be suitable for embedded systems?
What is a high level language? What is an embedded system? Once upon a time C was a high level language and a Raspberry Pi would have changed the outcome of major wars, now almost every microcontroller can be programmed with C and we use Pis that run a full-blown desktop OS to turn servo motors. Let's say a high level language is a language that has strong abstraction mechanisms and an embedded system is a system with very limited memory and a processor with few features.
That alone is not enough to say whether this language is suitable for embedded programming or not. The important part is how the programs in the language can be compiled. Many languages (have to) add something called a runtime to the programs. For Haskell for example the runtime added by GHC is about 50k LOC and includes a garbage collector, a scheduler and a bunch of other stuff. That is quite a lot of code for a small chip to handle and might require processor features that aren't present.
Rust is another language that I'd call high-level, but it is possible (in theory at least) to run Rust on many embedded systems. This is because Rust has the possibility to use a much smaller runtime that can be handled by simpler processors and doesn't add as much overhead.
So in summary, the important part is not the features of the language, but how much of those features need support at runtime as opposed to a clever compiler. Garbage collection is typically too difficult for embedded systems, but a surprising amount of abstraction power can be provided without any extra costs at runtime.
Note that in practice you're still limited to C or Assembler in many cases, because you need a compiler that supports your target architecture. Unfortunately it is often the case that the architecture is proprietary and you're limited to using the compiler provided by the manufacturer. That is typically a compiler that supports some flavor of C.
There is metaprogramming exists many years ago, so you can do hardware/software codesign in any programming language including Python, Prolog, Lisp or anything you want to use.
Take code generation as a base principle, wrap C code writing to files, or wrap LLVM which can cross-compile directly to your system object code. Implement some class tree represents both source code elements (modules, functions, control structures), and your target model components (finite automata, DSP processing elements,..).
You can construct the target software you want to build by interconnecting these like objects and transform model object to source code objects by your metaprograms. And finally, call code generation method in a recursion starting from the top-level object, which will generate files with C source code, or directly call LLVM.
Of cause, it is not an easy or well-described method, but it works at least at the level of parametric code snippets composition. As an example, look on CodeMX init code generator suite provided by STMicro. It is a closed-source vendor-provided system, but you can brew your own analog maybe not GUI but script-driven.
Also look on knowledge representation and reasoning, it will give you an idea of how it can be implemented.