Jusqu'où peut macros LISP aller?

voix
43

J'ai lu beaucoup de choses que LISP peut redéfinir la syntaxe à la volée, sans doute avec des macros. Je suis curieux de savoir jusqu'où va aller cette réalité? Pouvez-vous redéfinir la structure linguistique, si bien qu'il devient limite un compilateur pour une autre langue? Par exemple, pourriez-vous changer la nature fonctionnelle de LISP dans une syntaxe plus orientée objet et sémantique, peut-être dire d'avoir une syntaxe plus proche de quelque chose comme Ruby?

Surtout, est-il possible de se débarrasser de l'enfer entre parenthèses en utilisant des macros? J'ai appris assez (Emacs-) LISP pour personnaliser Emacs avec mes propres micro-fonctionnalités, mais je suis très curieux de voir comment les macros peuvent aller loin dans la personnalisation de la langue.

Créé 05/08/2008 à 08:32
source utilisateur
Dans d'autres langues...                            


14 réponses

voix
33

Voilà une très bonne question.

Je pense qu'il est nuancé mais certainement répondre:

Les macros ne sont pas coincés dans s-expressions. Voir la macro de boucle pour un langage très complexe écrit en utilisant les mots clés (symboles). Ainsi, alors que vous pouvez commencer et terminer la boucle avec des parenthèses, à l'intérieur il a sa propre syntaxe.

Exemple:

(loop for x from 0 below 100
      when (even x)
      collect x)

Cela étant dit, les macros les plus simples utilisent simplement s-expressions. Et vous seriez « coincé » à les utiliser.

Mais s-expressions, comme Sergio a répondu, commencent à se sentir. La syntaxe sort de la voie et de commencer à coder dans l'arbre de syntaxe.

En ce qui concerne les macros de lecture, oui, vous pourriez peut écrire quelque chose comme ceci:

#R{
      ruby.code.goes.here
  }

Mais vous auriez besoin d'écrire votre propre analyseur de syntaxe Ruby.

Vous pouvez également imiter certains des constructions Ruby, comme des blocs, avec des macros qui compilent aux constructions existantes Lisp.

#B(some lisp (code goes here))

se traduirait

(lambda () (some lisp (code goes here)))

Voir cette page pour savoir comment faire.

Créé 15/09/2008 à 16:07
source utilisateur

voix
20

Oui, vous pouvez redéfinir la syntaxe de sorte que Lisp devient un compilateur. Pour cela, utilisez « macros Reader » qui sont différents de la « Macros compilateur » normal que vous pensez probablement.

Common Lisp a l'installation intégrée pour définir une nouvelle syntaxe pour le lecteur et macros lecteur pour traiter cette syntaxe. Ce traitement se fait à temps lire ( ce qui vient avant ou compiler le temps eval). Pour en savoir plus sur la définition des macros de lecteur en Common Lisp, voir le Common Lisp hyperspec - vous voulez lire Ch. 2, "Syntaxe" et Ch. 23, "Reader" . (Je crois que le schéma a la même facilité, mais je ne suis pas aussi familier avec elle - voir les sources Scheme pour la langue de programmation Arc ).

A titre d'exemple simple, supposons que vous voulez Lisp utiliser des accolades plutôt que des parenthèses. Cela exige quelque chose comme les définitions de lecteur suivantes:

