8
votes

Plus d'explications sur la liaison lexicale dans la fermeture?

Il y a beaucoup de postes liés à cela, mais je le pose à nouveau avec un but différent

J'essaie de comprendre pourquoi les fermetures sont importantes et utiles. Une des choses que j'ai lues dans d'autres messages en ce qui concerne cela est que lorsque vous passez une variable à la fermeture, la fermeture commence à se souvenir de cette valeur à partir de là. Est-ce l'ensemble de l'aspect technique ou il y a plus à ce qui se passe là-bas.

Ce que je me demande, c'est ce qui se passerait lorsque la variable utilisée à l'intérieur de la fermeture est modifiée de l'extérieur. Si celles-ci ne sont que des constantes seulement?

Dans le clojure de langue, je peux faire ce qui suit: mais comme il y a de la valeur est immuable, ce problème ne se présente pas. Qu'en est-il des autres langues et quelle est la définition technique appropriée d'une fermeture? xxx


0 commentaires

8 Réponses :


2
votes

Vous pouvez penser à une fermeture comme un "environnement", dans lequel les noms sont liés à valeurs . Ces noms sont entièrement privés à la fermeture, c'est pourquoi nous disons qu'il "ferme" son environnement. Donc, votre question n'est donc pas significative, dans la mesure où le «extérieur» ne peut affecter l'environnement fermé. Oui, une fermeture peut faire référence à un nom dans un environnement mondial (en d'autres termes, s'il utilise un nom qui n'est pas lié dans son environnement privé, fermé), mais c'est une histoire différente.

Si vous aimez, vous pouvez penser à un environnement comme dictionnaire ou table de hachage. Une fermeture obtient son propre petit dictionnaire où les noms sont levés.


2 commentaires

Il est un peu trompeur de dire que les noms de fermeture sont liés à valeurs . Dans certaines langues (par exemple Smalltalk), ils sont liés à références . Dans SmallTalk, deux fermetures peuvent "fermer" une variable locale x et ils se verront les affectations de chacun à x .


D'accord, et j'ai pensé avec précaution sur mon choix de mots, envisageez mon auditoire. :)



5
votes

Une fermeture est en réalité une structure de données utilisée par le compilateur pour vous assurer qu'une fonction aura toujours accès aux données nécessaires à l'opportunité. Voici un exemple de fonction qui enregistre quand il a été défini.

