J'ai eu du mal à voir en quoi consiste ce principe et pourquoi est-il si important pour la conception du langage.
Fondamentalement, il indique que pour chaque expression expr
dans le langage devrait être exactement la même que cette construction:
(function () { return expr; })()
En outre, j'ai entendu dire que Ruby obéit à ce principe, contrairement à Python. Je ne comprends pas pourquoi c'est vrai, ou si c'est vrai du tout.
design
language-agnostic
Andrew
la source
la source
expr
obtienne la trace de pile actuelle.Réponses:
Je n'ai jamais entendu parler auparavant du "principe de correspondance de Tennent" et encore moins de son importance dans la conception du langage. La recherche sur les expressions semble conduire à un blog Neal Gafter de 2006 qui définit ce qu'il pense que c'est et comment il pense que cela devrait également s'appliquer aux fermetures. Et la plupart de tous les autres dans les forums semblent faire référence à l'entrée de Gafter.
Voici cependant une mention dudit "TCP" par Douglas Crockford (un nom que je connais et auquel je fais confiance): http://java.sys-con.com/node/793338/ . En partie
Il semble donc que le nom de «principe de correspondance de Tennent» soit mal utilisé, et tout ce dont Neal parle peut-être devrait être appelé «TCP imaginé et éventuellement généralisé de Gafter» ... ou quelque chose du genre. En tout cas, pas assez pour se cacher derrière un rideau de nom de livre épuisé
la source
Je vois cela comme faisant partie d'une règle générale selon laquelle un langage bien conçu fait ce à quoi un programmeur devrait naturellement s'attendre. Si j'ai un bloc de code que je veux refactoriser dans une fermeture, et que j'enveloppe ce bloc avec la syntaxe appropriée sans vraiment penser aux lignes de code individuelles, alors je m'attends à ce que ce bloc fasse la même chose dans la fermeture qu'il a fait en ligne. Si certaines instructions utilisent le mot-clé "this" (peut-être implicitement) et que le langage fait que "this" utilisé à l'intérieur de la fermeture fait référence à une classe anonyme utilisée pour la représenter plutôt qu'à la classe qui définit la méthode qui définit la fermeture, alors la signification de ces déclarations ont changé, mon bloc de code ne fait plus ce que je pense, et je dois traquer un bogue et trouver comment changer mon code pour qu'il fonctionne pendant la fermeture.
Le problème pourrait également être atténué avec un IDE avec des outils de refactorisation intelligents, qui pourraient extraire les fermetures, détecter les problèmes potentiels et même ajuster automatiquement le code extrait pour résoudre les problèmes.
la source
Claus Reinke: concernant la "Conception du langage basée sur les principes sémantiques" de Tennent
Donne une interprétation intéressante des principes:
"La correspondance est le principe qui nous permet de dire que
et
devrait être équivalent, et que tout ce que nous pouvons faire dans des listes de paramètres formelles, nous devrions également être en mesure de le faire dans des déclarations, et vice versa. "[Voir aussi, Reinke, ci-dessous.]
RD Tennent: Méthodes de conception de langage basées sur des principes sémantiques
"Deux méthodes de conception de langage basées sur des principes dérivés de l'approche dénotationnelle de la sémantique du langage de programmation sont décrites et illustrées par une application au langage Pascal. Les principes sont, premièrement, la correspondance entre paramétrique et mécanismes déclaratifs, et deuxièmement, un principe d'abstraction pour les langages de programmation adapté de la théorie des ensembles. Plusieurs extensions et généralisations utiles de Pascal émergent en appliquant ces principes, y compris une solution au problème des paramètres de tableau et une facilité de modularisation. "
Claus Reinke: "Sur la programmation fonctionnelle, la conception de langage et la persistance" sur Haskell
la source
Pour répondre à la question de savoir pourquoi le CP de Tennent est si important pour la conception de langage, je voudrais citer Neal Gafter :
Toute violation de TCP est susceptible de nuire à certains programmeurs à l'avenir lorsqu'il s'attend à ce que les fermetures fonctionnent comme du code de non-fermeture, mais constate que, en violation de TCP, elles ne le font pas.
la source
RE Python ne suit pas ce principe. Généralement, il suit le principe. Exemple de base:
Cependant, Python définit les expressions et les instructions séparément. Étant donné que les
if
branches, leswhile
boucles, les affectations destructives et d'autres instructions ne peuvent pas du tout être utilisées dans leslambda
expressions, la lettre du principe Tennent ne s'applique pas à elles. Même ainsi, se limiter à utiliser uniquement des expressions Python produit toujours un système complet de Turing. Je ne considère donc pas cela comme une violation du principe; ou plutôt, s'il viole le principe, aucun langage définissant séparément les déclarations et les expressions ne peut être conforme au principe.De plus, si le corps de l'
lambda
expression capturait une trace de pile ou effectuait une autre introspection dans la machine virtuelle, cela pourrait provoquer des différences. Mais à mon avis, cela ne devrait pas être considéré comme une violation. Siexpr
et(lambda: expr)()
nécessairement compiler dans le même bytecode, alors le principe concerne vraiment les compilateurs et non la sémantique; mais s'ils peuvent être compilés en différents octets, nous ne devons pas nous attendre à ce que l'état de la machine virtuelle soit identique dans chaque cas.Une surprise peut être rencontrée en utilisant la syntaxe de compréhension, bien que je pense que ce n'est pas non plus une violation du principe Tennent. Exemple:
La surprise est le résultat de la définition des compréhensions de liste. La compréhension «surprise» ci-dessus est équivalente à ce code:
Vu de cette façon, la compréhension «surprise» ci-dessus est moins surprenante et ne constitue pas une violation du principe Tennent.
la source