Si uso un sin sellar trait
o abstract class
en Scala y luego uso la coincidencia de patrones, me pregunto, ¿el compilador no sabe en el momento de la compilación para este patrón en particular qué posibles implementaciones de este rasgo / clase están disponibles? Entonces, si lo hace, ¿no podría dar advertencias de coincidencia de patrones a pesar de que trait
/ abstract class
no está sellado porque sabe qué tipos podrían usarse, al verificar todas las dependencias / importaciones posibles?
Por ejemplo, si tengo una Option[A]
coincidencia de patrones y solo para Some[A]
pero no para None
, el compilador se quejará porque Option
está sellado.
Si el compilador no puede saber / resolver eso, ¿por qué no puede hacerlo? Y si el compilador (en teoría) puede hacer eso, ¿cuáles son las razones por las que no se usa en Scala? ¿Hay otros idiomas que soporten ese tipo de comportamiento?
fuente
Foo
con subclasesA
,B
yC
, y todas sus coincidencias de patrones coinciden solo con esas tres. Nada me impide agregar una nueva subclaseD
que explote tus coincidencias de patrones.java.lang.ClassLoader
.Respuestas:
Resolver todas las subclases de una clase se llama Análisis de jerarquía de clases, y hacer CHA estático en un lenguaje con carga de código dinámico es equivalente a resolver el Problema de detención.
Además, uno de los objetivos de Scala es la compilación y el despliegue separados de módulos independientes, por lo que el compilador simplemente no puede saber si una clase está subclaseada en otro módulo, ya que nunca analiza más de un módulo. (¡Después de todo, puede compilar un módulo contra la interfaz de algún otro módulo sin que ese módulo exista en su sistema!) Es por eso
sealed
que todas las subclases se definen en la misma unidad de compilación.Esa es también una de las razones por las cuales las JVM pueden competir tan favorablemente con los compiladores de C ++: los compiladores de C ++ suelen ser compiladores estáticos, por lo que, en general, no pueden determinar si un método está anulado o no, y por lo tanto no pueden alinearlo. JVMs OTOH, generalmente son compiladores dinámicos, no necesitan realizar CHA para determinar si un método se anula o no, solo pueden mirar la Jerarquía de clases en tiempo de ejecución. E incluso si en un momento posterior en la ejecución del programa aparece una nueva subclase que no estaba allí antes, no es gran cosa, simplemente recompile ese fragmento de código sin incluirlo.
Nota: todo esto solo se aplica dentro de Scala. La JVM no tiene noción de
sealed
, por lo que es perfectamente posible subclasificar lassealed
clases de otro lenguaje JVM, ya que no hay forma de comunicar esto a otro idioma. Lasealed
propiedad se registra en laScalaSig
anotación, pero los compiladores de otros idiomas no tienen en cuenta esas anotaciones, obviamente.fuente
Se puede hacer (al menos para todas las clases conocidas en tiempo de compilación), es simplemente costoso. Destruiría por completo la compilación incremental, porque todo lo que contenga una coincidencia de patrones debería volver a compilarse cada vez que se modifique cualquier otro archivo.
Y que estas comprando? Es un olor a código para escribir coincidencias de patrones que deben cambiar con frecuencia cuando se agrega una nueva clase derivada. Es una violación del principio abierto / cerrado . Use la herencia correctamente y no necesitará escribir ese tipo de coincidencias de patrones. Y sí, el principio abierto / cerrado también se aplica a lenguajes funcionales sin herencia basada en clases. De hecho, entre características como clases de tipos, métodos múltiples y funciones simples de orden superior, los lenguajes funcionales hacen que la extensión sin modificación sea mucho más fácil.
fuente
It can be done (at least for all classes known at compile time), it's just expensive.
Pero si el programa no es 100% autónomo (es decir, depende de.jar
archivos externos ), ¿no podría colarse en una nueva subclase después de compilar a través de uno de losjar
s? Por lo tanto, el compilador podría decirle "Sus coincidencias de patrones son exhaustivas ahora, pero eso puede cambiar si alguna de sus dependencias cambia", lo que no tiene ningún valor ya que el punto de tener dependencias externas es poder actualizarlas sin volver a compilar.