Formation avancé sur la programmation avec Python et le Framework TACTIC


Télécharger Formation avancé sur la programmation avec Python et le Framework TACTIC

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Formation avancé sur la programmation avec Python et le Framework TACTIC

  1. Motivation et contributions

Le langage de programmation Python est actuellement largement utilisé dans l'industrie, la science et l'éducation. En raison de sa popularité, il dispose désormais de plusieurs outils tiers, notamment des analyseurs qui vérifient divers motifs d'erreur potentiels [2, 5, 11, 13]. Il comporte également des environnements de développement interactifs [1, 8, 14] offrant une variété de fonctionnalités telles que les refactorisations à renommage variable et la complétion de code. Malheureusement, ces outils ne sont pas sains: par exemple, le simple programme de huit lignes présenté dans l'annexe n'utilise aucune fonctionnalité «dynamique» et confond la fonctionnalité de changement de nom de variable de ces environnements. La difficulté de raisonner à propos de Python devient encore plus pressante à mesure que le langage est adopté dans des domaines de plus en plus importants. Par exemple, la US Securities and Exchange Commission a proposé d'utiliser Python en tant que spécification exécutable de contrats financiers [12]. Cette méthode est désormais utilisée pour créer de nouveaux paradigmes de réseau [10].

Il est donc vital de disposer d’une sémantique précise pour l’analyse des programmes et la démonstration des propriétés les concernant. Cet article présente une sémantique pour une grande partie de Python (section 5). Pour rendre la sémantique souple pour les outils et les preuves, nous la divisons en deux parties: un langage de base, λπ, avec un petit nombre de constructions, et une fonction désuète qui traduit les programmes sources dans le noyau.1 Le langage de base est essentiellement traditionnel lambda-calcul stateful enrichi de fonctionnalités pour représenter l'essence de Python (telles que l'ordre de recherche de méthodes et les listes de primitives), et devrait donc être familier à ses utilisateurs potentiels.

Parce que desugaring convertit la syntaxe de surface Python en langage central, lorsqu'il est composé avec un interpréteur pour λπ (facile à écrire), nous avons une autre implémentation de Python. On peut alors se demander comment cette implémentation se compare à celle de CPython traditionnelle, qui représente une forme de vérité sur le terrain. En ajustant soigneusement le noyau et en désaspérant, nous avons atteint la haute fidélité avec CPython. Par conséquent, les utilisateurs peuvent créer des outils au sommet de λπ, en s’assurant qu’ils sont conformes au langage réel. Au cours de la création de cette sémantique haute fidélité, nous avons identifié certains coins particuliers du langage. En particulier, la portée est non-triviale et interagit avec des fonctionnalités peut-être inattendues. Notre exposition se concentre sur ces aspects.

En résumé, cet article apporte les contributions suivantes:

  • une sémantique de base pour Python, appelée λπ, définie comme une sémantique de réduction utilisant PLT Redex [3];
  • un interpréteur, appelé λπ ↓, implémenté dans 700LOC de Racket, qui a été testé par rapport au modèle Redex;
  • une traduction déplaisante des programmes Python vers λπ, implémentée dans Racket;
  • une démonstration de conformité de la composition de la désinsertion avec λπ ↓ à CPython; et,
  • des informations sur Python tirées de ce processus.

Présenter la sémantique dans son intégralité n'est ni réalisable, compte tenu des limites d'espace, ni surtout éclairant. Nous nous concentrons plutôt sur les parties importantes ou intéressantes. Nous donnons d’abord un aperçu du modèle de valeur et d’objet de λπ. Nous introduisons ensuite la désinsertion dans les cours. Nous discutons ensuite des générateurs, des classes et de leur interaction avec scope. Enfin, nous décrivons les résultats du test de notre sémantique contre CPython. L'ensemble de notre code, ainsi qu'une annexe supplémentaire comprenant la spécification complète de la sémantique, sont disponibles en ligne à l'adresse http: // cs.brown.edu/research/plt/dl/lambda-py/.



  1. Warmup: Un rapide tour d'horizon de λπ

Nous fournissons une vue d'ensemble du modèle objet de λπ et de Python, de quelques opérations de base sur les objets et de la forme de notre sémantique à petits pas. Ceci introduit la notation et les concepts qui seront utilisés plus tard pour expliquer les parties les plus difficiles de la sémantique de Python.

2.1 Valeurs λπ

 La figure 1 montre toutes les valeurs et expressions de λπ.

Les métavariables v et val vont sur les valeurs de la langue. Toutes les valeurs de λπ sont soit des objets, écrits sous forme de triplets dans, soit des références à des entrées dans le magasin, écrites avec @ref.

Chaque objet λπ est écrit sous la forme d'un triple de l'une des formes:

V, mval, {string: ref, ...}〉

 X, mval, {chaîne: ref, ...}〉

Σ :: = ((ref v + undef) ...)

ref :: = naturel

