Para seleccionar el lenguaje adecuado en determinado proyecto de desarrollo de software, se recomienda evaluar criterios de relevancia técnica y económica como:
4.1.1. Escalabilidad
El lenguaje debe permitir la construcción de programas desde unidades de compilación que han sido codificados y probados separadamente, quizás por diferentes programadores. La compilación separada es una necesidad práctica, dado que inconsistencias de tipos son menos comunes al interior de una unidad de compilación (escrito por un único programador) que entre las unidades de compilación (quizás escrita por diferentes programadores) y lo último no es detectado por compilación independiente.
4.1.2. Modularidad
El lenguaje debe soportar la descomposición de los programas en unidades de programa de tal manera que podemos distinguir claramente entre lo que hace cada una unidad de programa (vista de programador) y cómo será codificada (vista de implementador); esta separación es una herramienta de interés intelectual esencial para la gestión del desarrollo de programas de gran envergadura. Conceptos de este contexto son los procedimientos, paquetes, tipos abstractos, y clases.
4.1.3. Reusabilidad
El lenguaje debe soportar la reutilización de unidades de programa para acelerar la reutilización en las pruebas que se hace a dichas unidades de programa, e incluso éstas pueden tomarse para desarrollar nuevas unidades de programa. Los conceptos relevantes asociados a este criterio son los paquetes, tipos abstractos, clases y particularmente unidades genéricas.
4.1.4. Portabilidad
El lenguaje debe ayudar a la escritura de código portable; es decir, el código puede ser movido de una plataforma a otra, sin sufrir grandes cambios.
4.1.5. Nivel
El lenguaje debe motivar a los programadores a pensar en términos de abstracciones de alto nivel orientado a la aplicación y no forzarlos a pensar todo el tiempo en cuanto a detalles de bajo nivel, tales como bits y punteros. Ello puede propiciar errores, especialmente si se utilizan punteros (aunque a veces es necesario su uso).
4.1.6. Confiabilidad
El lenguaje debe ser diseñado de tal manera que pueda detectar y eliminar los errores de programación lo más rápidamente posible. Lo ideal es que los errores deben ser detectados en tiempo de compilación para garantizar la ausencia de errores en el programa en tiempo de ejecución. Los errores detectados en tiempo de ejecución garantizan que no causan algún daño, que no sea una excepción, o en el peor de los casos dar por concluido el programa. Los errores no detectados en absoluto pueden causar daño sin límites (datos corruptos) antes de que el programa se bloquee, congele o cuelgue. La confiabilidad es siempre importante y esencial en sistemas críticos.
4.1.7. Eficiencia
El lenguaje debe ser capaz de ser aplicado de manera eficiente. Algunos aspectos de la programación OO implican sobrecargas en tiempo de ejecución, tales como tags de clases, dispatch dinámicos, garbage collection que hace más lento el programa en momentos impredecibles y los controles en tiempo de ejecución (aunque algunos compiladores están dispuestos a suprimirlos, con riesgo por cuenta del programador). El código interpretado es unas diez veces más lento que el código máquina nativo, aunque las partes críticas del programa debe ser altamente eficiente y el lenguaje debe permitir ajustes de codificación de bajo nivel, o hacer llamadas a procedimientos escritos en un lenguaje de bajo nivel.
4.1.8. Legibilidad
El lenguaje debe motivar buenas prácticas de programación, no debe imponer sintaxis críptica, identificadores muy cortos, declaraciones por defecto o ausencia de información de tipo; ya que eso hace que sea difícil escribir código legible. El punto es que el código es leído (por su autor y otros programadores) con más frecuencia de lo que es escrito.
4.1.9. Modelamiento de datos
El lenguaje debe ofrecer tipos, y operaciones asociadas que sean adecuadas para la representación de las entidades en las pertinentes áreas de aplicación. Ejemplos de ello serían los registros y archivos de procesamiento de datos, números reales y las matrices de cálculo científico, cadenas en el procesamiento de texto, listas, árboles, mapping de los traductores, las colas en los sistemas operativos y simuladores. Si el lenguaje en sí mismo carece de los tipos, es necesario que permita a los programadores definir nuevos tipos y operaciones que las entidades con precisión el modelo en el área de aplicación. Conceptos de este contexto son los tipos abstractos y las clases.
4.1.10. Modelamiento de procesos
El lenguaje debe proporcionar estructuras de control adecuadas para modelar el comportamiento de las entidades en las pertinentes áreas de aplicación. En particular, se necesita concurrencia para modelar simultáneos procesos en simuladores, sistemas operativos y controladores de procesos en tiempo real.
4.1.11. Disponibilidad de los compiladores y herramientas
El lenguaje debe tener disponible compiladores de buena calidad que haga cumplir la sintaxis del lenguaje y las reglas tipo, que genere código objeto correcto y eficiente, que genere controles en tiempo de ejecución (por lo menos como opción) para atrapar cualquier error que no se pueden detectar en tiempo de compilación, y los informes de todos los errores de forma clara y precisa. Además se debe disponer de un entorno integrado de desarrollo de buena calidad (IDE) porque aumenta la productividad mediante la combinación de un editor de programas, compilador, enlazador, depurador y herramientas relacionadas a un único sistema integrado.
4.1.12. Familiaridad
El lenguaje debe ser conocido por los programadores disponibles en el mercado. En caso no sea así, se debe analizar si existe disponibilidad de formación de alta calidad y si la inversión que se aplicará en tiempo y dinero justifica la formación para futuros proyectos.