2011-12-25 9 views
10

me he dado cuenta de este idioma en Data.Unique:¿Qué tan seguro es `UnsafePerformIO (newTVarIO 0)`?

uniqSource :: TVar Integer 
uniqSource = unsafePerformIO (newTVarIO 0) 
{-# NOINLINE uniqSource #-} 

¿Está garantizada sólo a ejecutar una vez?

+0

Como regla general, 'unsafePerformIO' solo debe usarse como un detalle de implementación del código de la biblioteca, y entonces solo debe usarlo porque está bastante seguro de que no hay absolutamente ninguna otra manera de lograr el mismo rendimiento/comportamiento. No estoy del todo seguro de por qué sentí la necesidad de decirlo aquí, ya que no es 100% pertinente a la pregunta, pero ahí lo tienes. –

+0

Relacionados: http://stackoverflow.com/questions/6076129/ – fuz

Respuesta

11

En GHC, sí. Consulte the documentation para obtener más información; Existe una variante unsafeDupablePerformIO que se puede ejecutar varias veces para evitar la sobrecarga dedicada a lograr esta garantía.

Tenga en cuenta que unsafePerformIO para crear variables variables no es seguro en general; como se describe en la documentación, puede crear una referencia polimórfica y usarla para implementar unsafeCoerce. Sin embargo, eso no es algo que pueda hacer accidentalmente, y no se aplica al código en cuestión (ya que el tipo de referencia se especifica explícitamente).

El paquete safe-globals abstrae esta "expresión idiomática" (aunque es útil en algunos casos, es generally considered an antipattern, y no debe usarse en el código normal) de forma que se garantice la seguridad.

Vea también mi previous answer en unsafePerformIO y la precaución que debe usarse al aplicarlo.

Estoy bastante seguro de que se aplica a todas las demás implementaciones, también; el cuidado especial que GHC toma para evitar la ejecución repetida solo es necesario en una configuración enhebrada, y no conozco ninguna otra implementación de Haskell. Sin embargo, GHC es la única implementación que las personas realmente usan en la actualidad ...

Cuestiones relacionadas