;; { and } become list delimiters, along with ( and ).
(set-syntax-from-char #\{ #\( )
(defun lcurly-brace-reader (stream inchar) ; this was way too easy to do.
  (declare (ignore inchar))
  (read-delimited-list #\} stream t))
(set-macro-character #\{ #'lcurly-brace-reader)

(set-macro-character #\} (get-macro-character #\) ))
(set-syntax-from-char #\} #\) )

;; un-lisp -- make parens meaningless
(set-syntax-from-char #\) #\] ) ; ( and ) become normal braces
(set-syntax-from-char #\( #\[ )

Vous dites que le Lisp {est comme un (et que le} est comme a). Ensuite , vous créez une fonction ( lcurly-brace-reader) que le lecteur appellera chaque fois qu'il voit un {et que vous utilisez set-macro-characterpour attribuer cette fonction à la {. Ensuite , vous dites que Lisp (et) sont comme [et] (c'est pas la syntaxe significative).

D' autres choses que vous pourriez faire comprendre, par exemple, la création d' une nouvelle syntaxe de chaîne ou en utilisant [et] pour enfermer la notation en solution et le transformer en S-expressions.

Vous pouvez aussi aller bien au - delà, la redéfinition de la syntaxe entière avec vos propres caractères macro qui va déclencher des actions dans le lecteur, de sorte que le ciel est vraiment la limite. Ceci est juste l' une des raisons pour lesquelles Paul Graham et d' autres continuer à dire que Lisp est une bonne langue pour écrire un compilateur.

Créé 16/09/2008 à 20:28
source utilisateur

voix
16

Je ne suis pas un expert Lisp, diable, je ne suis même pas un programmeur Lisp, mais après un peu d'expérimenter avec la langue que je suis venu à la conclusion que, après un certain temps la parenthèse commencent à devenir « invisibles » et vous commencez à voir le code comme vous voulez qu'il soit. Vous commencez à prêter plus d'attention aux constructions syntaxiques vous créez via S-exprs et macros, et moins à la forme lexicale du texte des listes et entre parenthèses.

Cela est particulièrement vrai si vous profitez d'un bon éditeur qui aide à la coloration d'indentation et la syntaxe (essayez de régler la parenthèse à une couleur très similaire à l'arrière-plan).

Vous pourriez ne pas être en mesure de remplacer complètement la langue et obtenir la syntaxe « Ruby », mais vous n'avez pas besoin. Merci à la flexibilité de la langue que vous pourriez avoir un dialecte qui se sent comme vous suivez le « style de la programmation Ruby » si vous voulez, peu importe ce que cela signifierait pour vous.

Je sais que cela est juste une observation empirique, mais je pense que j'avais un de ces moments d'illumination Lisp quand j'ai réalisé cela.

Créé 26/08/2008 à 10:49
source utilisateur

voix
15

Maintes et maintes fois, les nouveaux arrivants à Lisp veulent « se débarrasser de toute la parenthèse. » Il dure quelques semaines. Aucun projet de construire une syntaxe sérieuse de programmation général au-dessus de l'analyseur d'habitude S-expression devient jamais nulle part, parce que les programmeurs du vent invariablement préférant ce que vous percevez actuellement comme « l'enfer entre parenthèses. » Il faut un peu pour s'y habituer, mais pas beaucoup! Une fois que vous ne vous y habituer, et vous pouvez vraiment apprécier la plasticité de la syntaxe par défaut, retourner aux langues où il n'y a qu'une seule façon d'exprimer toute construction de programmation particulière est vraiment réseau.

Cela étant dit, Lisp est un excellent substrat pour la construction de langues spécifiques du domaine. Aussi bien, sinon mieux que, XML.

Bonne chance!

Créé 16/09/2008 à 20:29
source utilisateur

voix
12

La meilleure explication des macros Lisp j'ai jamais vu est à

https://www.youtube.com/watch?v=4NO83wZVT0A

À partir d'environ 55 minutes. Ceci est une vidéo d'une conférence donnée par Peter Seibel, l'auteur de « pratique Common Lisp », qui est le meilleur manuel Lisp il est.

La motivation des macros Lisp est généralement difficile à expliquer, parce qu'ils sont vraiment dans leur propre dans des situations qui sont trop longues pour présenter dans un tutoriel simple. Peter arrive avec un excellent exemple; vous pouvez le saisir complètement, et il fait bon, la bonne utilisation des macros Lisp.

Vous avez demandé: « Pourriez-vous changer la nature fonctionnelle de LISP dans une syntaxe plus orientée objet et de la sémantique ». La réponse est oui. En fait, à l'origine Lisp n'a pas de programmation orientée objet du tout, pas surprenant puisque Lisp a été autour depuis bien avant la programmation orientée objet! Mais lorsque nous avons appris POO en 1978, nous avons pu l'ajouter à Lisp facilement, en utilisant, entre autres, les macros. Finalement, le système de Common Lisp Object (CLO) a été mis au point, un système de programmation orienté objet très puissant qui intègre parfaitement dans Lisp. peut être chargé comme une extension du tout - rien est intégré! Tout cela est fait avec des macros.

Lisp a une caractéristique tout à fait différente, appelée « macros lecteur », qui peut être utilisé pour étendre la syntaxe de surface de la langue. En utilisant des macros de lecture, vous pouvez faire sous-langages qui ont une syntaxe de type C ou Ruby-like. Ils transforment le texte en Lisp, en interne. Ceux-ci ne sont pas largement utilisées par la plupart des vrais programmeurs Lisp, principalement parce qu'il est difficile d'étendre l'environnement de développement interactif pour comprendre la nouvelle syntaxe. Par exemple, les commandes d'indentation Emacs seraient désorientés par une nouvelle syntaxe. Si vous êtes énergique, bien que, Emacs est trop extensible, et vous pouvez enseigner à votre nouvelle syntaxe lexicale.

Créé 05/10/2008 à 16:03
source utilisateur

voix
11

Macros fonctionnent régulièrement sur les listes d'objets. Le plus souvent, ces objets sont d' autres listes (formant ainsi des arbres) et des symboles, mais ils peuvent être d' autres objets tels que des chaînes, des objets, hashtables définis par l' utilisateur, etc. Ces structures sont appelées s-exps .

Donc, lorsque vous chargez un fichier source, votre compilateur Lisp analysera le texte et la production s-exps. Les macros fonctionnent sur ces derniers. Cela fonctionne très bien et il est une merveilleuse façon d'étendre le langage dans l'esprit de s-exps.

De plus, le processus d'analyse ci-dessus peut être prolongée par des « macros lecteur » qui vous permettent de personnaliser la façon dont votre compilateur transforme le texte en s-exps. Je suggère, cependant, que vous embrassez la syntaxe de Lisp au lieu de le plier en quelque chose d'autre.

Vous avez l' air un peu confus lorsque vous mentionnez la « nature fonctionnelle » et « la syntaxe orientée objet » Ruby Lisp. Je ne suis pas sûr de ce que « la syntaxe orientée objet » est censé être, mais Lisp est un langage multi-paradigme et il prend en charge la programmation orientée objet extremelly bien.

BTW, quand je dis Lisp, je veux dire Common Lisp .

Je vous suggère de répudier vos préjugés et donner un coup Lisp honnête .

Créé 26/08/2008 à 10:36
source utilisateur

voix
9

Ce que vous demandez est un peu comme demander comment devenir un expert Chocolatier de sorte que vous pouvez supprimer tout ce genre de choses de votre brun infernales gâteau au chocolat préféré.

Créé 17/09/2008 à 13:14
source utilisateur

voix
9

Parenthèse enfer? Je ne vois pas plus parenthèse:

(function toto)

que dans:

function(toto);

Et en

(if tata (toto)
  (titi)
  (tutu))

pas plus que dans:

if (tata)
  toto();
else
{
  titi();
  tutu();
}

Je vois moins crochets et « ; » bien que.

Créé 16/09/2008 à 17:23
source utilisateur

voix
6

Oui, vous pouvez changer fondamentalement la syntaxe, et même échapper « l'enfer entre parenthèses ». Pour cela, vous devrez définir une nouvelle syntaxe du lecteur. Regardez dans les macros de lecteur.

Je suspectons toutefois que pour atteindre le niveau d'expertise Lisp pour programmer ces macros que vous aurez besoin de vous immerger dans la langue à tel point que vous ne plus considérer Parenthese « l'enfer ». -À-dire le temps que vous savez comment les éviter, vous venez de les accepter comme une bonne chose.

Créé 15/09/2008 à 13:07
source utilisateur

voix
2

voir cet exemple de la façon dont les macros de lecteur peuvent étendre le lecteur Lisp avec des tâches complexes comme XML templating:

http://common-lisp.net/project/cl-quasi-quote/present-class.html

cette bibliothèque utilisateur compile les parties statiques de la XML en UTF-8 codé tableaux d'octets littéral au moment de la compilation qui sont prêtes à être écriture sequence'd dans le flux de réseau. et ils sont utilisables dans les macros Lisp normales, ils sont orthogonaux ... le placement des influences de caractère par des virgules quelles parties sont constantes et qui devraient être évalués lors de l' exécution.

plus de détails disponibles à: http://common-lisp.net/project/cl-quasi-quote/

un autre projet que pour les extensions de syntaxe Common Lisp: http://common-lisp.net/project/cl-syntax-sugar/

Créé 17/09/2008 à 01:30
source utilisateur

voix
2

Si vous voulez Lisp ressembler à Ruby utiliser Ruby.

Il est possible d'utiliser Ruby (et Python) d'une manière très Lisp comme ce qui est l'une des principales raisons pour lesquelles ils ont gagné l'acceptation si rapidement.

Créé 05/08/2008 à 08:40
source utilisateur

voix
1

L'une des utilisations de macros qui ont fait sauter mon esprit était la vérification de compilation des requêtes SQL contre DB.

Une fois que vous réalisez que vous avez la langue complète à portée de main lors de la compilation, il ouvre de nouvelles perspectives intéressantes. Ce qui signifie que vous pouvez également vous tirer dans le pied de nouvelles façons intéressantes (comme rendant la compilation non reproductibles, ce qui peut très facilement se transformer en un cauchemar de débogage).

Créé 19/09/2008 à 11:43
source utilisateur

voix
1

Il est une question délicate. Depuis Lisp est déjà structurellement si près d'un arbre d'analyse syntaxique la différence entre un grand nombre de macros et mettre en œuvre votre propre mini-langue dans un générateur d'analyseur est pas très claire. Mais, à l'exception des paren d'ouverture et de fermeture, vous pouvez très facilement vous retrouver avec quelque chose qui ne ressemble en rien Lisp.

Créé 06/08/2008 à 13:14
source utilisateur

voix
1

@sparkes

Parfois, LISP est le choix de langage clair, à savoir les extensions Emacs. Je suis sûr que je pourrais utiliser Ruby pour étendre Emacs si je voulais, mais Emacs a été conçu pour être étendu avec LISP, donc il semble logique de l'utiliser dans cette situation.

Créé 05/08/2008 à 08:45
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more