Aunque, mi pregunta puede ser completamente irrelevante, pero he sentido un patrón entre la mayoría de los lenguajes de programación y sus implementaciones oficiales.
Los lenguajes interpretados (¿interpretados por byte?) Como Python, Lua, etc. generalmente tienen una sintaxis extremadamente indulgente y fácil y generalmente no tienen tipo o no requieren que el desarrollador escriba explícitamente tipos de variables en el código fuente;
Los lenguajes compilados como C, C ++, Pascal, etc. generalmente tienen una sintaxis estricta, generalmente tienen tipos y en su mayoría requieren más tiempo de código / desarrollo
Los lenguajes cuyas implementaciones oficiales están compiladas en JIT como Java / C # suelen ser un compromiso único entre los dos anteriores con algunas de las mejores características de ambos.
Algunos de los lenguajes de programación compilados más modernos como D y Vala (y la implementación GNU GJC de Java) son quizás una excepción a esta regla y se parecen a la sintaxis y las características de los lenguajes compilados JIT como Java y C #.
Mi primera pregunta es, ¿es esto realmente relevante? ¿O es solo una coincidencia que la mayoría de los idiomas interpretados tienen una sintaxis fácil, los compilados JIT tienen una sintaxis moderada y características, etc.
En segundo lugar, si esto no es una coincidencia, ¿por qué es así? Como, por ejemplo, ¿algunas características solo pueden implementarse en un lenguaje de programación si, por ejemplo, está compilando JIT?
fuente
Respuestas:
No hay conexión alguna entre semántica y sintaxis. Los lenguajes compilados homoicónicos como Scheme vienen con una sintaxis bastante minimalista. Los metalenguajes compilados de bajo nivel como Forth son aún más simples que eso. Algunos lenguajes compilados estrictamente tipados se basan en una sintaxis trivial (piense en ML, Haskell). OTOH, la sintaxis de Python es muy pesada, en términos de una serie de reglas de sintaxis.
Y sí, escribir no tiene nada que ver con la sintaxis, está en el lado semántico de un lenguaje, a menos que sea algo tan pervertido como C ++, donde ni siquiera se puede analizar sin tener toda la información de escritura disponible.
Una tendencia general es que los lenguajes que evolucionaron durante demasiado tiempo y no contenían ninguna protección de diseño contra las desviaciones de sintaxis, tarde o temprano evolucionarían en abominaciones sintácticas.
fuente
type checking
" es extremadamente contraproducente y no debe usarse, es muy engañoso, no refleja la naturaleza de los sistemas de tipos.Sobre todo esto es una coincidencia.
Los lenguajes de programación han evolucionado con el tiempo y la tecnología de compiladores e intérpretes ha mejorado. La eficiencia del procesamiento subyacente (es decir, el tiempo de compilación, la sobrecarga de interpretación, el tiempo de ejecución, etc.) también es menos importante a medida que las plataformas informáticas convencionales han crecido en potencia.
La sintaxis del lenguaje hace tener un impacto - por ejemplo, Pascal fue diseñado con mucho cuidado por lo que podría utilizar un único pase compilador - es decir, un pase sobre la fuente y tiene código de máquina excutable. Ada, por otro lado, no prestó atención a esto, y los compiladores de Ada son notoriamente difíciles de escribir, la mayoría requiere más de un pase. (Un muy buen compilador Ada que utilicé hace muchos años fue un compilador de 8 pases. Como se puede imaginar, fue muy lento).
Si observa idiomas antiguos como Fortran (compilado) y BASIC (interpretado o compilado), tienen / tenían una sintaxis muy estricta y reglas semánticas. [En el caso de BASIC, eso no es Bills old BASIC, debe volver antes al original.]
Por otro lado, mirando otras cosas más antiguas como APL (un montón de diversión) esto tenía una tipificación dinámica, más o menos. También se interpretó generalmente, pero también se pudo compilar.
La sintaxis de Lenient es difícil: si eso significa que tiene cosas que son opcionales o que se pueden inferir, significa que el idioma tiene la riqueza suficiente para poder eliminarlo. Por otra parte, BASIC tenía eso hace muchos años cuando la declaración "LET" se convirtió en opcional.
Muchas de las ideas que ve ahora (por ejemplo, mecanografía sin tipo o dinámica) son en realidad muy antiguas: aparecieron por primera vez en los años 70 o principios de los 80. La forma en que se usan y los idiomas en que se usan estas ideas han cambiado y crecido. Pero fundamentalmente, gran parte de lo nuevo es en realidad cosas viejas vestidas con ropa nueva.
Aquí hay algunos ejemplos fuera de mi cabeza:
Podría seguir.
Actualización: porque no estaba lo suficientemente claro.
Escribir puede variar ampliamente.
La tipificación estática fija en tiempo de compilación es común (p. Ej., C, Ada, C ++, Fortan, etc., etc.). Aquí es donde declaras una COSA de TIPO y es así para siempre.
También es posible tener una escritura dinámica, donde la cosa recoge el tipo que se le asigna. Por ejemplo, PHP y algunos principios básicos, y APL, donde asignaría un número entero a una variable y de ahí en adelante era un tipo entero. Si luego le asignó una cadena, entonces era un tipo de cadena. Y así.
Y luego hay una escritura suelta, por ejemplo PHP, donde puedes hacer cosas realmente extrañas como asignar un número entero (entre comillas, por lo que es una cadena) a una variable y luego agregarle un número. (por ejemplo, '5' + 5 daría como resultado 10). Esta es la tierra de lo extraño, pero también a veces muy útil.
SIN EMBARGO, estas son características diseñadas en un lenguaje. La implementación solo hace que eso suceda.
fuente
Creo que es al revés: la implementación depende de la sintaxis. Por ejemplo, si su sintaxis permite la reflexión, entonces la implementación debe proporcionar un tiempo de ejecución que lo admita.
fuente
Generalmente estoy de acuerdo con rapid_now en que su observación es principalmente un resultado de la historia. Dicho esto, el razonamiento subyacente se reduce a algo como esto:
(No es una cita realmente, solo mi propia formulación). Cuando escribo
comfortable
aquí, me refiero a lo que usted llamóbest features of both
. Más precisamente, no quiero hablar a favor o en contra de la escritura estática / dinámica o la sintaxis estricta / indulgente. En cambio, es importante ver el enfoque puesto en los desarrolladores y aumentar su nivel de comodidad al trabajar con el lenguaje.Aquí hay algunas razones que no se han mencionado en las respuestas anteriores, que pueden proporcionarle algunas ideas de por qué observa estas cosas (y están basadas en la historia del desarrollo del lenguaje de programación):
Tenemos cientos de lenguajes de programación en estos días. Cuando surge una nueva, ¿cómo puede encontrar una audiencia amplia? Esta es la razón principal por la cual los nuevos lenguajes siempre intentan aumentar el nivel de comodidad de los desarrolladores. Si el idioma puede hacer lo mismo que el anterior, pero puede hacerlo mucho más fácil / más simple / más elegante / etc. es posible que desee considerar cambiar realmente.
La curva de aprendizaje va de la mano con eso. En el pasado, teníamos pocos idiomas y valía la pena invertir tiempo para aprender uno. Incluso si eso significaba invertir mucho tiempo. La comodidad vuelve a aumentar si se te ocurre un lenguaje que los desarrolladores puedan aprender muy rápidamente. La complejidad de cualquier tipo (por ejemplo, sintaxis complicada involucrada) es perjudicial para esto y, por lo tanto, se reduce cada vez más en los idiomas más nuevos.
Los avances tecnológicos (una razón histórica directa aquí) son responsables de que los creadores de compiladores ahora puedan centrarse más en la comodidad del desarrollador. En los primeros días, estábamos felices de poder construir un compilador. Sin embargo, eso a menudo implicaba fuertes restricciones. A medida que aumentó el conocimiento tecnológico, pudimos levantar estas restricciones nuevamente.
Entonces, en general, los lenguajes de programación y los compiladores han visto un desarrollo similar al de las aplicaciones típicas de usuario final:
fuente
(Not a quote really, just my own formulation.)
Bueno, lo formateó como código, no como una cita enUn lenguaje de programación dado puede o no exponer o restringir suficiente información semántica para que un compilador deduzca cómo reducirlo a código ejecutable sin decisiones adicionales de tiempo de ejecución ("¿qué tipo es esta variable?", Etc.) Algunos lenguajes están explícitamente diseñados para hacer Esta restricción es obligatoria o fácil de determinar.
A medida que los compiladores se vuelven más inteligentes, podrían adivinar o perfilar suficiente información para generar código ejecutable para la (s) ruta (s) más probable (s) incluso para idiomas que no fueron diseñados explícitamente para exponer o restringir esas decisiones.
Sin embargo, los idiomas donde el código (evalString ()) se puede crear o ingresar en tiempo de ejecución (y otras cosas que el compilador no puede deducir ni adivinar) pueden requerir un intérprete o compilador JIT para estar disponible en tiempo de ejecución, incluso con intentos de compilarlos.
En el pasado, un lenguaje de programación y su implementación podrían haber evolucionado para ajustarse a alguna restricción de hardware, como si el intérprete podría caber en 4k o 16k, o si el compilador podría terminar en menos de un minuto de tiempo de CPU. A medida que las máquinas se vuelven más rápidas, es posible (re) compilar algunos programas interpretados anteriormente tan rápido como el programador puede presionar la tecla de retorno, o interpretar el código fuente del programa compilado anteriormente más rápido de lo que el hardware un poco más antiguo podría ejecutar ejecutables compilados optimizados.
fuente