scala - son - paradigmas programacion
¿Cuáles son las principales diferencias entre Scala y Frege(en los paradigmas de programación)? (3)
Además de los problemas sintácticos, la mayor diferencia está en el sistema de tipos y el modelo de ejecución.
Como @senia ya señaló, scala es estricto y no puro, lo que no significa que no pueda escribir funciones puras (también puede hacerlo en C), solo que el compilador no las impondrá.
Frege, OTOH es vago y puro, lo que significa que todos los efectos impuros se ven obligados a vivir en la mónada ST o IO. El sistema de tipos es esencial en Haskell 2010, con clases de tipos y tipos de funciones de rango superior adicionales. La inferencia de tipos funciona en todo el programa, la única excepción son las funciones con tipos de rango más alto, donde al menos el argumento polimórfico debe ser anotado. Aquí hay un ejemplo:
both f xs ys = (f xs, f ys)
Para esta función, el compilador infiere el tipo:
both :: (α->β) -> α -> α -> (β, β)
Tenga en cuenta que tanto xs
como ys
obtienen el mismo tipo, debido a la aplicación de f
. Pero ahora digamos que queremos usar una función de lista polimórfica que podamos usar con xs e ys de tipos diferentes. Por ejemplo, queremos escribir:
both reverse [1,2,3] [''a'' .. ''z'']
Tal como está, esta aplicación sería un error, porque las dos listas tienen diferentes tipos de elementos y, por lo tanto, diferentes tipos. Entonces el compilador rechazaría la lista de caracteres.
Afortunadamente, podemos decirle al compilador más exactamente lo que queremos con una anotación de tipo:
both :: (forall e.[e] -> [e]) -> [a] -> [b] -> ([a], [b])
Esto dice lo siguiente: pasaremos a una función que realiza alguna transformación de lista pero no le importa el tipo de elemento de lista. Luego pasamos 2 listas con posiblemente diferentes tipos de elementos. Y recibimos una tupla con nuestras listas transformadas de vuelta. Tenga en cuenta que el código de both
no necesita ser cambiado.
Otra forma de lograr lo mismo sería escribir:
both (f :: forall e.[e]->[e]) xs ys = (f xs, f ys)
y el comprobador de tipos deduce el resto, es decir, que xs
y ys
deben ser listas, pero pueden tener diferentes tipos de elementos.
El sistema de tipo Scalas totalmente (que yo sepa) es compatible con OO. Si bien Frege lo admite solo parcialmente con respecto a los tipos importados para Java, pero no admite la definición de los propios tipos similares a OO.
Por lo tanto, ambos lenguajes admiten programación funcional en un entorno JVM, aunque en nichos completamente diferentes. Un tercer nicho es el tipeado dinámicamente, donde Clojure es el rey en el mundo de JVM.
Scala y Frege son lenguajes funcionales escritos que apuntan a JVM.
Frege está más cerca de Haskell, Scala tiene una historia más independiente.
Pero si no observamos las diferencias sintácticas, ¿cuáles son las diferencias en las técnicas, estilos y conceptos de programación permitidos entre los dos?
En mi humilde opinión, los dos idiomas son realmente buenos, pero con respecto a los paradigmas, Scala hace OO mejor que Frege, pero Frege funciona mejor que Scala. Con respecto a las diferencias, todo se reduce a Haskell vs Scala, ya que Frege es (o casi, ve las diferencias entre Haskell y Frege here ) Haskell para la JVM.
La inferencia de tipos de Frege es global, por lo que no tenemos que anotar tipos tan a menudo como lo hacemos en Scala (inferencia local).
En Frege, los módulos son solo espacios de nombres para tipos y funciones, mientras que Scala tiene un mejor sistema de módulos. http://2013.flatmap.no/spiewak.html
En Frege, las funciones se actualizan de forma predeterminada, por lo que no hay necesidad de construcciones adicionales para la aplicación de la función parcial. Lo mismo aplica para la aplicación de constructor de tipo parcial.
En Frege, no hay
def
vsval
y todo es función. Por lo tanto, las funciones son más de primera clase que Scala.Frege no tiene subtitulación, pero el sistema de tipos resuelve el subtipo en las llamadas nativas. Por ejemplo, puede pasar un
ArrayList
a una función que requiere unaList
Java.Como no hay subtipado, en Frege no podemos extender una clase Java o implementar una interfaz a partir de ahora (podría ser compatible en el futuro), así que necesitamos tener una clase Java que se extienda / implemente, pero las implementaciones del método se aprobarán desde Frege. como funciones.
Desde Scala, es fácil llamar a Java, pero en Frege, se debe declarar una clase / método Java (solo el tipo y las anotaciones de pureza) antes de su uso. Por ejemplo, para usar
LinkedList
de Java,data LinkedList a = native java.util.LinkedList where native add :: Mutable s (LinkedList a) -> a -> ST s Bool native get :: Mutable s (LinkedList a) -> Int -> ST s (Maybe a) throws IndexOutOfBoundsException native new :: () -> STMutable s (LinkedList a)
Aquí, ya que las funciones mutan el objeto, deben estar en la mónada
ST
. También tenga en cuenta que aquí Frege también maneja elnull
devuelto desde el métodoget
, ya que está anotado con el tipoMaybe
. La única forma en quenull
puede acceder a su programa Frege es a través de la interfaz nativa, ya que Frege no tiene noción de nulo.Otro ejemplo:
pure native floor Math.floor :: Double -> Double
que indica que la función es pura y, por lo tanto, la firma refleja directamente la firma original de Java sin
IO
oST
.Frege no tiene variables como en la
var
de Scala y los efectos secundarios son más explícitos a través de los tipos. (Solonull
, novar
y efectos secundarios explícitos hacen que Frege sea más interesante, al menos para mí. En cierto sentido, Frege, al igual que Haskell, es un "lenguaje de programación imperativo" para la JVM).Al ser un dialecto de Haskell, Frege es más natural para los Functors, Applicatives, Monads y otros "patrones" funcionales y tiene esos en su biblioteca estándar, mientras que en Scala, es posible que necesite Scalaz.
Frege es perezoso por defecto, pero se puede activar el rigor cuando sea necesario a través de
!
mientras que Scala es estricto por defecto, pero tiene la palabra clave perezosa para la evaluación perezosa.
Sin embargo, al ser lenguajes JVM, un idioma puede beneficiarse de otro. Una vez porté un ejemplo de Akka a Frege . Al final, todo se reduce a la rigurosidad, la pureza, la funcionalidad, la OO y la inferencia de tipos y lo importante que es para usted.
Tal vez está fuera del tema, pero Scala se puede usar para desarrollar aplicaciones de Android (*), pero Frege no se ha usado con éxito para eso. (**) IIRC, es porque la interoperabilidad con bibliotecas Java existentes es mucho más fácil en Scala que en Frege, entre otros temas.
(*) Caveat Emptor. Solo he hecho pequeños programas de ejemplo yo mismo.
(**) Las mezclas de Frege / Java se han usado para aplicaciones de Android, pero las aplicaciones de solo Frege todavía no están disponibles, AFAIK.