(defn outer []
    (let [foo (get-time-of-day)]
      (defn inner []
          #(str "then:" foo " now:" (get-time-of-day)))))


(def then-and-now (outer))
(then-and-now)    ==> "then:1:02:03 now:2:30:01"
....
(then-and-now)    ==> "then:1:02:03 now:2:31:02"


0 commentaires

5
votes

a fermeture lexicale est un dans lequel les variables ci-jointes (par exemple préfixe de message d'accueil dans votre exemple) sont jointes à la référence. La fermeture créée ne reçoit pas simplement la valeur de préfixe de message d'accueil au moment de sa création, mais obtient une référence. Si VOYAGE-PREFIX est modifié après la création de la fermeture, sa nouvelle valeur sera utilisée par la fermeture chaque fois qu'elle est appelée.

Dans des langues fonctionnelles pures, ce n'est pas une grande distinction, car les valeurs ne sont jamais changées. Donc, peu importe si la valeur de de préfixe-préfixe est copiée dans la fermeture: il n'y a pas de différence possible de comportement qui pourrait résulter de se référer à l'original par rapport à sa copie.

Dans "Imperative-Languages-avec fermetures", telles que C # et Java (via des classes anonymes), une décision doit être faite sur le point de savoir si la variable ci-jointe est jointe à une valeur ou par référence. En JAVA, cette décision est préemptée en permettant uniquement aux variables de final à imiter efficacement une langue fonctionnelle en ce qui concerne cette variable. En C #, je crois que c'est une question différente.

Englobant par la valeur simplifie la mise en oeuvre: la variable à clôturerie existe souvent sur la pile et sera donc détruite lorsque la fonction construit la fermeture de la fermeture - cela signifie qu'il ne peut pas être enfermé par référence. Si vous avez besoin d'un boîtier par référence, une solution de contournement consiste à identifier de telles variables et à les conserver dans un objet attribué chaque fois que cette fonction est appelée. Cet objet est ensuite maintenu dans le cadre de l'environnement de la fermeture et doit rester en direct tant que toutes les fermetures en utilisant sont en direct. (Je ne sais pas si des langues compilées utilisent directement cette technique.)


0 commentaires


1
votes

Jetez un coup d'œil à ce blog post: Adts in Clojure . Il montre une agréable application de fermetures au problème des données de verrouillage de manière à ce qu'elle soit accessible exclusivement via une interface particulière (rendu du type de données opaque).

L'idée principale de ce type de verrouillage est plus simplement illustrée avec le compteur Exemple, quel huaiyuan a posté en commun Lisp pendant que je pouvais composer cette réponse. En réalité, la version de Clojure est intéressante en ce sens qu'elle montre que la question d'une variable de changement fermé changeant sa valeur est survenue dans le clojure si la variable arrive à contenir une instance de l'un des types de référence. P>

((make-greeter "Hello from Gizmos Dept") "John")
((make-greeter "Hello from Gadgets Dept") "Jack").


0 commentaires


9
votes

Ce n'est pas le genre de réponse qui semble avoir des votes utiles ici, mais je vous exhorte tout à fait envie de découvrir la réponse à votre question en lisant Shrram Krishnamurthi's (gratuit!) (en ligne!) manuel, Langues de programmation: Application et interprétation .

Je vais paraphraser le livre très, très brièvement, en résumant le développement des minuscules interprètes qui vous conduisent à travers:

  • Un langage d'expression arithmétique (AE)
  • une langue d'expression arithmétique avec des expressions nommées (wae); La mise en œuvre consiste à développer une fonction de substitution qui peut remplacer les noms avec des valeurs
  • une langue qui ajoute des fonctions de premier ordre (F1WAE): L'utilisation d'une fonction implique de substituer valeurs pour chacun des noms de paramètres.
  • la même langue, sans substitution: il s'avère que les "environnements" vous permettent d'éviter les frais généraux de la substitution préventive.
  • une langue qui élimine la séparation entre les fonctions et les expressions en permettant Fonctions à définir à des emplacements arbitraires (AWAE)

    Ceci est le point clé: vous mettez en œuvre cela, puis vous découvrez cela avec la substitution, cela fonctionne bien, mais avec des environnements, il est cassé. En particulier, afin de le réparer, vous devez vous assurer d'associer à une définition de fonction évaluée de l'environnement qui était en place lorsqu'il a été évalué. Cette paire (Fundef + Environnement de définition) est ce qu'on appelle une "fermeture".

    whew!

    D'accord, que se passe-t-il lorsque nous ajoutons des liaisons mutables à la photo? Si vous essayez ceci vous-même, vous verrez que la mise en œuvre naturelle remplace un environnement qui associe des noms avec des valeurs avec un environnement qui associe des noms avec des liaisons. C'est orthogonal à la notion de fermeture; Étant donné que la fermeture Capturing Environnements, et puisque les environnements sont désormais de noms de noms vers des fixations, vous obtenez le comportement que vous décrivez, dans lequel la mutation d'une variable capturée dans un environnement est visible et persistante.

    Encore une fois, je vous exhorte beaucoup à vous demander de jeter un coup d'œil à Plai .


1 commentaires

Votre réponse pourrait être améliorée en fournissant un lien hypertexte sur le site du livre - et non qu'il est trop difficile de trouver, mais c'est une bonne faveur.



0
votes

Vous pouvez penser à une fermeture en tant que "environnement", dans lequel les noms sont lié aux valeurs. Ces noms sont entièrement privé à la fermeture, qui C'est pourquoi nous disons qu'il "ferme" " son environnement. Donc votre question n'est pas significatif, dans ce "extérieur" ne peut affecter la environnement fermé. Oui un la fermeture peut faire référence à un nom dans un environnement mondial (en d'autres termes, si il utilise un nom qui n'est pas lié dans son environnement privé, fermé), Mais c'est une histoire différente.

Je suppose que la question était de savoir si des choses comme celles-ci sont possibles dans des langues qui permettent la mutation des variables locales: xxx

et - car ils sont évidemment possibles - je pense que la question est légitime.


0 commentaires