En el área de la lógica matemática y la informática conocida como teoría de tipos , un tipo de unidad es un tipo que permite solo un valor (y por lo tanto no puede contener información). El portador (conjunto subyacente) asociado con un tipo de unidad puede ser cualquier conjunto único . Existe un isomorfismo entre dos conjuntos de este tipo, por lo que es habitual hablar sobre el tipo de unidad e ignorar los detalles de su valor. También se puede considerar el tipo de unidad como el tipo de tuplas 0 , es decir, el producto de ningún tipo.
El tipo de unidad es el objeto terminal en la categoría de tipos y funciones escritas. No debe confundirse con el tipo zero o bottom , que no admite valores y es el objeto inicial en esta categoría. De manera similar, el booleano es el tipo con dos valores.
El tipo de unidad se implementa en la mayoría de los lenguajes de programación funcionales . El tipo void que se usa en algunos lenguajes de programación imperativos cumple algunas de sus funciones, pero debido a que su conjunto de portadores está vacío, tiene algunas limitaciones (como se detalla a continuación).
En lenguajes de programación
Varios lenguajes de programación de computadoras proporcionan un tipo de unidad para especificar el tipo de resultado de una función con el único propósito de causar un efecto secundario y el tipo de argumento de una función que no requiere argumentos.
- En Haskell y Rust , el tipo de unidad se llama
()
y su único valor también es()
, lo que refleja la interpretación de tupla 0. - En los descendientes de ML (incluidos OCaml , Standard ML y F # ), se llama al tipo
unit
pero el valor se escribe como()
. - En Scala , se llama al tipo de unidad
Unit
y su único valor se escribe como()
. - En Common Lisp, el tipo llamado NULL es un tipo de unidad que tiene un valor, a saber, el símbolo NIL . Esto no debe confundirse con el tipo NIL , que es el tipo inferior .
- En Python , hay un tipo llamado
NoneType
que permite el valor único deNone
. - En Swift , el tipo de unidad se llama
Void
o()
y su único valor también es()
, lo que refleja la interpretación de tupla 0. - En Java , se llama al tipo de unidad
Void
y su único valor esnull
. - En Go , se escribe el tipo de unidad
struct{}
y su valor esstruct{}{}
. - En PHP , el tipo de unidad se llama nulo, cuyo único valor es NULL.
- En JavaScript , tanto
Null
(su único valor esnull
) comoUndefined
(su único valor esundefined
) son tipos de unidad incorporados. - en Kotlin ,
Unit
es un singleton con un solo valor: elUnit
objeto. - En Ruby ,
nil
es la única instancia de laNilClass
clase. - En C ++ , el
std::monostate
tipo de unidad se agregó en C ++ 17. Antes de eso, es posible definir un tipo de unidad personalizada usando una estructura vacía comostruct empty{}
.
Tipo vacío como tipo de unidad
En C , C ++ , C # y D , void
se usa para designar una función que no devuelve nada útil o una función que no acepta argumentos. El tipo de unidad en C es conceptualmente similar a un vacío struct
, pero una estructura sin miembros no está permitida en la especificación del lenguaje C (esto está permitido en C ++). En cambio, ' void
' se usa de una manera que simula algunas, pero no todas, las propiedades del tipo de unidad, como se detalla a continuación. Como la mayoría de los lenguajes imperativos, C permite funciones que no devuelven un valor; estos se especifican con el tipo de retorno vacío. Tales funciones se denominan procedimientos en otros lenguajes imperativos como Pascal , donde se hace una distinción sintáctica, en lugar de una distinción de sistema de tipos, entre funciones y procedimientos.
Diferencia en la convención de llamadas
La primera diferencia notable entre un tipo de unidad verdadero y el tipo de vacío es que el tipo de unidad siempre puede ser el tipo del argumento de una función, pero el tipo de vacío no puede ser el tipo de un argumento en C, a pesar de que puede aparecen como el único argumento en la lista. Este problema se ilustra mejor con el siguiente programa, que es un error en tiempo de compilación en C:
void f ( vacío ) {} void g ( vacío ) {}int main ( vacío ) { f ( g ()); // error en tiempo de compilación aquí return 0 ; }
Este problema no surge en la mayoría de la práctica de programación en C, porque dado que el void
tipo no lleva información, es inútil pasarlo de todos modos; pero puede surgir en programación genérica , como las plantillas de C ++ , donde void
debe tratarse de manera diferente a otros tipos. Sin embargo, en C ++, se permiten clases vacías, por lo que es posible implementar un tipo de unidad real; el ejemplo anterior se vuelve compilable como:
class unit_type {}; const unit_type the_unit ;unit_type f ( unit_type ) { return the_unit ; } unit_type g ( unit_type ) { return the_unit ; }int main () { f ( g ( la_unidad )); return 0 ; }
(Para abreviar, en el ejemplo anterior no nos preocupa si the_unit
es realmente un singleton ; consulte el patrón singleton para obtener detalles sobre ese tema).
Diferencia en almacenamiento
La segunda diferencia notable es que el tipo void es especial y nunca se puede almacenar en un tipo de registro , es decir, en una estructura o clase en C / C ++. Por el contrario, el tipo de unidad se puede almacenar en registros en lenguajes de programación funcionales, es decir, puede aparecer como el tipo de un campo; la implementación anterior del tipo de unidad en C ++ también se puede almacenar. Si bien esto puede parecer una característica inútil, permite, por ejemplo, implementar elegantemente un conjunto como un mapa del tipo de unidad; en ausencia de un tipo de unidad, aún se puede implementar un conjunto de esta manera almacenando algún valor ficticio de otro tipo para cada clave.
En Genéricos
En Java Generics, los parámetros de tipo deben ser tipos de referencia. El tipo de contenedor Void
se usa a menudo cuando se necesita un parámetro de tipo de unidad. Aunque el Void
tipo nunca puede tener instancias, tiene un valor null
(como todos los demás tipos de referencia), por lo que actúa como un tipo de unidad. En la práctica, cualquier otro tipo no instanciable, por ejemplo Math
, también puede usarse para este propósito, ya que también tienen exactamente un valor null
,.
public static Void f ( Void x ) { return null ; } public static Void g ( Void x ) { return null ; }public static void main ( String [] args ) { f ( g ( nulo )); }
Ver también
- Patrón singleton (donde una clase en particular tiene solo una instancia, pero las referencias no anulables de tipo restringido a ella generalmente no se encuentran en otras clases)
Referencias
- Pierce, Benjamin C. (2002). Tipos y lenguajes de programación . Prensa del MIT . págs. 118-119. ISBN 0-262-16209-1.
- tipo de unidad en nLab