Programming languages come in many flavors and finding a balance between simplicity, expressiveness, and other desired properties is difficult. Programming languages can be at different levels of abstraction, with some providing more control over machine resources and others hiding machine details. Ultimately, programs must be in a form the computer can execute directly as machine code. Compilers translate programs to machine code for direct execution, while interpreters translate programs piece-by-piece at runtime.