28 votes

Pourquoi coder en tant que données?

Qu'est-ce que le code en tant que données? J'ai entendu dire que c'était supérieur aux "codes en tant que caractères ascii", mais pourquoi? Personnellement, je trouve la philosophie du code comme données un peu déroutante en fait.

J'ai essayé le schéma, mais je n'ai jamais vraiment compris tout le code sous forme de données et je me suis demandé ce que cela signifie exactement.

38voto

I GIVE CRAP ANSWERS Points 12429

Cela signifie que le code de votre programme que vous écrivez est également des données qui peuvent être manipulées par un programme. Prenez un Schéma simple expression comme

(+ 3 (* 6 7))

Vous pouvez le considérer comme une expression mathématique qui lors de l'évaluation donne une valeur. Mais c'est aussi une liste contenant les trois éléments, à savoir d' +, 3 et (* 6 7). En citant la liste,

 '(+ 3 (* 6 7))

Vous dites régime à la considérer comme la dernière, à savoir juste une liste contenant les trois éléments. Ainsi, vous pouvez manipuler cette liste avec un programme et puis de l'évaluer. La puissance qu'il vous donne est un énorme, et quand vous "obtenir" l'idée, il y a des trucs cool à jouer.

29voto

Matthias Benkard Points 11264

Code-comme-les données sont en réalité un seul côté de la médaille. L'autre est de données de code.

La possibilité d'incorporer des données arbitraires dans le code Lisp et de le charger et de le recharger à la volée en fait (les données) très pratique à manipuler, car il peut éliminer toute possibilité d'adaptation d'impédance entre la façon dont les données sont représentées et la façon dont le code fonctionne.

Laissez-moi vous donner un exemple.

Disons que vous voulez écrire une sorte de jeu d'ordinateur avec différents monstre classes. Vous avez essentiellement deux choix: le modèle le monstre classes dans votre langage de programmation ou l'utilisation d'une approche axée sur les données, où les descriptions de classe sont lues à partir de, disons, un fichier XML.

Faire de la modélisation dans le langage de programmation a les avantages de la facilité d'utilisation et la simplicité (qui est toujours une bonne chose). Il est également facile à personnaliser son comportement en fonction du monstre de classe. Enfin, la mise en œuvre est sans doute pas très optimisé.

D'autre part, le chargement de tout à partir de fichiers de données est beaucoup plus souple. Vous pouvez faire de l'héritage multiple où la langue n'a pas de support; vous pouvez faire typage dynamique; vous pouvez charger et recharger les choses au moment de l'exécution; vous pouvez utiliser simple, à-le-point, spécifiques au domaine de la syntaxe, et beaucoup plus. Mais maintenant, vous avez besoin d'écrire une sorte d'environnement d'exécution pour l'ensemble de la chose, et en spécifiant le comportement moyen de fractionnement soit les données entre les fichiers de données et le code du jeu ou intégration d'un langage de script, qui est encore une autre couche de accessoires complexité.

Ou vous pouvez faire le Lisp de la manière: spécifiez votre propre sous-langue, à les transformer en code, et de l'exécuter. Si le langage de programmation que vous utilisez est suffisamment dynamique et flexible du point de vue syntaxique, vous bénéficiez de tous les avantages de l'utilisation d'une approche axée sur les données (depuis le code de données) combinée avec la simplicité de tout garder dans le code (comme les données sont code).

Ce n'est pas spécifique à Lisp, par la manière. Il y a différentes nuances de code-données-équivalence de gris entre Lisp et, disons, C++. Ruby, par exemple, fait de l'incorporation des données dans l'application plus facile que Python n', et Python rend plus facile que Java n'. La fois les données et le code-comme-les données sont de plus de un continuum qu'ils sont soit-ou des questions.

13voto

Rainer Joswig Points 62532

En tant que programmeur Lisp vous apprendre à penser d'un programme comme source de données. Il n'est plus un texte statique, mais les données. Dans certaines formes de Lisp le programme lui-même, c'est que la structure de données, qui est exécuté.

Ensuite, tous les outils sont orientés de cette façon. Au lieu d'un texte macro processeur Lisp a un système de macro qui fonctionne sur les programmes en tant que données. La transformation de programmes et de texte a aussi ses outils.

Nous allons réfléchir à l'ajout de deux éléments d'un vecteur:

(let ((v (vector 1 2 3)))
   (+ (aref v 0)
      (aref v 1)))

Il n'y a rien d'inhabituel à ce sujet. Vous pouvez compiler et l'exécuter.

Mais vous pouvez aussi faire ceci:

