Me pregunto cuáles son las diferencias de implementación técnica entre C # y Scala y cómo ambas soluciones se comparan con las ideas y preocupaciones de implementación expresadas en el correo electrónico Peek Past lambda de Brian Goetz, enviado a la lista de correo del Proyecto Lambda (JSR 335) .
Desde el correo electrónico:
Exploramos el camino de "quizás las lambdas deberían ser solo instancias de clase interna, eso sería realmente simple", pero finalmente llegamos a la posición de "las funciones son una mejor dirección para el futuro del lenguaje".
y además:
La visión lambdas-son-objetos del mundo entra en conflicto con este posible futuro. La visión del mundo de las lambdas-son-funciones no lo hace, y preservar esta flexibilidad es uno de los puntos a favor de no cargar a las lambdas incluso con la apariencia de objetividad.
Conclusión:
Lambdas-are-functions abre puertas. Lambdas-are-objects los cierra.
Preferimos ver esas puertas abiertas.
Y un comentario de una persona en el hilo de Reddit dice:
De hecho, envié un correo electrónico a Neal Gafter sobre esto y para mi comprensión limitada de su explicación C # y el diseño actual de Java son bastante similares en el sentido de que los Delegados son en realidad objetos y no tipos de funciones. Parece que él cree que Java debería aprender de las desventajas de las lambdas de C # y evitarlas (al igual que C # aprendió de las desventajas de Java y las evitó al principio).
¿Por qué el enfoque de "Lambdas-son-funciones" permite más oportunidades en el futuro que "Lambdas-son-objetos"? ¿Alguien puede explicar qué diferencias existen y cómo influirían en cómo se escribiría el código?
Al ver que las cosas en Scala "simplemente funcionan", sigo pensando que me falta algo sobre los enfoques adoptados / propuestos en C # / Java (8), ¿probablemente esté relacionado con preocupaciones sobre la compatibilidad con versiones anteriores?
Respuestas:
Creo que la discusión sobre objetos versus funciones es una pista falsa. Si la pregunta es: "¿Es una lambda una función o un objeto?" La respuesta debería ser sí .
Ese es el punto de las funciones de primera clase: no se tratan de manera diferente que cualquier otro tipo. Java ya se las arregla para ignorar principalmente las diferencias entre los objetos y los tipos primitivos (y Scala lo hace aún mejor), por lo que si una lambda es una subclase de Object o es un nuevo tipo primitivo o algo más no es realmente importante para el lenguaje. Lo importante es que puede poner sus lambdas en colecciones, pasarlas para que las llamen, llamarlas y hacer cualquier otra cosa que desee hacer con un objeto o un método.
Scala logra esto mediante el uso de un objeto contenedor que tiene un método llamado
apply
que se puede invocar con solo()
, haciendo que se vea como una llamada a un método. Esto funciona espléndidamente; la mayor parte del tiempo no necesita preocuparse si tiene un método o si está llamando a la aplicación de un objeto de función.fuente
Por lo que entiendo, se trata más de cómo se consideran las lambdas en el nivel de idioma primario. Como dice el correo electrónico,
Creo que eso resume muy bien tu pregunta. Si declaras que "las lambdas son objetos", entonces son solo un objeto de una clase en particular y estás atascado con eso. Por otro lado, si declaras "lambdas son funciones", semánticamente tienes un campo de juego mucho más rico. Java 1.7 podría compilarlos en objetos, por lo que son prácticamente idénticos en ese punto.
Pero Java 1.8, o 1.9, podría traer cambios en el lenguaje (como los tipos estructurales reificados) que permitan que las funciones se usen de maneras mucho más flexibles. Si las "lambdas fueran objetos", estos cambios no serían compatibles con versiones anteriores y tendrías que introducir un nuevo concepto por completo, para no romper el código existente de las personas. Pero si
javac
solo estaba convirtiendo silenciosamente lambdas en objetos detrás de escena, el nuevojavac
puede convertirlos a lo que quiera, siempre que la semántica siga vigente.fuente
foreach
,map
,filter
a las colecciones.Sobre todo, él simplemente no quiere comprometerse demasiado pronto con algo. No veo ninguna razón más allá del borrado que presentó, pero esa es una razón muy fuerte.
Considere estos métodos en Scala
Regex
:Sería más simple si fueran simplemente esto:
Desafortunadamente, eso no es posible, porque esas dos funciones son idénticas bajo borrado. Pero, bueno, estas funciones hacen cosas algo diferentes, por lo que un nombre diferente podría ser lo suficientemente justo.
Sin embargo, a
Match
es algo muy útil, pero la mayoría de las veces desea que coincidanString
o la lista de subgrupos. Nos gustaría tener esto:No es posible, debido a la eliminación. Elegí este ejemplo en particular porque estaba directamente involucrado en él, pero he visto al menos media docena de preguntas sobre Stack Overflow, donde la gente pregunta por qué una sobrecarga es ilegal, causada por este problema exacto.
Y, luego, considere que la coincidencia de patrones de Scala y Java
instanceof
son efectivamente inútiles debido a la eliminación.Creo que es justo retrasar los tipos de funciones hasta que se aborde este problema. Después de todo, hay muchos lenguajes que lo tienen en la JVM, y no es que Java sea un lenguaje que evoluciona rápidamente.
fuente