Cuando la gente dice "X no compone", lo que quieren decir con "componer" en realidad solo significa "juntar", y qué y cómo los juntas pueden ser muy diferentes, dependiendo de qué es exactamente "X".
Además, cuando dicen "no compone", pueden significar algunas cosas ligeramente diferentes:
- No puedes poner dos X juntas, punto.
- Usted puede poner dos Xs juntos, pero el resultado puede ser que no sea una X (OIA: X no está cerrado bajo la composición ).
- Puede juntar dos X, pero la X resultante podría no funcionar de la manera esperada.
Un ejemplo para el n. ° 1 son los analizadores con escáneres / lexers. Es posible que escuche la frase "los escáneres / lexers no componen". Eso no es realmente cierto. Lo que quieren decir es "el analizador que usa una etapa lexing separada no compone".
¿Por qué quieres componer analizadores? Bueno, imagina que eres un proveedor de IDE como JetBrains, Eclipse Foundation, Microsoft o Embarcadero, y quieres construir un IDE para un marco web. En el desarrollo web típico, a menudo mezclamos idiomas. Tiene archivos HTML con <script>
elementos que contienen ECMAScript y<style>
elementos que contienen CSS. Tiene archivos de plantilla que contienen HTML, algún lenguaje de programación y algunas metasintaxis de lenguaje de plantilla. No desea escribir marcadores de sintaxis diferentes para "Python", "Python incrustado en una plantilla", "CSS", "CSS dentro de HTML", "ECMASCript", "ECMAScript dentro de HTML", "HTML", "HTML dentro de una plantilla ", y así sucesivamente. Desea escribir un resaltador de sintaxis para Python, uno para HTML, uno para el lenguaje de plantilla y luego componer los tres en un resaltador de sintaxis para un archivo de plantilla.
Sin embargo, un lexer analiza el archivo completo en una secuencia de tokens, lo que solo tiene sentido para ese idioma. El analizador para el otro idioma no puede funcionar con los tokens que el lexer lo pasa. Por ejemplo, los analizadores de Python generalmente se escriben de tal manera que el lexer realiza un seguimiento de la sangría e inyecta falsificaciones INDENT
y DEDENT
tokens en la secuencia de tokens, lo que permite que el analizador esté libre de contexto aunque la sintaxis de Python no lo sea. Sin embargo, un lexer HTML ignorará completamente los espacios en blanco, ya que no tiene significado en HTML.
Sin embargo, un analizador sin escáner, que simplemente lee caracteres, puede pasar el flujo de caracteres a un analizador diferente, que luego puede devolverlo, lo que hace que sean mucho más fáciles de componer.
Un ejemplo de # 2 son las cadenas con consultas SQL en ellas. Puede tener dos cadenas, cada una de las cuales tiene una consulta SQL sintácticamente correcta, pero si concatena las dos cadenas, el resultado puede no ser una consulta SQL sintácticamente correcta. Es por eso que tenemos de consulta como álgebra ARel
, que hacen componer.
Las cerraduras son un ejemplo de # 3. Si tiene dos programas con bloqueos, y los combina en un solo programa, todavía tiene un programa con bloqueos, pero incluso si los dos programas originales eran completamente correctos, libres de puntos muertos y carreras, el programa resultante no necesariamente tiene esto propiedad. El uso correcto de los bloqueos es una propiedad global de todo el programa y una propiedad que no se conserva al componer programas. Esto es diferente de, por ejemplo, transacciones, que hacen de redacción. Un programa que usa transacciones correctamente puede componerse con otro de esos programas y producirá un programa combinado que usa transacciones correctamente.