Question

Dans un impératif, objet langage oriente, serait plus logique d'avoir des fermetures mutables ou immuables?

Par exemple:

int i=5;
function() f={print(i);};
f();
i=6;
f();

Si la fermeture est mutable, ce imprimera:

5
6

Si elle est immuable, il imprimera:

5
5

Je me rends compte que même avec des fermetures immuables, vous pouvez toujours faire ceci:

class I {int i;}
I i=new I();
i.i=5;
function() f={
    I j=i;
    print(j.i);
};
f();
i.i=6;
f();

Alors, serait-il préférable d'avoir des fermetures mutables ou immuables, ou la possibilité pour les deux? fermetures semblent plus faciles à Immuable mettre en œuvre, de sorte à ce moment-là, je pense que je vais avec cela, à moins qu'il y ait une bonne raison de ne pas.

Était-ce utile?

La solution

langues Impératif sont généralement construits autour du concept de l'Etat. Par conséquent, il est plus logique pour les caractéristiques linguistiques pour refléter le fait que, y compris les fermetures. Oui, ce comportement peut être déroutant parfois, mais ça fait partie du problème et l'avantage d'avoir l'état dans votre application.

Je pense que la meilleure preuve de cet argument est d'examiner quelques-unes des langues les plus récentes qui ont le soutien de fermeture. C # et VB.Net, langages OO impératif, a choisi d'avoir des fermetures mutables. Bien que F #, un langage fonctionnel, a des fermetures immuables (principalement découlant de l'idée que F # est immuable par défaut).

Aussi qu'est-ce que cela signifie en fait d'avoir une fermeture immuable dans un langage impératif? La plupart des gens pensent à ce que de faire les variables équivalentes à readonly de C #. Bien sûr les types de valeur seraient protégés contre toute modification, mais qu'en est-types de référence mutables. Vous ne seriez pas en mesure de changer où la variable a, mais vous pouvez appeler une fonction mutationniste et obtenir un effet similaire. Par exemple.

class Student {
  public string Name { get; set; }
}

void Example() {
  var student = new Student() { Name = "foo" };
  Action() del = () => 
    { student.Name = "bar"; };
  del();
}

Cela pourrait être mis en œuvre avec une fermeture immuable que je ne modifie pas réellement où les variables pointent. Cependant, je fais bien encore une opération muter.

Autres conseils

langues ont lambdas Devaient que la capture par la valeur ou la capture par référence? Décider pour vous-même, mais voir « Sur lambdas, la capture et la mutabilité » pour plus de commentaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top