Hallo Robert,
Eine tiefere Erklärung warum MMA eine Fehlermeldung bei [[]] (Part[])
auf ein nichtexistierendes Element bringt und nicht einfach wie beim
indizieren mittels [ ] die Sache unevaluiert belässt ist das alles
nicht.
Einverstanden.
In[4]:= a[[3]]
During evaluation of In[4]:= Part::partd: Part specification a[[3]] is
longer than depth of object. >>
Out[4]= a[[3]]
In[5]:= a[3]
Out[5]= a[3]
Als überwiegend funktionale Programmiersprache sollte in MMA Part[a,3]
sich nicht viel anders als z.B. Sin[3] verhalten, doch selbst wenn ich
mit:
ClearAttributes[Part, {NHoldRest, Protected, ReadProtected}]
alle Attribute von Part lösche hat es ein anders Verhalten als z.B. Sin[]
Warum ist das so ?
In diesem Text sind 3 Themen gleichzeitig angesprochen:
(i) Sin[3] ist definiert, a[[3]] ist nicht definiert, wie bereits gesagt.
(ii) a[3] ist auch nicht definiert, wird aber für assoziative Listen
gebraucht
In[43]:= Array[a, {3}]
Out[43]= {a[1],a[2],a[3]}
In[44]:= With[{m=1},
RSolve[Select[Coefficient[D[Sum[a[i] x^i,{i,n-m,n+m}],x]
-Sum[a[i] k^i x^i,{i,n-m,n+m}],x,n],FreeQ[#,x]&]==0,a[n],n]
]
Out[44]= {{a[n]->(k^(1/2 (-1+n) n) C[1])/Gamma[1+n]}}
(iii) Beim Part[]-Operator steht weiterhin geschrieben
"You can make an assignment like t[[spec]] = value to modify any part or
sequence of parts in an expression."
Zuweisungen können nicht an nicht-existierende Bestandteile von Ausdrücken
gerichtet werden. In prozeduralen Sprachen kommt bei der Zuweisung an
einen nichtexistierenden oder reservierten Ausdruck der Kompilerfehler
"lvalue required as left operand of assignment", Mma weist mit Part::partd
auf diesen Fehler hin. Wenn Mma die o.g. Zuweisung nicht ermöglichen
würde, könnte man den Standpunkt einnehmen, dass a[[3]] = f[1] die
_Definition_ von a[[3]] sein soll, was jedoch - wg. der Bestimmung, dass
a[[0]] immer den Head ausgibt - bei einer wohlgeordneten Indexmenge die
Frage aufwirft, wodurch a[[1]] und a[[2]] repräsentiert sein sollen.
Analog funktionieren die Slot-Operatoren:
In[57]:= f[#4]&[x1, x2, x3]
Function::slotn: Slot number 4 in f[#4]& cannot be filled from
(f[#4]&)[x1,x2,x3]. >>
Out[57]= f[#4]
Übrigens gibt es auch umgekehrte Beispiele:
In[1]:= f=(3+#)&
Out[2]= 3+#1&
In[4]:= f[[1]]
Out[4]= 3+#1
In[5]:= f[[0]]
Out[5]= Function
In[6]:= f[1]
Out[6]= 4
In[7]:= f[1] = 4
During evaluation of In[7]:= Set::write: Tag Function in (3+#1&)[1] is
Protected. >>
Out[7]= 4
In diesem Beispiel existieren Teilausdrücke von f, aber man kann f nicht
mehr als Symbol für eine assoziative Liste verwenden.
Schliesslich
In[27]:= Sin[a[[3]]] /. a[[3]] -> \[Pi]/4
During evaluation of In[27]:= Part::partd: Part specification a[[3]] is
longer than depth of object. >>
During evaluation of In[27]:= Part::partd: Part specification a[[3]] is
longer than depth of object. >>
Out[27]= 1/Sqrt[2]
Das Erscheinen einer Fehlermeldung bedeutet nicht das Ende des
Evaluierungspfades. Insofern schrumpft Ihre Frage darauf zusammen, ob Sie
die Fehlermeldung abschalten oder nicht:
Off[Part::partd]
bewirkt die reine nihilierung Heidegger's
Umgekehrt könnten Sie Sin[] redefinieren, so dass er bei nichtnumerischem
Input eine Fehlermeldung ausgibt. An der Stelle besteht nicht wirklich ein
Problem.
Gruss
Udo.