php - tipado - ¿cuál es la definición de lenguaje débil?
¿Cuáles son los beneficios(y desventajas) de un lenguaje débilmente tipado? (7)
Débil y fuerte son términos cargados. (¿Quieres ser un programador de lenguaje débil?) Dinámico y estático son mejores, pero me imagino que la mayoría de las personas preferiría ser un programador dinámico que uno estático. Llamaría a PHP un lenguaje promiscuo (no es un término cargado;))
PHP:
garbage_out = garbage_in * 3; // garbage_in was not initialized yet
"hello world" + 2; // does this make sense?
Permitir variables no inicializadas crea errores muy difíciles de encontrar a partir de errores ortográficos. Permitir operaciones en tipos no relacionados es casi siempre un error que debe ser reportado. La mayoría de los lenguajes dinámicos interpretados no permiten estas cosas por una buena razón. Puede tener un lenguaje escrito dinámicamente sin permitir basura.
Soy un gran admirador de PHP y obviamente es un lenguaje muy débilmente tipado. Me doy cuenta de que algunos de los beneficios incluyen la independencia general de cambiar los tipos de variables sobre la marcha y tal.
Lo que me pregunto son los inconvenientes. ¿Qué se puede sacar de un lenguaje fuertemente tipado como C que de otro modo no se puede obtener de un tipo débilmente tipado como PHP? También con la configuración de tipo (como double ($ variable)), se podría argumentar que incluso un lenguaje débilmente tipado puede actuar igual que uno fuertemente tipado.
Asi que. Débil-tipo. ¿Cuáles son algunos beneficios que no incluí? Más importante aún, ¿cuáles son los inconvenientes?
Directamente desde wikipedia:
La ventaja que se reclama de la tipificación débil es que requiere menos esfuerzo por parte del programador que una mecanografía fuerte, porque el compilador o intérprete realiza implícitamente ciertos tipos de conversiones. Sin embargo, una de las desventajas alegadas es que los sistemas de programación de tipo débil capturan menos errores en el momento de la compilación y algunos de ellos podrían permanecer después de que se completó la prueba.
Eso es más o menos lo mismo que diría. Sin embargo, tenga cuidado con la relativa ambigüedad de estos términos ("tipado fuerte" y "tipado débil") ya que las conversiones implícitas desdibujan la línea.
La ventaja citada del tipado estático es que hay clases enteras de errores capturados en tiempo de compilación, que no pueden alcanzar el tiempo de ejecución. Por ejemplo, si tiene una clase o interfaz estáticamente estátizada como parámetro de función, entonces no va a pasar accidentalmente un objeto del tipo incorrecto (es decir, sin un molde explícito e incorrecto).
Por supuesto, esto no evita que pases el objeto incorrecto del tipo correcto o una implementación de una interfaz en la que le hayas dado las funciones correctas, pero hacen las cosas incorrectas. Además, si tiene una cobertura de código del 100%, diga la gente de PHP / Python / etc, ¿a quién le importa si detecta el error en tiempo de compilación o en tiempo de ejecución?
Personalmente, he tenido momentos divertidos en idiomas con tipeo estático y momentos divertidos en idiomas sin. Rara vez es el tema decisivo, ya que nunca he tenido que elegir entre dos idiomas idénticos que no sean el tipo de tipeo y normalmente hay cosas más importantes de las que preocuparse. Encuentro que cuando uso lenguajes tipados estáticos deliberadamente "me apoyo en el compilador", tratando de escribir código de tal manera que, si está mal, no compila. Por ejemplo, hay ciertos refactores que puede realizar haciendo un cambio en un lugar, y luego arreglando todos los errores de compilación que resultan, repita hasta la compilación limpia. Hacer lo mismo ejecutando un conjunto de pruebas completo varias veces puede no ser muy práctico. Pero no es inaudito que los IDE automaticen los mismos refactores en otros idiomas, o que las pruebas se completen rápidamente, por lo que se trata de lo que es conveniente, no lo que es posible.
Las personas que tienen una preocupación legítima más allá de la conveniencia y la preferencia de estilo de codificación son las que trabajan en pruebas formales de la corrección del código. Mi impresión ignorante es que la deducción de tipo estático puede hacer la mayoría (pero no la totalidad) del trabajo que hace el tipado estático explícito, y ahorra un desgaste considerable en el teclado. Entonces, si el tipado estático obliga a las personas a escribir código de una manera que lo haga más fácil de probar, entonces podría haber algo de ese punto de vista. Digo "si": no lo sé, y no es como si la mayoría de las personas probaran su código de tipo estático de todos modos.
cambiar los tipos de variables sobre la marcha y tal
Creo que tiene un valor dudoso. Siempre es muy tentador hacer algo como (Python / Django):
user = request.GET[''username'']
# do something with the string variable, "user"
user = get_object_or_404(User,user)
# do something with the User object variable, "user"
Pero realmente, ¿se debería usar el mismo nombre para diferentes cosas dentro de una función? Tal vez. Probablemente no. La "reutilización", por ejemplo, las variables enteras para otras cosas en los lenguajes tipados estáticamente tampoco se fomenta masivamente. El deseo de no tener que pensar en nombres de variables descriptivos y concisos, probablemente el 95% de las veces no debe anular el deseo de un código inequívoco ...
Por cierto, usualmente tipear débil significa que ocurren conversiones de tipo implícitas, y una tipificación fuerte significa que no. Según esta definición, C está débilmente tipado en lo que respecta a los tipos aritméticos, así que supongo que eso no es lo que quieres decir. Creo que se considera ampliamente que la tipificación completa es más una molestia que una ayuda, y que la "mecanografía completa y débil" (cualquier cosa se puede convertir a cualquier otra cosa) no tiene sentido en la mayoría de los idiomas. Entonces, la pregunta sobre cuántas conversiones implícitas se pueden tolerar antes de que se vuelva demasiado difícil de descifrar. Ver también, en C ++, la dificultad actual para decidir si implementar operadores de conversión y constructores no explícitos de una arg.
Se ha escrito mucho sobre este tipo de cosas. Hay una compensación inherente; con un lenguaje débilmente tipado, muchas molestias simplemente dejan de serlo. Por ejemplo, en Python, nunca tendrá que preocuparse por dividir un float
por un int
; agregar un argumentos de las funciones de tipeo (¿sabías que OCaml tiene operadores especiales para agregar int
a una list
;float
porque (+)
envía int
s a int
s!); olvidando que una variable puede ser nula ... ese tipo de problemas simplemente desaparecen.
En su lugar vienen toda una serie de nuevos errores de tiempo de ejecución: Python''s [0]*5
da, ¡aguarde, [0,0,0,0,0]
! OCaml, a pesar de la molestia de la tipificación fuerte, atrapa muchos errores con su compilador; y esta es precisamente la razón por la cual es bueno. Es una compensación.
Consulte esta tabla , que muestra los resultados del operador PHP ==
aplicado a pares de valores principales vacíos u otros de varios tipos, como 0
, "0"
, NULL
y ""
. El operador no es conmutativo, y la tabla es bastante intuitiva, por decir lo menos. (No es que tenga mucho sentido preguntar si una cadena es igual a una matriz, para ser justos, pero puedes hacerlo en un lenguaje débilmente tipado, que es la trampa, y puede que Turing te ayude si el lenguaje intenta hacerlo " ayudarte.)
Debe comprender que PHP fue creado para el contexto de las aplicaciones web. Todo en el contexto de la web es una cadena. Por lo tanto, es muy raro que una tipificación fuerte sea beneficiosa.
He estado usando tanto lenguaje fuertemente tipado (como Java) como de tipo débil (como JavaScript) desde hace algún tiempo. Lo que he encontrado es que la conveniencia de los idiomas de tipo débil es excelente para aplicaciones pequeñas. Desafortunadamente, a medida que la aplicación aumenta de tamaño, se vuelve imposible de administrar. Se vuelve demasiado para realizar un seguimiento en su cabeza y tiene que empezar a depender de su IDE y el compilador cada vez más o su codificación se detiene. Es entonces cuando los lenguajes fuertes de tipo mecanografiado comienzan a ser más útiles, con la aplicación crece mucho.
Dos ejemplos que constantemente me vuelven loco en el JavaScript de tipo débil están utilizando bibliotecas externas que no están completamente documentadas y refactorizadas.
Bibliotecas externas: cuando se trata de un lenguaje fuertemente tipado, el código de la propia biblioteca proporciona auto-documentación. Cuando creo una variable de tipo Persona, el IDE puede inspeccionar el código y decir que hay un getFirstName (), getLastName () y getFullName (). En los lenguajes de tipo débil, este no es el caso ya que una variable puede ser cualquier cosa, tener cualquier tipo de variable o función y tener argumentos de función que también podrían ser cualquier cosa (no están definidos explícitamente). Como resultado, un desarrollador tiene que apoyarse mucho en la documentación, búsquedas en la web, foros de discusión y su memoria de usos pasados. Creo que puede llevar horas buscar cosas en JavaScript para bibliotecas externas, mientras que con Java, simplemente presiono el "." clave y aparece todas mis opciones con la documentación adjunta. Cuando encuentre bibliotecas que no estén completamente documentadas al 100%, puede ser muy frustrante con los lenguajes de tipo débil. Recientemente me encontré preguntando "¿Qué es argumento ''argumento'' en la función ''dibujar''?" cuando se utiliza jqplot, una biblioteca de JavaScript bastante bien pero no completamente documentada. Tuve que pasar una o dos horas investigando el código fuente antes de finalmente darme por vencido y encontrar una solución alternativa.
Refactorización: con los lenguajes fuertemente tipados, me puedo refactorizar rápidamente simplemente cambiando el archivo que necesito cambiar y luego solucionando los errores del compilador. Algunas herramientas incluso se refactorizarán con un simple clic de un botón. Con los idiomas de tipo débil, debe hacer una búsqueda y luego reemplazar con cuidado y luego probar, probar, PRUEBA y luego probar un poco más. Raramente está completamente seguro de haber encontrado y arreglado todo lo que rompió, especialmente en aplicaciones grandes.
Para necesidades simples y aplicaciones pequeñas, estas dos preocupaciones son mínimas o inexistentes. Pero si está trabajando con una aplicación con cientos de miles o millones de líneas de código, los lenguajes de tipos débiles lo volverán loco.
Creo que muchos desarrolladores se molestan por esto y lo convierten en una discusión emocional porque a veces nos damos cuenta de que hay un enfoque correcto y otro incorrecto. Pero cada enfoque tiene sus méritos: sus propias ventajas y desventajas. Una vez que reconozca que deja de lado la emoción y elija la mejor para usted para lo que necesita en este momento.