(Dés) avantages du typage structurel

15

Je viens de regarder cette conférence de Daniel Spiewak où il parle des avantages du typage structurel par rapport au typage nominal de Scala et Java . Un exemple de cette différence serait le code Java suivant

public interface Foo {
  public int length();
}
public interface Bar {
  public int length();
}

Foo f = ...;
Bar b = f;

qui bien sûr ne compilerait pas car la compatibilité des types entre Fooet Barest déterminée par le nom.

Un système de type structurel, d'autre part, pourrait déclarer les deux types égaux ou compatibles et donc, entre autres, permettre le typage vérifié du canard.

Maintenant, je pense que je comprends la plupart des avantages d'un système de type structurel, mais je me demande si cela n'invaliderait pas la sécurité des types à partir d'exemples tels que les suivants

class Foo {
  class Bar { /* ... */ }
  def takeBar(b: Bar) = { /* ... */ }
  def getBar: Bar = new Bar
}

val foo1 = new Foo
val foo2 = new Foo
foo1.takeBar(foo1.getBar) // should compile
foo1.takeBar(foo2.getBar) // should not compile

Est-ce que je comprends que dans un système de type structurel, la dernière ligne se compilerait également et si oui, ne serait-ce pas un inconvénient en ce qui concerne la sécurité des types?

Debilski
la source
3
Pourriez-vous expliquer pourquoi la dernière ligne ne devrait pas être compilée? Je ne vois pas l'incompatibilité de type.
Sam Goldberg
2
C'est un type dépendant du chemin Scala .
Debilski
En fait, je voulais en discuter du point de vue du système de type Scala. Il se trouve que le seul exemple donné dans l'exposé était en Java.
Debilski

Réponses:

12

En fait, les types dépendant du chemin sont orthogonaux au typage structurel vs nominal. On ne sait pas vraiment ce que signifie une classe interne dans le contexte d'un langage structurellement simple. Il est cependant très possible de le définir . Si vous deviez définir des classes internes dans un contexte structurellement typé, vous devez vous assurer que les cas comme celui que vous avez énuméré seront rejetés (précisément pour les mêmes raisons que Scala les rejette).

Vous rejetteriez de tels cas en faisant la même chose que Scala: modéliser le type dépendant du chemin comme un type existentiel. La même procédure de pack / unpack entourant l'accès aux objets se tiendrait et les résultats seraient presque identiques à ce que fait Scala. Les résultats peuvent sembler être une égalité de type nominale, mais ce serait toujours un système de type structurel puisque la question de la compatibilité de type sera toujours décidée sur l'interface plutôt que sur le nom.

Le typage structurel a beaucoup d'implications, mais (peut-être de manière surprenante) la plupart des mêmes concepts que nous connaissons et aimons tous des systèmes de types nominaux se retrouvent dans la structure. Le typage structurel n'est rien d'autre qu'une manière différente de définir la compatibilité des types.

Daniel Spiewak
la source
0

Le typage structurel facilite l'écriture de code de bibliothèque générique. La première raison pour laquelle l'écosystème Java est si gonflé est qu'il est difficile d'écrire facilement de petites bibliothèques. Si Java était structurellement typé, je pense que ce serait une autre histoire et une bien meilleure situation.

Le seul inconvénient auquel je peux penser pour le typage structurel est le potentiel de compilation plus lente. Je ne sais pas si les langages structurels se compilent généralement plus lentement que les langages nominatifs ou non, mais par exemple Golang est typé structurellement et très rapide à compiler.

Alexander Mills
la source