Eine Möglichkeit, diese beiden Konzepte zu betrachten, besteht darin, zu sagen, dass Pattern Matching ein Merkmal von Programmiersprachen ist, um Diskriminierung nach Konstruktoren zu kombinieren und Begriffe zu zerstören (während Termfragmente sicher, kompakt und effizient ausgewählt und lokal benannt werden). Die Forschung zum Pattern Matching konzentriert sich typischerweise auf die Implementierungseffizienz, z. B. darauf, wie die Anzahl der Vergleiche, die der Matching-Mechanismus durchführen muss, minimiert werden kann.
Im Gegensatz dazu ist das Umschreiben von Begriffen ein allgemeines Berechnungsmodell , das eine breite Palette von (möglicherweise nicht deterministischen) Methoden untersucht, um syntaktische Ausdrücke (genauer gesagt ein Element einer Termalgebra über eine Reihe von Variablen) durch andere Begriffe zu ersetzen. Bei der Erforschung von Term Rewriting-Systemen geht es normalerweise um abstrakte Eigenschaften von Rewriting-Systemen wie Zusammenfluss, Determinismus und Terminierung und insbesondere darum, wie solche Eigenschaften durch algebraische Operationen auf Rewrite-Systemen erhalten werden oder nicht, dh inwieweit diese Eigenschaften kompositorisch sind.
Natürlich gibt es konzeptionelle Überschneidungen zwischen beiden, und die Unterscheidung ist eher traditionell als technisch. Ein technischer Unterschied besteht darin, dass das Umschreiben von Begriffen in beliebigen Kontexten erfolgt (dh eine Regel induziert das Umschreiben von für beliebige Kontexte Und Substitutionen ), während Pattern Matching in modernen Sprachen wie Haskell, OCaml oder Scala ermöglicht nur das Umschreiben "am Anfang" eines Begriffs. Ich denke, diese Einschränkung wird auch in Jays Musterkalkül auferlegt. Lassen Sie mich erklären, was ich mit dieser Einschränkung meine. Mit Pattern Matching im Sinne von OCaml, Haskell, Scala kann man so etwas nicht sagenC [ l σ ] → C [ r σ ] C [ . ] σ( l , r )C[ l σ] → C[ r σ]C[ . ]σ
match M with
| C[ x :: _ ] -> printf "%i ...\n" x
| C[ [] ] -> printf "[]"
Was ist C[.]
hier Es soll eine Variable sein, die sich über einlöchrige Kontexte erstreckt. Sprachen wie OCaml, Haskell oder Scala geben Programmierern jedoch keine Variablen, die sich über beliebige (Ein-Loch-) Kontexte erstrecken, sondern nur Variablen, die sich über Werte erstrecken. Mit anderen Worten, in solchen Sprachen können Sie keine Musterübereinstimmung an einer beliebigen Position in einem Begriff durchführen. Sie müssen immer den Pfad von der Wurzel des Musters zu den Teilen angeben, an denen Sie interessiert sind. Ich denke, der Hauptgrund für diese Einschränkung ist, dass der Mustervergleich ansonsten nicht deterministisch wäre, da ein Begriff möglicherweise mit einem Muster in übereinstimmt mehr als eine möglichkeit. Beispielsweise (true, [9,7,4], "hello", 7)
stimmt der Begriff C[7]
auf zwei Arten mit dem Muster überein , vorausgesetzt, er C[.]
erstreckt sich über solche Kontexte.