Ein Trick mit #0
Eine Standardübung in jeder Programmiersprache ist ein sich selbst
reproduzierendes Programm. Bei kompilierten Sprachen bedeutet das
normalerweise ein Programm, das seinen eigenen Programmtext ausgibt.
In interpretierten Sprachen wie Lisp oder Mathematica hat man mehr
Möglichkeiten, da das Programm selber ja auch ein Ausdruck der
jeweiligen Sprache ist. Dafür bietet die unendliche Evaluations-Semantik
wieder ein neues Problem, da ein Asudruck, der zu sich selber evaluiert
entweder trivial ist, oder zu einer unendlichen Iteration führt.
Man kann dann wenigstens etwa erzeugen, das gleich aussieht, wie die
Eingabe, dank Dingen wie HoldForm:
In[1]:= HoldForm[1+1]
Out[1]= 1 + 1
Solche Programme kann man oft mittels reiner Funktionen schreiben, also
in der Form Function[expr][arg]. Damit das sich selber wieder erzeugt,
braucht man Zugriff auf die Funktion selber, wofür der Ausdruck #0 steht
(genauso, wie #1 für das Argument steht), also regeneriert #0[#1] als
expr wieder den ursprünglichen Ausdruck.
Daraus ergibt sich der Ansatz
In[2]:= Function[#0[#1]][arg]
$IterationLimit::itlim: Iteration limit of 4096 exceeded.
Out[2]= Hold[(#0[#1] & )[arg]]
Um die Iteration zu brechen, muss also die Ausgabe in HoldForm[]
eingehüllt werden:
In[3]:= Function[HoldForm[#0[#1]]][arg]
Out[3]= (#0[#1] & )[arg]
Bisher haben wir das Argument noch gar nicht gebraucht, also können wir
damit das HoldForm in die Funktion hineinschmuggeln:
In[4]:= Function[#1[#0[#1]]][HoldForm]
Out[4]= (#1[#0[#1]] & )[HoldForm]
Und wenn wir jetzt noch die Eingabeform so umschreiben, wie sie auch
ausgegeben wird, sind wir fertig:
In[5]:= (#1[#0[#1]] & )[HoldForm]
Out[5]= (#1[#0[#1]] & )[HoldForm]
Noch einen schönen Tag,
Roman Mäder