(let ((v (vector 1 2 3)))
   (list '+
         (list 'aref v 0)
         (list 'aref v 1)))

Renvoie une liste avec un symbole plus et deux sous-listes. Ces sous-listes ont le symbole de l'aref, puis le tableau de la valeur de v et la valeur de l'indice.

Cela signifie que la construction du programme contient en fait des symboles, mais aussi de données. Le tableau est vraiment une partie de la sous-listes. De sorte que vous pouvez construire des programmes, et ces programmes sont données, et peuvent contenir des données arbitraires.

EVAL évalue ensuite le programme en tant que données.

CL-USER 17 > (setf *print-circle* t)
=>  T

Ci-dessus nous indique que l'imprimante doit imprimer circulaire structures de données telles que les identités sont conservés lors de la lecture en arrière.

CL-USER 18 > (let ((v (vector 1 2 3)))
               (list '+
                     (list 'aref v 0)
                     (list 'aref v 1)))
=>  (+ (AREF #1=#(1 2 3) 0) (AREF #1# 1))

Maintenant, nous allons eval de données comme un programme Lisp:

CL-USER 19 > (EVAL (let ((v (vector 1 2 3)))
                     (list '+
                           (list 'aref v 0)
                           (list 'aref v 1))))

=>  3

Si votre compilateur s'attend à ce texte comme source de on peut construire ces textes, mais ils ne peuvent pas référence directement les données. Pour ces texte en fonction de la source de la construction de nombreux outils ont été développés, mais beaucoup de de ces ont tendance à travailler dans les stades. En Lisp de la fonctionnalité de la manipulation de données peuvent être appliquées directement à manipuler des programmes et cette fonctionnalité est directement intégré et d'une partie du processus d'évaluation.

Donc Lisp vous donne un degré supplémentaire de liberté et de nouvelles façons de penser.

9voto

trptcolin Points 1718

Le code en tant que données fait référence au fait que votre code est exprimé en termes de structures de données de la langue. Je n'essaierais pas d'argumenter ici que c'est la meilleure façon de programmer, mais je trouve que c'est une belle façon d'exprimer les idées du code.

L'un des avantages est que la métaprogrammation est presque la même que la programmation régulière. Avec des caractères codés en tant qu'ascii, vous finissez souvent par devoir effectuer une analyse sérieuse pour faire quoi que ce soit de méta, et vous ignorez ces méchants bits avec Lisp.

6voto

Vijay Mathew Points 17155

Dans le Schéma (ou tout Lisp), vous pouvez déclarer la liste des littéraux comme ceci:

> '(1 2 3)
=> (1 2 3)

Ceci est similaire à de nombreux autres langages de haut niveau, à l'exception de légères différences dans la notation. Par exemple, c'est ainsi que certaines autres langues représentent liste des littéraux:

[1, 2, 3] # Python
#(1 2 3) "Smalltalk. This is in fact an array in Smalltalk. Let us ignore that for now."

Les listes peuvent contenir n'importe quel type de valeurs. Comme les fonctions sont des objets de première classe, une liste peut contenir des fonctions ainsi. Nous allons remplacer le premier élément dans la liste ci-dessus avec une fonction:

> '(+ 2 3)
=> (+ 2 3)

Le guillemet simple (') identifie la liste littérale. (Tout comme le # en Smalltalk). Ce qui va se passer si on enlève le devis? Le Système interprète traiter la liste spéciale. Il examinera le premier élément comme une fonction (ou procédure) et le reste des éléments comme arguments de la fonction. La fonction est exécutée (ou évaluer):

> (+ 2 3)
=> 5

La capacité de représenter le code de l'exécutable à l'aide d'une structure de données dans la langue ouvre une nouvelle possibilité, nous pouvons écrire des programmes qui écrivent des programmes. Cela signifie que, des extensions qui nécessitent des modifications pour le compilateur et le système d'exécution dans d'autres langues pourraient être mises en œuvre en Lisp, que quelques lignes de Lisp lui-même. Imaginez que vous ayez besoin d'une nouvelle structure de contrôle dans votre langue appelée when. Il est similaire à l' if mais rend la lecture du code un peu plus de naturel dans certaines situations:

 (when this-is-true do-this)

Vous pouvez étendre votre système Lisp pour appuyer when par l'écriture d'un court de macro:

 (defmacro when (condition &rest body)
    `(if ,condition (progn ,@body)))

Une macro est rien mais une liste, qui est élargi au moment de la compilation. Plus complexe des structures de la langue ou le même ensemble de paradigmes pourraient être ajoutés à la base de la langue à l'aide de ces listes. Par exemple, le CLOS, le Common Lisp Object Systèmes est essentiellement une collection de macros écrit en Common Lisp lui-même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X