Este reclamo de Aleks Bromfield afirma:
Casi todos los idiomas con un sistema de tipo estático también tienen un sistema de tipo dinámico. Aparte de C, no puedo pensar en una excepción
¿Es este un reclamo válido? Entiendo que con las clases Reflection o Loading en tiempo de ejecución Java se vuelve un poco así, pero ¿puede esta idea de 'tipeo gradual' extenderse a una gran cantidad de idiomas?
languages
dynamic-typing
static-typing
ojo de halcón
fuente
fuente
Respuestas:
Tweeter original aquí. :)
En primer lugar, ¡estoy algo divertido / sorprendido de que mi tweet se tome tan en serio! Si hubiera sabido que iba a ser tan ampliamente difundido, ¡habría pasado más de 30 segundos escribiéndolo!
Thiago Silva tiene razón al señalar que "estático" y "dinámico" describen con mayor precisión la verificación de tipos , en lugar de los sistemas de tipos . De hecho, tampoco es realmente exacto decir que un idioma está tipeado estática o dinámicamente. Por el contrario, un lenguaje tiene un sistema de tipos, y una implementación de ese lenguaje podría imponer el sistema de tipos mediante la verificación estática, o la verificación dinámica, o ambas, o ninguna (¡aunque eso no sería una implementación de lenguaje muy atractiva!).
Como sucede, hay ciertos sistemas de tipos (o características de los sistemas de tipos) que son más susceptibles a la verificación estática, y hay ciertos sistemas de tipos (o características de los sistemas de tipos) que son más susceptibles a la verificación dinámica. Por ejemplo, si su idioma le permite especificar en el texto de un programa que un valor particular siempre debe ser una matriz de enteros, entonces es razonablemente sencillo escribir un verificador estático para verificar esa propiedad. Por el contrario, si su idioma tiene subtipos, y si permite el downcasting, entonces es razonablemente sencillo verificar la validez de un downcast en tiempo de ejecución, pero es extremadamente difícil hacerlo en tiempo de compilación.
Lo que realmente quise decir con mi tweet es simplemente que la gran mayoría de las implementaciones de lenguaje realizan una cierta cantidad de verificación de tipo dinámico. O, de manera equivalente, la gran mayoría de los idiomas tienen algunas características que son difíciles (si no imposibles) de verificar estáticamente. Downcasting es un ejemplo. Otros ejemplos incluyen desbordamiento aritmético, verificación de límites de matriz y verificación nula. Algunos de estos pueden verificarse estáticamente en algunas circunstancias, pero en general, sería difícil encontrar una implementación de lenguaje que no haga ninguna verificación en tiempo de ejecución.
Esto no es algo malo. Es solo una observación de que hay muchas propiedades interesantes que nos gustaría que nuestros idiomas aplicaran, y que realmente no sabemos cómo verificar estáticamente. Y es un recordatorio de que las distinciones como "tipos estáticos" versus "tipos dinámicos" no son tan claras como algunas personas quisieran hacer creer. :)
Una nota final: los términos "fuerte" y "débil" no se usan realmente en la comunidad de investigación del lenguaje de programación, y realmente no tienen un significado consistente. En general, descubrí que cuando alguien dice que un idioma tiene "mecanografía fuerte" y otro idioma tiene "mecanografía débil", realmente está diciendo que su idioma favorito (el que tiene "mecanografía fuerte") les impide cometiendo un error que el otro idioma (el que tiene "mecanografía débil") no lo hace, o por el contrario, que su idioma favorito (el que tiene "mecanografía débil") les permite hacer algo interesante que el otro idioma (el uno con "mecanografía fuerte") no.
fuente
Bueno, sí. Puede tener bolsas de propiedades en cualquier idioma estáticamente escrito. La sintaxis será terrible, mientras que al mismo tiempo obtendrá todas las desventajas del sistema de tipo dinámico. Por lo tanto, no hay realmente ninguna ventaja a menos que el compilador le permita usar una sintaxis más agradable, algo como lo
dynamic
está haciendo C # con .Además, puedes hacer eso fácilmente en C también.
En reacción a otras respuestas: creo que la gente está confundiendo la escritura estática / dinámica con la escritura fuerte / débil. La escritura dinámica se trata de poder cambiar la estructura de los datos en tiempo de ejecución y el código puede utilizar datos que se ajusten a lo que el código necesita. Esto se llama Duck Typing .
Mencionar la reflexión no es contar toda la historia, porque la reflexión no le permite cambiar la estructura de datos existente. No puede agregar un nuevo campo a una clase o estructura en C, C ++, Java o C #. En lenguajes dinámicos, agregar nuevos campos o atributos a las clases existentes no solo es posible, sino que es bastante común.
Por ejemplo, mire Cython , el compilador Python-to-C. Crea código C estático, pero el sistema de tipos aún conserva su naturaleza dinámica. C es un lenguaje estáticamente escrito, pero puede admitir la escritura dinámica desde Python.
fuente
ExpandoObject
, aunque es en gran medida un proceso de suscripción, muy diferente a JavaScript o Ruby. Aún así, ha hecho un punto muy importante, que es que la escritura de pato (lo que el 99% de los desarrolladores realmente quieren decir cuando dicen "escrito dinámicamente") y la reflexión no son las mismas cosas.True
para decir "este objeto loco es una instancia de la clase que estoy definiendo"). OCaml tiene esta característica por lo que yo entiendo, pero realmente no lo sé.Los lenguajes dinámicos son lenguajes estáticos . Lo que comúnmente se llama "escritura dinámica" es realmente un caso especial de escritura estática, el caso en el que se ha limitado a tener solo un tipo. Como experimento mental, imagine escribir un programa en Java o C # usando solo
Object
variables / campos / parámetros y descargando inmediatamente antes de llamar a cualquier método. Sería más preciso llamar a lenguajes como Python o Javascript "unitped". (Esta afirmación probablemente confundirá / molestará a muchas personas, teniendo en cuenta que dicho programa Java o C # usaría muchos subtipos, pero eso se debe a que el lenguaje OOP promedio combina tipos y clases. Lea la publicación del blog para obtener más detalles).Tenga en cuenta que incluso C tiene una escritura "dinámica": puede lanzar cualquier puntero a un puntero
void
(y si la memoria me sirvechar
) y viceversa. Y tenga en cuenta, también, que no hay tiempo de ejecución comprobando allí; Si te equivocas, ¡disfruta de tu comportamiento indefinido!fuente
String foo = (String) bar
que no significa quebar
de hecho es aString
. Solo puede saberlo con seguridad en el tiempo de ejecución, por lo que no veo cómo se realiza el reparto "estáticamente".dynamic
objeto para hacer esto. Si intenta agregar una propiedad a unobject
... bueno, no puede.La diferencia entre la tipificación estática y dinámica es cuando se marca el tipo de un valor: tiempo de compilación versus tiempo de ejecución. En los lenguajes donde los valores llevan su tipo con ellos (por ejemplo, objetos Java), siempre puede recurrir a la escritura dinámica, incluso cuando el idioma realmente prefiere la escritura estática. Aquí hay un ejemplo en Java, con un método de tipo dinámico:
Observe cómo se verifica el tipo de cada elemento en tiempo de ejecución. El método equivalente de tipo estático es:
En C, los valores (y específicamente los punteros) no retienen su tipo durante el tiempo de ejecución; cada puntero es equivalente a a
void *
. En cambio, las variables y las expresiones tienen un tipo. Para lograr una escritura dinámica, debe llevar la información de tipo usted mismo (por ejemplo, como un campo en una estructura).fuente
frobnicate
método aquí sin antes saberloSpecificType
.dynamic
palabra clave). Igualar estático a tiempo de compilación y dinámico a tiempo de ejecución en su mayoría simplemente enturbia las aguas.[1,2].Add([3,4])
ceder[1,2,3,4]
,[1,2,[3,4]]
o[4,6]
?Add
método en la matriz que acepte una matriz porque dicho método sería ambiguo. La escritura de pato no te excusa de escribir tipos y funciones comprensibles.La escritura estática vs. dinámica básicamente se refiere a cómo se verifican los tipos. La tipificación estática significa que la verificación de los tipos de diversas variables o expresiones se verifica en función del código real (generalmente por el compilador) mientras que en un sistema de tipo dinámico esta verificación se realiza solo en tiempo de ejecución, por el entorno de tiempo de ejecución.
Lo que creo que se refiere el texto es que incluso si los tipos se verifican estáticamente, también se verifican en tiempo de ejecución, es decir, dinámicamente. Usted mencionó correctamente Java Reflection; la reflexión solo ocurre en tiempo de ejecución y el Java Runtime Environment (JVM) realmente realiza la verificación de tipos cuando se usa la reflexión, lo que básicamente significa la verificación dinámica de tipos.
fuente
La excitación es incorrecta: C también tiene un importante sistema de tipo dinámico. Simplemente no lo marca ("C está fuertemente tipado, débilmente marcado"). Por ejemplo, tratar una estructura como un
double
(reinternpret_cast
estilo) genera un comportamiento indefinido, un error de tipo dinámico.fuente