2010-03-01 11 views
5

W kręgach projektowania języków od dawna debatowano nad tym, czy języki powinny używać structural equivalence lub name equivalence. Języki takie jak ALGOL lub ML lub Modula-3 używały równoważności strukturalnej, podczas gdy ... właściwie większość języków programowania używa nazwanej równoważności (w tym Modula-2).Jakie są argumenty za i przeciw zarówno równoważności nazwy, jak i równoważności strukturalnej?

Jakie są typowe argumenty przemawiające za równoważnością strukturalną? Jakie są typowe argumenty przeciwne temu? Jakie są typowe argumenty przemawiające za równoważnością nazw? Jakie są typowe argumenty przeciwne temu?

+0

Linki do Wikipedii: http://en.wikipedia.org/wiki/Structural_type_system http://en.wikipedia.org/wiki/Nominative_type_system –

+0

To mówi mi, czym one są. Wiem o tym, będąc użytkownikiem, no cóż, wielu języków, które używają wariantów obu rodzajów. Co te strony nie mówią mi, jakie argumenty są używane do wspierania każdej strony i zburzyć drugą stronę. –

+0

Tak, właśnie dostarczałem linki dla czytelników, którzy nie wiedzą o co chodzi. Może powinienem zamiast tego edytować pytanie. –

Odpowiedz

6

Myślę, że zaletą systemów typu strukturalnego jest to, że zachęcają do tworzenia precyzyjnych interfejsów zorientowanych na to, czego potrzebuje użytkownik interfejsu, a nie na to, co zapewnia implementator.

W mianowalnym systemie typów wymagana jest wspólna zależność od interfejsu. W systemie typu strukturalnego wymóg ten jest eliminowany: można zbudować luźno powiązany system bez potrzeby tworzenia wspólnej biblioteki, w której umieszczane są wszystkie interfejsy. Każdy klient może niezależnie zadeklarować interfejs, którego oczekuje od współpracownika.

Wadą systemów typu strukturalnego jest to, że dopasowują klasy do interfejsów, które mogą nie implementować poprawnej umowy. Na przykład, jeśli masz ten interfejs:

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

następnie dodaje klasy będą domyślnie uznawane wdrożyć IBananaProvider w systemie typu strukturalnego. Jednak klasa narusza warunku pocztowy że wrócił banan jest nigdy zerowa:

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; 
     } 
    } 
} 

To może być ustalona, ​​gdyby umowa została w jakiś sposób określony formalnie i traktowane jako część struktury typu. Myślę, że sprawy idą w tym kierunku, np. System.Diagnostics.Contracts w .NET 4.0.

+0

Dla jasności: korzyści z równoważności strukturalnej są podobne do zalet typowania kaczego, ale wymagają pełnych interfejsów, aby były zaimplementowane, więc są mniej elastyczne, ale do tego bardziej prawdopodobne, że zostaną poprawnie napisane. –

+1

Nie rozumiem, co masz na myśli przez "wymagają pełnych interfejsów do wdrożenia, więc są mniej elastyczne". Pisanie strukturalne pozwala zdefiniować absolutny minimalny interfejs dla każdego współpracownika, bez implementatorów, które muszą znać wszystkie te minimalne interfejsy. Dlatego powiedziałbym coś odwrotnego: typowanie strukturalne eliminuje potrzebę implementacji bezużytecznych elementów interfejsu, ponieważ każdy wymagany element to taki, który jest faktycznie używany przez klienta. –

+1

W pisaniu na kaczce, jeśli mam "interfejs" z elementami A i B i wiem, że dany użytkownik z niego tylko uzyskuje dostęp do sztucznej inteligencji może przejść w "implementatorze" tego interfejsu, który zapewnia tylko A (próbny obiekt do testowania, say) - "typ" jest sprawdzany tylko w punkcie użycia i tylko dla konkretnego używanego elementu. W Modula-3 (strukturalnym języku równoważności) nie mogę tego zrobić. Kompilator statycznie sprawdza strukturę pod względem równoważności, więc nie mogę przekazać czegoś, co zapewnia podzbiór funkcji, nawet jeśli wiem, że ten jeden określony klient (lub jego część) używa tylko tego podzbioru. –

3

Jednym z dobrych argumentów na rzecz ścisłej ekwiwalencji nazwy (na przykład w wersji Ada) jest to, że umożliwia ona kompilatorowi odrzucenie kodu, który przypadkowo miksuje różne jednostki, np. Centymetry i cale lub Celsjusza i Fahrenheita. .

W języku o nazwie ścisłej równoważności można mieć dwa rodzaje

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

var c : celsius; var f : fahrenheit; 

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

podczas gdy w języku o nazwie stracić równoważności iw jednym z równoważności strukturalnej ...

type celsius is float; 
type fahrenheit is float; 

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

.. W rezultacie skończyłoby się błędne obliczenia, które doprowadzą do nieprzewidywalnego zachowania, w zależności od rodzaju aplikacji i systemu, co może doprowadzić do poważnej straty finansowej, a nawet śmierci. Taki logiczny błąd jest również bardzo trudny do wyśledzenia bez ścisłej równoważności nazw w miejscu.

+2

Więc mówisz, że NASA preferujesz ścisłą równoważność nazwy? ;) –

+0

Jeśli chodzi o NASA, mamy do czynienia z misją na Wenus, gdzie statek kosmiczny został utracony z powodu pomieszania kilometrów i mil. Gdyby to oprogramowanie zostało napisane w języku o ścisłej ekwiwalencji nazwy, to tak, rzeczywiście, błąd ten zostałby złapany podczas kompilacji. – trijezdci

Powiązane problemy