3 votos

¿Por qué no importa que Null no sea seguro para los que les gusta la seguridad tipográfica?

No estoy muy interesado en la seguridad de tipos como concepto, pero muchos la consideran importante para un código bien escrito y piensan que para algunos de los factores más importantes como para que el código escale bien, sea reutilizable, sea robusto, etc... tiene que ser seguro de tipos.

Los lenguajes como C# se toman en serio la seguridad de tipos, están tipados estáticamente y los genéricos en C# son considerablemente más seguros que las plantillas de C++. Incluso ArrayList que se considera no tan seguro como List<> siendo que es un List<object> es mucho más seguro que, por ejemplo, un List<dynamic> que creo que debería ser posible, pero que es ciertamente oscuro.

Sin embargo, me pregunto, usando de nuevo C# como ejemplo, por qué sigue habiendo null . Me gusta y apruebo null pero no está en consonancia con la seguridad tipográfica del resto del lenguaje.

Tal vez en algunos aspectos 'null' mejora el rendimiento evitando que todo tenga que ser construido por defecto, pero también requiere una comprobación extra en tiempo de ejecución para que el ordenador lance excepciones null y demás.

String s = null;
int n = s.Length; // error like a type error, even if technically it isn't

9voto

Eric Lippert Puntos 300275

No me gusta mucho la seguridad de tipos como concepto

Tal vez deberías estarlo.

para que el código escale bien, sea reutilizable, sea robusto, etc... tiene que ser de tipo seguro.

No creo que necesita para estar seguro del tipo, aunque seguro que ayuda. Mucha gente escribe código en C++, un lenguaje que tiene una seguridad de tipo relativamente débil (porque los punteros se pueden convertir a y desde enteros arbitrarios). Sin embargo, C++ también es un lenguaje que ha sido diseñado para fomentar la reutilización del código a través de código robusto encapsulado en clases.

Además, no hay que confundir la comprobación de tipos estática con la seguridad de tipos. Algunos argumentarían que los lenguajes con comprobación dinámica son igual de "seguros en cuanto a tipos"; simplemente hacen sus verificaciones del sistema de tipos en tiempo de ejecución en lugar de en tiempo de compilación.

Lenguajes como C# se toman en serio la seguridad de tipos

Sí, es cierto.

Los genéricos en C# son considerablemente más seguros que las plantillas de C++.

No veo ninguna prueba de esta afirmación. La comprobación de tipos en los genéricos es diferente a la comprobación de tipos en las plantillas, pero ambas son comprobadas. La diferencia fundamental es que un genérico asume que cualquier que cumple con las restricciones podría ser el argumento de tipo y, por lo tanto, requiere que el programa pase una comprobación de tipo estática para cualquier posible argumento de tipo. Por otro lado, las plantillas sólo requieren los argumentos de tipo que realmente se utiliza para pasar la comprobación de tipos estáticos.

Incluso ArrayList, que se considera que no es tan seguro como List<T> siendo que es un List<object> es mucho más seguro que, por ejemplo, un List<dynamic> que creo que debería ser posible, pero es ciertamente oscuro.

Bueno, la dinámica es un caso interesante. Como dije antes, dinámico significa básicamente "trasladar la comprobación de tipos de esta cosa al tiempo de ejecución".

Me pregunto por qué, de nuevo usando C# como ejemplo sigue habiendo null. Puedo ver cómo en algunos aspectos es más rápido que asegurar que todo se construye por defecto, pero no es un gran problema de seguridad de tipos

Tienes razón al plantear esta preocupación; los nulos plantean un problema difícil al verificador de tipos. A uno le gustaría que un lenguaje de tipado estático fuera "seguro en memoria" - para asegurar que ningún patrón de bits inválido se abra paso en una variable anotada con un tipo particular. C# (fuera del subconjunto inseguro) logra este objetivo excepto que el patrón de bits de referencia nula siempre es legal en una variable anotada con un tipo de referencia, aunque ese patrón de bits no se refiera a ningún objeto válido.

Ciertamente, se pueden encontrar lenguajes que no tengan referencias nulas y que sean comprobados estáticamente; Haskell es un buen ejemplo. ¿Por qué no hacer lo mismo en C#?

Razones históricas. Las referencias nulas son muy útiles, a pesar de sus peligros, y C# proviene de una larga tradición de lenguajes de programación que permiten las referencias nulas.

Personalmente, habría preferido que hubiéramos incorporado la anulabilidad en el marco de trabajo desde el primer día, de modo que se pudieran tener tipos de valor anulables o no anulables, y tipos de referencia anulables o no anulables. Recuerda esto la próxima vez que diseñes un sistema de tipos desde cero.

También requiere una comprobación extra en tiempo de ejecución para que el ordenador lance excepciones nulas y demás

En realidad no es tan malo. La forma en que estas cosas se implementan normalmente es que la página de memoria virtual que contiene el puntero nulo se marca como no legible, escribible o ejecutable. Un intento de hacerlo resulta entonces en una excepción lanzada por el hardware. E incluso en los casos en los que hay que hacer una comprobación de nulos, comparar un registro a cero es bastante rápido.

Hay problemas peores. Por ejemplo, los arrays tampoco son "seguros" en el sentido de que no se puede comprobar estáticamente si un programa está garantizado para acceder sólo a los índices válidos de un Array. El CLR hace mucho trabajo para asegurarse de que cada acceso a un Array es válido.

La covarianza insegura de los arrays también es problemática; es un problema de buena fe del sistema de tipos. Tenemos que hacer comprobaciones de tipo cada vez que se escribe un elemento de un tipo más derivado a un Array de su tipo base. Este es mi candidato a "peor característica" del CLR.

4voto

Lucero Puntos 38928

NULL significa que no hay instancia, nada. Como tal, no puede tener un tipo, y por lo tanto no se pueden comprobar los tipos en NULL.

La necesidad de NULL viene con las referencias: al menos durante la creación de objetos con referencias, éstas tendrán que apuntar a "nada". Y NULL hace precisamente eso.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X