Syntax, Atome, Ausdrücke

Everything Is an Expression ist ein wichtiges Motto in Mathematica. In dem eben verlinkten Tutorial heißt es:

Mathematica handles many different kinds of things: mathematical formulas, lists and graphics, to name a few. Although they often look very different, Mathematica represents all of these things in one uniform way. They are all expressions.

Lesen Sie dort weiter!

Die elementaren Ausdrücke, die sich also nicht weiter zerlegen lassen, sind die Symbole, die Zahlen und die Strings. Sie alle heißen Atome. Symbole sind die "elementarsten" benamten Objekte in Mathematica. Der Name eines Symbols besteht aus einer beliebigen Folge von Buchstaben und Ziffern, fängt aber nicht mit einer Ziffer an. Das erste Zeichen kann auch ein  $  sein.  $MachineEpsilon kam z.B. schon auf Seite 20 vor. Klein- und Großschreibung ist zu beachten:

abs		ist ein vom Benutzer definiertes Symbol,
	Abs		ist ein vom System definiertes Symbol,
	$Pre 		ist ein vom System definiertes Symbol.

?$Pre

Zahlen sind Integer,Rational,Real oder Complex und können eine beliebige Anzahl von Ziffern enthalten.

Strings bestehen aus einer in " " eingeschlossenen Folge von Zeichen. Soll dabei ein  "  enthalten sein, so muß  \"  eingetippt werden. Es gibt diverse Funktionen zur Verarbeitung von Strings:

"Dies ist ein Text."

str = "The string."

Characters[ str ]

StringLength[ str ]

In Mathematica reicht eine einzige Regel, um zu beschreiben, wie aus Ausdrücken neue gebildet werden: Für  n > 0 seien  (Subscript[e, 0]),  (Subscript[e, 1]), ... , (Subscript[e, n])  Ausdrücke. Dann ist  (Subscript[e, 0])[ (Subscript[e, 1]), ... , (Subscript[e, n])]  wieder ein Ausdruck. Damit kann jeder Ausdruck ausgehend von Atomen aufgebaut werden. (Subscript[e, 0]) heißt der Kopf  (engl. head) des Ausdrucks;   (Subscript[e, 1]), ... , (Subscript[e, n])  sind die Elemente des Ausdrucks.

Head[ expr ] zeigt den Kopf von expr an:

Head[ a + b + c ]

FullForm[ expr ]  zeigt die “volle Form”, also den Aufbau von  expr  an:

FullForm[ 1 + (x^2) + (((y + z))^2) ]

An diesem Beispiel können Sie gut die Struktur der Ausdrücke bei funktionaler Programmierung erkennen.

Head[ 12345 ]

Head[1.2345]

Head[Head]

Clear[x,k];FullForm[ Expand[ Product[x+k,{k,2}] ]]

{ pp= Product[x+k,{k,2}] ,Expand[pp]}

FullForm[ exprod[ n_Integer ] ]

Die meisten Köpfe von vom System definierten Ausdrücken sind atomar; die Ausdrücke haben also die Gestalt   (Subscript[e, 0])[ (Subscript[e, 1]), ... , (Subscript[e, n])] , mit einem Symbol  (Subscript[e, 0]) . Ich habe bisher im Handbuch nur wenige Stellen gefunden, an denen Ausdrücke die Gestalt  f [g][h]  haben, wobei   f [g][h]  die Bedeutung von  (f [g])[h]  hat.

