2010-03-01 9 views
5

En los círculos de diseño de idiomas solía haber un largo debate sobre si los idiomas deberían usar structural equivalence o name equivalence. Los lenguajes como ALGOL o ML o Modula-3 usaban equivalencia estructural mientras ... bueno, casi todos los lenguajes de programación emplean equivalencia nombrada (incluyendo Modula-2).¿Cuáles son los argumentos a favor y en contra de la equivalencia de nombres y la equivalencia estructural?

¿Cuáles son los argumentos típicos a favor de la equivalencia estructural? ¿Cuáles son los argumentos típicos en oposición a esto? ¿Cuáles son los argumentos típicos a favor de la equivalencia de nombres? ¿Cuáles son los argumentos típicos en oposición a esto?

+0

Enlaces de Wikipedia: http://en.wikipedia.org/wiki/Structural_type_system http://en.wikipedia.org/wiki/Nominative_type_system –

+0

Esto me dice cuáles son. Ya lo sé, siendo un usuario de, bueno, una gran cantidad de idiomas que usan variantes de ambos tipos. Lo que esas páginas no me dicen es qué argumentos se usan para apoyar a cada lado y derribar el otro lado. –

+0

Sí, solo estaba proporcionando enlaces para el beneficio de lectores que no saben de qué se trata la pregunta. Tal vez debería haber editado la pregunta en su lugar. –

Respuesta

6

Creo que la ventaja de los sistemas de tipo estructural es que lo alientan a crear interfaces de grano fino orientadas hacia lo que el usuario de la interfaz necesita, en lugar de lo que el implementador proporciona.

En un sistema de tipo nominativo necesita una dependencia común en la interfaz. En un sistema de tipo estructural, ese requisito se elimina: puede construir un sistema débilmente acoplado sin necesidad de crear esa biblioteca común donde coloca todas las interfaces. Cada cliente puede declarar independientemente la interfaz que espera de un colaborador.

La desventaja de los sistemas de tipo estructural es que combinan clases con interfaces que pueden no implementar el contrato correcto. Por ejemplo, si usted tiene esta interfaz:

public interface IBananaProvider 
{ 
    /// Returns a banana, never null. 
    Banana GetBanana(); 
} 

entonces implícitamente se considerará lo siguiente clase para implementar IBananaProvider en un sistema de tipo estructural. Sin embargo, la clase viola la condición post que el plátano regresado nunca es nula:

public class SomeBananaProvider 
{ 
    // returns a banana or null if we're all out 
    public Banana GetBanana() 
    { 
     if (bananas.Count > 0) 
     { 
      return bananas.RemoveLast(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

Esto podría fijarse si el contrato se especifica alguna manera formal y considera parte de la estructura de tipo. Creo que las cosas se están moviendo en esa dirección, p. System.Diagnostics.Contracts en .NET 4.0.

+0

Solo por aclaración: las ventajas de la equivalencia estructural son similares a las ventajas del tipado de pato, pero requieren interfaces completas para ser implementadas, por lo que son menos flexibles, pero ¿es más probable que se tipeen correctamente? –

+1

No entiendo lo que quiere decir con "requieren interfaces completas para ser implementadas por lo que son menos flexibles". La tipificación estructural le permite definir la interfaz mínima absoluta para cada colaborador, sin que los implementadores necesiten conocer todas esas interfaces mínimas. Por lo tanto, diría lo contrario: la tipificación estructural elimina la necesidad de implementar miembros de interfaz inútiles, ya que cada miembro requerido es uno que realmente utiliza el cliente. –

+1

En pato escribiendo si tengo una "interfaz" con los elementos A y B y sé que un usuario dado de ella solo tiene acceso a AI puede pasar en un "implementador" de esa interfaz que solo proporciona A (un objeto falso para probar, decir) - el "tipo" se verifica solo en el punto de uso y solo para el elemento específico que se utiliza. En Modula-3 (un lenguaje de equivalencia estructural) no puedo hacer eso. El compilador comprueba estáticamente la estructura para la equivalencia, por lo que no puedo pasar algo que proporcione un subconjunto de la funcionalidad, incluso si sé que este cliente específico (o parte del mismo) solo usa ese subconjunto. –

3

Un buen argumento a favor de la equivalencia de nombres estrictos (como está disponible en Ada por ejemplo) es que hace posible que el compilador rechace código que accidentalmente mezcla diferentes unidades, como por ejemplo centímetros y pulgadas, o celsius y fahrenheit .

En un lenguaje con el nombre de equivalencia estricta puede tener dos tipos

type celsius based on float; 
type fahrenheit based on float; 

var c : celsius; var f : fahrenheit; 

c := f; /* compile time error: incompatible types */ 

tiempo, en un lenguaje con el nombre de equivalencia perder y en uno con la equivalencia estructural ...

type celsius is float; 
type fahrenheit is float; 

c := f; /* no error and no warning here */ 

.. Usted terminaría con un error de cálculo que conducirá a un comportamiento impredecible, dependiendo del tipo de aplicación y el sistema esto podría conducir a una grave pérdida financiera o incluso a la muerte. Tal error lógico también es muy difícil de rastrear sin una equivalencia de nombre estricta en su lugar.

+2

. Así que estás diciendo que la NASA prefieres la equivalencia estricta del nombre? ;) –

+0

En cuanto a la NASA, está el caso de una misión a Venus donde se perdió la nave espacial porque se mezclaron kilómetros y millas. Si ese software se hubiera escrito en un lenguaje con una equivalencia de nombres estricta, entonces sí, de hecho, este error se habría capturado en tiempo de compilación. – trijezdci

Cuestiones relacionadas