En informática , un sistema de tipos es nominal (también llamado nominativo o basado en nombres ) si la compatibilidad y equivalencia de los tipos de datos está determinada por declaraciones explícitas y/o el nombre de los tipos. Los sistemas nominales se utilizan para determinar si los tipos son equivalentes, así como si un tipo es un subtipo de otro. Los sistemas de tipos nominales contrastan con los sistemas estructurales , donde las comparaciones se basan en la estructura de los tipos en cuestión y no requieren declaraciones explícitas.
La tipificación nominal significa que dos variables son compatibles con el tipo si y solo si sus declaraciones nombran el mismo tipo. Por ejemplo, en C , dos struct
tipos con nombres diferentes en la misma unidad de traducción nunca se consideran compatibles, incluso si tienen declaraciones de campo idénticas.
Sin embargo, C también permite una typedef
declaración que introduce un alias para un tipo existente. Estos son meramente sintácticos y no diferencian el tipo de su alias a efectos de verificación de tipos. Esta característica, presente en muchos lenguajes, puede resultar en una pérdida de seguridad de tipos cuando (por ejemplo) el mismo tipo entero primitivo se usa de dos maneras semánticamente distintas. Haskell proporciona el alias sintáctico de estilo C en forma de type
declaración, así como la newtype
declaración que introduce un tipo nuevo, distinto, isomorfo a un tipo existente. [1]
De manera similar, el subtipo nominal significa que un tipo es un subtipo de otro si y sólo si se declara explícitamente que lo es en su definición. Los lenguajes de tipo nominal generalmente imponen el requisito de que los subtipos declarados sean estructuralmente compatibles (aunque Eiffel permite que se declaren subtipos no compatibles). Sin embargo, los subtipos que son estructuralmente compatibles "por accidente", pero no declarados como subtipos, no se consideran subtipos.
C++ , C# , Java , Kotlin , Objective-C , Delphi , Swift , Julia y Rust utilizan principalmente tipificación nominal y subtipificación nominal.
Algunos lenguajes con subtipos nominales, como Java y C#, permiten que las clases se declaren finales (o se sellen en terminología de C#), lo que indica que no se permiten más subtipos.
La escritura nominal es útil para prevenir la equivalencia de tipos accidental, lo que permite una mayor seguridad de escritura que la escritura estructural. El coste es una flexibilidad reducida, ya que, por ejemplo, la tipificación nominal no permite crear nuevos supertipos sin modificar los subtipos existentes.