tag name icon description application types type-inference julia-lang julia

types - name - ¿Se escribe Julia dinámicamente?



meta tags list html (4)

Ambas son ciertas. Julia se escribe dinámicamente, pero en un código julia bien escrito, los tipos generalmente se pueden inferir. A menudo obtienes una mejora importante en el rendimiento cuando eso es posible.

Hay una discusión sobre esto en las preguntas frecuentes .

Muchos blogs, y el manual en sí , dicen que Julia está escrita de forma dinámica . Pero de mi lectura del manual, me parece más como si estuviera estáticamente escrito con inferencia de tipos , como F# .

  • ¿Julia está estáticamente escrita con inferencia de tipos?
  • ¿Se escribe dinámicamente?
  • Supongo que está escrito dinámicamente, parece poco probable que el manual sea incorrecto.
  • ¿La inferencia de tipos está involucrada en Julia?

Aquí hay un extracto del libro Introducción al lenguaje de programación Julia :

También puede ser útil indicar los tipos de argumento para restringir el tipo de parámetros pasados ​​al llamar. Nuestro encabezado de función para números de coma flotante se vería como la función mult (x :: Float64, y :: Float64). Cuando llamamos a esta función con mult (5, 6), recibimos un error, ERROR: ''mult'' no tiene ningún método que coincida con mult (:: Int64, :: Int64), lo que demuestra que Julia es realmente un lenguaje fuertemente tipado. No acepta parámetros enteros para los argumentos de coma flotante.

Esta es la función de ejemplo en el libro:

function mult(x::Float64, y::Float64) x * y end mult(5, 6) # raises an error mult(5.0, 6.0) # => 30.0

No estoy seguro de si el libro es correcto, pero contradice todas las otras respuestas.


La respuesta de Tim Holy es bastante correcta, pero elaboraré un poco. Primero, definamos algunos términos: puede estar en desacuerdo con mis definiciones, pero al menos sabrá lo que estoy diciendo. La diferencia principal entre lenguajes estáticos y dinámicos, en mi opinión, es esta: en lenguajes estáticos, las expresiones tienen tipos; En lenguajes dinámicos, los valores tienen tipos.

En un lenguaje estático, hay reglas para determinar el tipo de cada expresión en un programa. Los tipos de expresiones dictan el comportamiento del programa. Un programa que no admite que se determine un tipo consistente para cada expresión se considera incorrecto y no se compilará. En presencia de polimorfismo, el tipo de expresión puede no ser un tipo concreto: el polimorfismo paramétrico puede considerarse como una forma de permitir que el mismo código describa una familia completa de algoritmos tipificados concretamente, indexados por los parámetros de los tipos; Se puede pensar que el polimorfismo de subtipo introduce una cantidad limitada de comportamiento dinámico en un lenguaje estático.

Los lenguajes dinámicos, por otro lado, no tienen reglas para asignar tipos a expresiones: los tipos están implícitos en la forma en que los datos fluyen a través del programa a medida que se ejecuta . En general, las expresiones pueden producir valores de cualquier tipo. Debido a esto, los teóricos de tipos a veces describen lenguajes dinámicos como "unidos", es decir, desde la perspectiva estática, donde un "tipo" es inherentemente una propiedad de una expresión, todas las expresiones en un lenguaje dinámico tienen el tipo Any . Por supuesto, eso está aplicando la noción estática de tipo, que solo es significativa para las expresiones, a un lenguaje donde la noción de tipo solo es significativa para los valores.

Julia está directamente en el campo dinámico: los tipos son una propiedad de valores, no expresiones. El tipo de código resultante está determinado por cómo los valores fluyen a través de él cuando se ejecuta; el lenguaje no incluye ninguna regla para asignar tipos a expresiones antes de ejecutarlas. Sin embargo, a diferencia de muchos lenguajes dinámicos, Julia tiene un lenguaje bastante sofisticado para hablar sobre tipos, y puede anotar expresiones con tipos. Por ejemplo, x::T es una afirmación de que x es un valor de tipo T ; si eso es cierto, x::T evalúa el valor de x , de lo contrario, se genera un error y la expresión no devuelve ningún valor. Las anotaciones de tipo en las firmas de métodos tienen un significado ligeramente diferente: en lugar de afirmar el tipo de un valor existente, indican que el método solo se aplica si el argumento correspondiente es del tipo indicado. En cualquier caso, el siguiente código puede asumir con seguridad que el valor de x es de tipo T

[Aparte: en algunos idiomas con mecanografía "gradual" u "opcional", las anotaciones de tipo cambian el idioma del modo dinámico al estático: los métodos sin anotaciones de tipo son dinámicos; Los métodos con anotaciones de tipo son estáticos. En el código estático, hay reglas para asignar tipos a todas las expresiones y el código debe satisfacerlas. Julia no funciona así: el código con anotaciones de tipo sigue siendo dinámico y tiene la misma semántica que el código sin anotaciones de tipo.]

La inferencia de tipos en lenguajes como F #, OCaml o Haskell es parte de cómo se determinan los tipos de expresiones. Si el compilador no puede inferir el tipo de ninguna expresión, su programa no funciona y no se compilará. Todos estos lenguajes usan alguna forma de inferencia de tipo Hindley-Milner, que es una forma muy inteligente de derivar los tipos de expresiones de la estructura del código sin tener que escribir tipos explícitos (compárelo con lenguajes dinámicos donde los tipos están implicados por ejecución del código). La mayoría de las veces no se requieren anotaciones de tipo, lo cual es bastante agradable en comparación con las declaraciones de tipo detallado que pueden ser necesarias en lenguajes como C ++, C # y Java. Sin embargo, esto es muy diferente de los lenguajes dinámicos como Julia y Python, donde no se requieren anotaciones de tipo simplemente porque es perfectamente aceptable que las expresiones no tengan un tipo predeterminado. En los lenguajes Hindley-Milner, es posible que no tenga que escribir tantos tipos como en C ++ o Java, pero cada expresión tiene un tipo predeterminado que el compilador puede calcular.

El compilador de Julia hace inferencia de tipos, pero es muy diferente: no es necesario que cada expresión tenga un tipo inferible. El compilador analiza el código para intentar predecir los tipos de expresiones y usa esa información para generar un código de máquina más eficiente. Pero si no puede determinar el tipo de una expresión, no es gran cosa: el compilador solo emite código genérico que funcionará de todos modos, utilizando información de tipo de tiempo de ejecución. En su mayor parte en Julia, la inferencia de tipos es solo una optimización: su código funcionará de la misma manera con o sin él, pero con una inferencia de tipos exitosa, se ejecutará mucho más rápido.


Se escribe dinámicamente, aunque si especifica un tipo como variable :: type, puede pensar que esa variable está estáticamente escrita (y esto mejorará el rendimiento en los casos en que el compilador no pueda inferir automáticamente el tipo)