v, val :: = 〈val, mval, {string: ref, ...}〉

 | X, mval, {chaîne: ref, ...}〉

 | @ref | (chaîne sym)

v + undef :: = v | ☠

e + undef :: = e | ☠

t :: = global | local

mval :: = (no-meta) | nombre | chaîne | meta-none

 | [val ...] | (val ...) | {val ...}

 | (méta-classe x) | (méta-code (x ...) x e)

 | λ (x ...) opt-var.e

opt-var :: = (x) | (no-var)

e :: = v | ref | (chercher e) | (set! e e) | (attribuer e)

 | e [e] | e [e: = e]

 | si e e e | e e

 | Soit x = e + undef dans e

 | x | e: = e | (effacer e)

 | e (e ...) | e (e ...) * e | (cadre e) | (retour e)

 | (pendant que e e e) | (boucle e e) | pause | continuer

 | (Builtin-prim op (e ...))

 | fun (x ...) opt-var e

 | 〈E, mval〉 | liste 〈e, [e ...]〉

 | tuple 〈e, (e ...) | définir 〈e, (e ...)〉

 | (tryexcept e x e e) | (tryfinally e e)

 | (augmenter e) | (err val)

 | (module e e) | (construct-module e)

 | (dans le module e ε)

Figure 1: expressions λπ

Ces objets ont leur classe dans la première position, leur contenu primitif dans la seconde et le dictionnaire des champs indexés par chaîne qu'ils contiennent dans la troisième. La valeur de la classe est soit une autre valeur λπ, soit le nom d'une classe intégrée. La position primitive de contenu, ou méta-valeur, contient des types particuliers de données intégrées, dont il existe un type par type intégré que modélise λπ: nombres, chaînes, la valeur méta-none distinguée, des listes, des nuplets, des ensembles, des classes et des fonctions .2 La forme distinguée ☠ («crâne») représente les emplacements de tas non initialisés dont la recherche doit générer une exception. Dans les expressions, cette forme ne peut apparaître que dans les letbindings dont la position de liaison peut contenir à la fois des expressions et expressions L'évaluation de ☠ dans une let-binding l'alloue sur le tas. Par la suite, il est erroné de rechercher un magasin contenant; une valeur doit être attribuée à cet emplacement pour que la recherche aboutisse. La figure 2 montre le comportement de la recherche dans les tas pour les valeurs et pour.



Cette notion d'emplacements non définis entrera en jeu lorsque nous discuterons de la portée dans la section 4.2.

Les programmes Python ne peuvent pas manipuler directement les valeurs d'objet; au contraire, ils travaillent toujours avec des références à des objets. Ainsi, beaucoup d'opérations dans λπ impliquent le tas, et peu sont purement fonctionnelles. Comme exemple de ce à quoi ressemble une telle opération, construisons une liste. Cela prend les valeurs qui devraient remplir la liste, les stocker dans le segment de mémoire et renvoyer un pointeur sur la référence nouvellement créée:

(E [liste 〈valc, [val ...]] ε Σ) [Liste électronique] (E [@refnew] ε Σ1) où (Σ1 refnew) = alloc (, 〈valc, [val ... ], {})

E-List est un bon exemple pour comprendre la forme de l'évaluation dans λπ. La forme générale de la relation de réduction recouvre les expressions e, les environnements globaux ε et les tas Σ: (e ε) (e ε Σ) Dans la règle E-List, nous utilisons également des contextes d'évaluation E pour imposer un ordre d'opérations et sémantique d'appel enthousiaste. Ceci est une application standard de la sémantique de smallstep de style Felleisen-Hieb [4]. Il est important de noter qu'une nouvelle valeur de liste est générée à partir de l'expression de liste via la métafonction alloc, qu'elle est allouée dans le magasin et que la valeur résultante de l'expression est un pointeur renvoyant à cette nouvelle liste. La figure 3 montre des règles similaires pour les objets en général, les n-uplets et les ensembles. Les listes, les n-uplets et les ensembles ont leur propre forme d'expression, car ils doivent évaluer leurs sous-expressions et avoir des contextes d'évaluation correspondants.

2.2 Accéder aux valeurs intégrées

Maintenant que nous avons créé une liste, nous devrions pouvoir y effectuer certaines opérations, telles que la recherche de ses éléments. λπ définit un certain nombre de primitives intégrées qui modélisent les opérateurs internes de Python pour la manipulation de données. Celles-ci sont utilisées pour accéder au contenu de la mval d’un objet donné. Nous formalisons ces primitives intégrées dans une métafonction δ. La figure 4 illustre quelques cas sélectionnés de la fonction δ. Cette métafonction nous permet, par exemple, de rechercher des valeurs dans des listes intégrées: (prim “list-getitem” (list-getitem ”(% list, [〈% str, ”, {}〉], {} 〈% Int, 0, {}〉)) ==>% str,“ premier-elt ”, {}〉



1