Beim NEWTONverfahren spielt ein Ausdruck der Gestalt  x – f (x) / f '(x)  eine entscheidende Rolle. In Pascal oder C-Programmen für das NEWTONverfahren muß jeweils eine Routine für  f  und  f '  angegeben werden. In Mathematica vereinfacht sich die Programmierung durch das Konzept der Pure Function. Damit können Ausdrücke übergeben werden und dann als Funktionen übersetzt und weiterverarbeitet werden.  x – f (x) / f '(x)  entspricht daher   (# – f [#] / f' [#] )& . Früher tauchte beim HERONverfahren schon die pure function  ( # / 2 + 1 / # )&  auf.

In Mathematica gibt es das Objekt Function, das die Rolle von pure function spielen kann. f = Function[ variable, expression ] hat die Bedeutung, die in Mathematiktexten mit  f :  variable ↦   expression  dargestellt wird. Function[ variable, expression ]  ist ein Ausdruck für eine Zuordnungsvorschrift.

f = Function[ z,(z^2) ]

ff = ((#)^2)&

{f[1+a],ff[1+b]}

Damit sind auch solche Konstrukte möglich:

Function[ u,Expand[(u^2)]][1+x]

Derivative[1][f][x]  ist einer der wenigen “längeren vordefinierten” Ausdrücke, die ich im Tutorial The Representation of Derivatives gefunden habe.

Clear[f]; f'// FullForm

f'// FullForm  ist ist die Postfix-Notation für  FullForm[ f' ] .

f'[x] // FullForm

Jetzt kommt eine pure function:

Sin'

#1 steht für einen Variablennamen mit der Zählung Eins.

Sin'[x]

Sin''[x] // FullForm

f''[x] // FullForm

Derivative[2][f][x]

Oben war gesagt worden, daß jeder Ausdruck die Form   (Subscript[e, 0])[ (Subscript[e, 1]), ... , (Subscript[e, n])]   hat. Dazu ein Zitat aus Roman MAEDER: Programming in Mathematica, Reading (Mass.): Adddison-Wesley, 1997, 3rd ed., p. 185:

For example, let us try to understand how the expression  Derivative[1][f][x]  is constructed. In this case  n  is 1 and  (Subscript[e, 0]) is the expression  Derivative[1][f]  and  (Subscript[e, 1])  is the expression  x . x  is a symbol and we have reached an atom. Derivative[1][f]  is again built up according our rule, with  n = 1 , (Subscript[e, 0])  being  Derivative[1]  and  (Subscript[e, 1])  being the symbol  f . We need to apply the rule one more time to  Derivative[1] .  (Subscript[e, 0])  is the symbol  Derivative  and  (Subscript[e, 1])  is the number  1 . We have now completly decomposed the expression into building blocks. This decomposition is unique. There is no other way we could have applied the rule.

Derivative[1][f][x]

(Subscript[e, 0 ]) =Derivative[1][f];(Subscript[e, 1])= x;{ (Subscript[e, 0 ]),(Subscript[e, 0 ])[(Subscript[e, 1])]}

(Subscript[ee, 0])=Derivative[1]; (Subscript[ee, 1])= f;{(Subscript[ee, 0]),(Subscript[ee, 0])[ (Subscript[ee, 1])]}

(Subscript[eee, 0])= Derivative; (Subscript[eee, 1])= 1;{(Subscript[eee, 0]), (Subscript[eee, 0])[ (Subscript[eee, 1])]}

Schon mehrfach kamen Ausdrücke vor wie  n_Integer  oder  x_Real . Muster (Pattern) stehen für Klassen von Ausdrücken. Sie enthalten pattern objects, die Teilmengen von zulässigen Ausdrücken darstellen. Ist etwa  s_h  ein Muster-Objekt, dann muss  s  ein Symbol sein und der Kopf  h  kann ein beliebiger Ausdruck sein, der aber kein pattern enthalten darf.

Datentypen

"Expressions are the main type of data in Mathematica" heißt es im Tutorial Basic Objects. 
Typdeklarationen wie etwa in Pascal sind in Mathematica i.A. nicht nötig. Ein Aufschrei der Empörung ist aber nicht angebracht, wie gleich zu sehen ist. 
Listen leisten Liebgewonnenes listenreich!

(Subscript[a, 1]) =1; (Subscript[a, 2])=2;
(Subscript[v, 1])={ 11,12 };(Subscript[v, 2])={ 21, 22 };
(Subscript[m, 1])=IdentityMatrix[ 3 ]; (Subscript[m, 2])=-(Subscript[m, 1]);
(Subscript[d, 1])={ (Subscript[a, 1]),(Subscript[v, 1]),(Subscript[m, 1])};(Subscript[d, 2])={ (Subscript[a, 2]),(Subscript[v, 2]),(Subscript[m, 2]) };
c  = (Subscript[d, 1])+(Subscript[d, 2])

Beachten Sie, wie unterschiedlich  +  operiert.

TableForm[%]

MatrixForm[%]

Analog zu den schon früher erwähnten Funktionen  NumberQ,IntegerQ,VectorQ gibt es z.B. auch StringQ.

?StringQ

t = xyz;{NumberQ[t],LetterQ[t],StringQ[t]}

Head[t]

s = "xyz";{ NumberQ[s], LetterQ[s], StringQ[s] }

Im Tutorial The Meaning of Expressions finden Sie den folgenden Text:

The notion of expressions is a crucial unifying principle in Mathematica. It is the fact that every object in Mathematica has the same underlying structure that makes it possible for Mathematica to cover so many areas with a comparatively small number of basic operations. 
Although all expressions have the same basic structure, there are many different ways that expressions can be used. Here are a few of the interpretations you can give to the parts of an expression. 
[ ... ]
Expressions in Mathematica are often used to specify operations. So, for example, typing in 2 + 3 causes 2 and 3 to be added together, while Factor[x^6 - 1] performs factorization. 
Perhaps an even more important use of expressions in Mathematica, however, is to maintain a structure, which can then be acted on by other functions. An expression like {a, b, c} does not specify an operation. It merely maintains a list structure, which contains a collection of three elements. Other functions, such as Reverse or Dot, can act on this structure. 
The full form of the expression {a, b, c} is List[a, b, c]. The head List performs no operations. Instead, its purpose is to serve as a “tag” to specify the “type” of the structure. 
You can use expressions in Mathematica to create your own structures. For example, you might want to represent points in three-dimensional space, specified by three coordinates. You could give each point as point[x, y, z]. The “function” point again performs no operation. It serves merely to collect the three coordinates together, and to label the resulting object as a point. 
You can think of expressions like point[x, y, z] as being “packets of data”, tagged with a particular head. Even though all expressions have the same basic structure, you can distinguish different “types” of expressions by giving them different heads. You can then set up transformation rules and programs which treat different types of expressions in different ways.

Dazu ein Beispiel, doch nicht mit point, denn es gibt  Point:

p = userpoint[x, y, z]; Head[p]