Une façon d'examiner ces deux concepts est de dire que la correspondance de motifs est une caractéristique des langages de programmation permettant de combiner la discrimination sur les constructeurs et la destruction de termes (tout en sélectionnant et en nommant localement des fragments de termes) de manière sûre, compacte et efficace. La recherche sur la correspondance de modèles se concentre généralement sur l'efficacité de la mise en œuvre, par exemple sur la façon de minimiser le nombre de comparaisons que le mécanisme de correspondance doit effectuer.
En revanche, la réécriture de termes est un modèle général de calcul qui étudie un large éventail de méthodes (potentiellement non déterministes) de remplacement de sous-termes d'expressions syntaxiques (plus précisément un élément d'une algèbre de termes sur un ensemble de variables) par d'autres termes. La recherche sur les systèmes de réécriture des termes porte généralement sur les propriétés abstraites des systèmes de réécriture telles que la confluence, le déterminisme et la terminaison, et plus précisément sur la façon dont ces propriétés sont ou ne sont pas préservées par les opérations algébriques sur les systèmes de réécriture, c'est-à-dire dans quelle mesure ces propriétés sont de composition.
Il existe clairement des chevauchements conceptuels entre les deux, et la distinction est dans une certaine mesure traditionnelle plutôt que technique. Une différence technique est que la réécriture des termes se produit dans des contextes arbitraires (c'est-à-dire qu'une règle induit des réécritures pour des contextes arbitraires Et des substitutions ), tandis que la correspondance de motifs dans les langages modernes comme Haskell, OCaml ou Scala ne permet que la réécriture «en haut» d'un terme. Cette restriction est également, je pense, imposée dans le calcul des motifs de Jay. Permettez-moi d'expliquer ce que je veux dire par cette restriction. Avec la correspondance de motifs dans le sens OCaml, Haskell, Scala, vous ne pouvez pas dire quelque chose commeC [ l σ ] → C [ r σ ] C [ . ] σ( l , r )C[ l σ] → C[ r σ]C[ . ]σ
match M with
| C[ x :: _ ] -> printf "%i ...\n" x
| C[ [] ] -> printf "[]"
Qu'y a-t-il C[.]
ici? C'est censé être une variable qui s'étend sur des contextes à trou unique. Mais des langages comme OCaml, Haskell ou Scala ne donnent pas aux programmeurs des variables qui s'étendent sur des contextes arbitraires (un trou), seulement des variables qui s'étendent sur des valeurs. En d'autres termes, dans de telles langues, vous ne pouvez pas appliquer de correspondance de motifs à une position arbitraire dans un terme. Vous devez toujours spécifier le chemin de la racine du motif aux parties qui vous intéressent. Je suppose que la principale raison pour imposer cette restriction est qu'autrement, la correspondance de motifs ne serait pas déterministe, car un terme pourrait correspondre à un motif dans plus d'une façon. Par exemple, le terme (true, [9,7,4], "hello", 7)
correspond au modèle C[7]
de deux manières, en supposant qu'il C[.]
varie dans de tels contextes.