<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">

<channel>
<title><![CDATA[Perl 6: Perl 6 Tutorial Part 3]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_3</link>
<description></description>
<pubDate>Fri, 06 Aug 2010 23:47:26 -0000</pubDate>
<webMaster>synedra@gmail.com</webMaster>
<generator>Socialtext Workspace v2.14.7.2</generator>

<item>
<title><![CDATA[Perl 6 Tutorial Part 3]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_3</link>
<description><![CDATA[<div class="wiki">
<div class="nlw_phrase"><table class='toc'><tr><td><div class="wiki">
<h3 id="contents">Contents: []</h3>
<ul>
<li><span class="nlw_phrase"><a title="section link" href="#arrays_in_perl">Arrays in Perl</a><!-- wiki: {link: [] Arrays in Perl} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#f_C3_BCttern_der_arrays">Füttern der Arrays</a><!-- wiki: {link: [] Füttern der Arrays} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#es_lebe_die_faulheit">Es lebe die Faulheit</a><!-- wiki: {link: [] Es lebe die Faulheit} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#die_raubtierf_C3_BCtterung_geht_weiter">Die Raubtierfütterung geht weiter</a><!-- wiki: {link: [] Die Raubtierfütterung geht weiter} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#giga_hyper_meta">Giga, Hyper, Meta ...</a><!-- wiki: {link: [] Giga, Hyper, Meta ...} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#und_noch_ein_blick_in_die_quantenwelt">Und noch ein Blick in die Quantenwelt</a><!-- wiki: {link: [] Und noch ein Blick in die Quantenwelt} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#danke">Danke</a><!-- wiki: {link: [] Danke} --></span></li>
</ul>
</div>
</td></tr></table><!-- wiki: {toc: } --></div><br /><br /><h3 id="arrays_in_perl">Arrays in Perl</h3>
<p>
Und wie angekündigt geht es in dieser Folge um Operatoren, die den Umgang mit<br />
Arrays erleichtern. Hier hat Perl 6 sehr zugelegt. Zwar zeichnet sich Perl 5<br />
durch sehr einfach und vielseitig verwendbare Arrays aus, die zudem mit 'map',<br />
'grep' und 'for' sehr flexibel bearbeitet werden können (das gibt es natürlich<br />
auch alles weiterhin), aber besonders funktionale Sprachen wie Haskell haben in<br />
den letzten Jahren gezeigt, daß auf dem Gebiet weit mehr möglich ist. Und es war<br />
auch die durch Pugs herbeigeführte, enge Zusammenarbeit von Haskell-Programmierern<br />
und dem Design-Team, die auf diesem Gebiet deutliche Spuren im Perl 6-Syntax<br />
hinterlassen hat. Darüber hinaus hat sich ebenso grundlegendes in der Schreibweise<br />
der Arrays geändert, daß damit nichts zu tun hat.</p>
<p>
Als Perl noch klein war und auf Larrys Wickeltisch lag, gab es nur einzelne Werte<br />
und einfache Listen oder Hashes als Spielzeug. Um sie gut unterscheiden zu können,<br />
bekamen sie als Erkennungssymbol die Sigil $, @ und %. Da aber Arrays und Hashes<br />
auch einzelne Werte abliefert können und Hashes sogar Arrays von Werten, entschied<br />
Larry, es sei besser in diesen Fällen die Sigil zu ändern, um immer zu sehen, ob<br />
man es grad mit einen oder mehrere Werten zu tun hat. (Hashes sind ja in Perl 5<br />
bloß Arrays mit gerader Länge.) Mit 7 Jahren erhielt Perl jedoch zur Einschulung<br />
Referenzen. Das war gut, denn nun konnte es komplexe Datenstrukturen erzeugen,<br />
was für größere Schulaufgaben wichtig ist. Aber damit verloren die veränderlichen<br />
Sigils ihren ursprünglichen Sinn, denn &quot;$fibo[7]&quot; konnte nun auch (eine Referenz<br />
auf) einen Array oder einen Hash zurückgeben. Und auch das Dereferenzieren mit<br />
geschweiften Klammern wie bei &quot;@a = @{$fibo[7]}&quot; kann zu komplexen Ausdrücken<br />
führen, die Anfänger verwirren. Deshalb haben Variablen in Perl 6 unveränderliche<br />
Sigils. Zu deutsch: eine Arrayvariable beginnt immer mit einem '@'. Damit bleibt <br />
wenigstens der Typ der Variable sichtbar. Zusätzlich vereinfacht das Dinge wie:</p>
<p>
	Perl 5: Perl 6:<br />
	@gerade = @{$zahlen[4]}; @gerade = @zahlen[4];<br />
	$zahl = $halde-&gt;<a href="http://www.perlfoundation.org/perl6/index.cgi?3" title="[click to create page]" class="incipient">3</a><a href="http://www.perlfoundation.org/perl6/index.cgi?4" title="[click to create page]" class="incipient">4</a><a href="http://www.perlfoundation.org/perl6/index.cgi?5" title="[click to create page]" class="incipient">5</a>; $zahl = $halde[3;4;5];</p>
<p>
Diese Beispiele zeigen: den Kontext bestimmt jetzt vor allem der Empfänger der<br />
Daten. Erhält ein Array eine Arrayref, dereferenziert Perl 6 automatisch. Weist<br />
man einem Array einen Skalar zu, hat er nur noch einen (neuen) Wert. Wird einem<br />
Skalar ein Array zugewiesen, so wird er zur Arrayref (ich mein natürlich Capture),<br />
die behandelt werden kann wie ein Array, auch wenn sie die Sigil $ hat. (Fast wie<br />
ein Array in PHP.)</p>
<p>
In Teil 2 wurde vorgestellt, daß ebenso Operatoren den Kontext bestimmen können.<br />
Auch hier erzwingt &quot;~&quot; den Stringkontext, was der Aneinanderreihung der Inhalte<br />
aller Elemente entspricht (selbstverständlich durch Leerzeichen getrennt). Und das<br />
&quot;+&quot; fordert den numerischen Kontext, in dem ein Array die Anzahl seiner Elemente<br />
liefert, in gleicher Weise wie Perl 5-Arrays im skalaren Kontext. Dafür gibt es<br />
noch einen objektorientierten, expliziteren Syntax:</p>
<p>
	Perl 5: Perl 6:<br />
	scalar @gerade; +@gerade; # Elementenanzahl<br />
	scalar @gerade; @gerade.elems; # geht auch<br />
	$#rray; @rray.end; # letzter Index</p>
<p>
Doch auch für das &quot;~@a&quot; wurde noch eine Schreibweise geschaffen, da innerhalb von<br />
doppelten Anführungsstrichen Arrays und Hashes nicht automatisch expandieren. Dies<br />
soll eine einfache Ausgabe von Mailadressen und Prozentangaben ermöglichen.</p>
<p>
Perl 6:<br />
	say @namen;<br />
	say &quot;meine Adresse: <a href="mailto:ich@namen.de">ich@namen.de</a>&quot;;</p>
<p>
Möchte man die Ausgabe der oberen Zeile innerhalb einer Angabe geht das nun auch<br />
so:</p>
<p>
Perl 6:<br />
	say &quot;Die taoistischen Unsterblichen sind: @namen[]&quot;;</p>
<p>
Auch die Ausgabe einzelner Arraywerte kann Umsteiger anfangs ratlos machen, denn<br />
z.B. das vorletzte Element fordert man jetzt mit &quot;@a[*-2]&quot; an. Der Stern bedeutet<br />
jetzt in fast jedem Kontext so etwas wie &quot;alles&quot;, &quot;unendlich&quot;, &quot;irgendetwas&quot; oder<br />
&quot;Grenzwert&quot;. Damit möchte ich aber die Einweisung in Perl 6-Arrays beenden, da<br />
eigentlich die Operatoren das aktuelle Thema sind.</p>
<h3 id="f_C3_BCttern_der_arrays">Füttern der Arrays</h3>
<p>
Das einfache füllen eines Arrays geht wie gewohnt:</p>
<p>
Perl 6:<br />
	my @noten = ('Do', 'Re', 'Mi', 'Fa', 'Sol', 'La', 'Si');</p>
<p>
Die runden Klammern können weggelassen werden, da das Komma jetzt arrayerzeugender<br />
Operator ist. Sonst würde im nächsten Beispiel gerade mal &quot;Si&quot; in &quot;@noten[0]&quot; landen.</p>
<p>
Perl 6:<br />
	my @noten = 'Re', 'Mi', 'Fa', 'Sol', 'La', 'Do', 'Si';</p>
<p>
Aber so würde es wohl auch kein geübter Perlautor schreiben, denn es gibt ja qw().<br />
Gibt es das noch? So etwas praktisches und nützliches wurde nicht nur behalten,<br />
sondern auch in der Schreibweise vereinfacht.</p>
<p>
Perl 6:<br />
	my @noten = &lt;Re Mi Fa Sol La Do Si&gt;;<br />
	my @tiere = &lt;&lt; $baer $hase $igel &gt;&gt;;</p>
<p>
Im vorigen Teil hatte ich ja schon erwähnt das es von &quot;&lt;&gt;&quot; noch eine Version gibt,<br />
die interpoliert. Die Namensgebung lehnt an '' und &quot;&quot; an, wo auch die &quot;doppelte&quot;<br />
Version interpoliert (Variablennamen mit ihren Inhalt ersetzt). Diese Schreibweise <br />
ist auch praktisch wenn dem Array Werte eines Hashes zugewiesen werden.</p>
<p>
Perl 6:<br />
	my @ausgaben = %rechnung&lt; alfred hein peter &gt;;<br />
	my @ausgaben = %rechnung&lt;&lt; @namen[] &gt;&gt;;</p>
<p>
Hashschlüssel wurden zwar vorher auch oft nicht gequotet aber sowas tun nur Rüpel,<br />
da barewords bekanntermaßen böse und hinterhältig sind und liebe Programmierer<br />
immer strict verwenden. In Perl 6 hat man hier keine Wahl, da strictness default<br />
ist, und es keine Bareword-Stringliteral mehr gibt.</p>
<p>
Auch die altbekannten Rangeoperatoren kann man immer noch zum befüllen von Arrays <br />
verwenden:</p>
<p>
Perl 6:<br />
	my @ziffern = 0 .. 9; # 0,1,2,3,4,5,6,7,8,9<br />
	my @buchst ='a'..'z'; # &lt;a b c d e f ... y z&gt;</p>
<p>
Ersteres kann man aber jetzt noch kürzer schreiben:</p>
<p>
Perl 6:<br />
	my @einer = ^10; # 0,1,2,3,4,5,6,7,8,9</p>
<p>
Ja genau, das Dach schließt das ihm Folgende als Grenzwert aus und die 0 wird<br />
standartmäßig als untere Schranke angenommen. Dieses Konstrukt hat vor allem zwei<br />
praktische Anwendungen. Im Skalarkontext kann man damit Bereiche definieren, deren<br />
Schranken nicht zur Menge gehören, aber auch einfache for-Schleifen können so<br />
noch um ein paar Anschläge kürzer geschrieben werden:</p>
<p>
Perl 6:<br />
	3 ~~ 3^.. 7; # gibt Bool::False<br />
	for ^5 { ... } # iteriert 5 mal</p>
<p>
Und da wir grad bei Schleifen sind: Wie oft wollten Perl 5-Programmierer die<br />
Iteratorvariable in Sprüngen oder rückwärts zählen lassen. Dies geht nun alles<br />
sehr einfach:</p>
<p>
Perl 6:<br />
	for ^10:by( 2) {...}; # 0,2,4,6,8<br />
	for 4..1:by(-1) {...}; # 4,3,2,1</p>
<p>
Selbstverständlich ist &quot;by&quot; kein Spezialbefehl für Schleifen, sondern kann immer<br />
für Bereiche (Ranges) eingesetzt werden. Wem es überhaupt nicht gefällt, kann im<br />
zweiten Beispiel auch auf reverse zurückgreifen, denn '4..1' evaluiert zu einer<br />
leeren Menge oder einem leeren Zahlenbereich.</p>
<p>
Perl 6:<br />
	for reverse 1..4 {...}; # 4,3,2,1</p>
<h3 id="es_lebe_die_faulheit">Es lebe die Faulheit</h3>
<p>
Die Menge die ein Perl 6-Array speichert, kann aber nicht nur leer sein, sondern<br />
auch unendlich groß. Dafür braucht es nicht einmal unendlich viel RAM. Es reicht<br />
vollkommen ihn wie folgt als unendlich zu bestimmen:</p>
<p>
Perl 6:<br />
	@zahlen = 5 .. Inf; # von 5 bis Unendlich<br />
	@zahlen = 5 .. <strong>; # das Selbe<br />
	@zahlen =</strong> .. *; # aka -Inf .. +Inf</p>
<p>
Inf (gibt es in den Varianten +Inf und -Inf) oder * steht hier für Unendlich und<br />
es ist auch ein mathematisch korrektes Inf, daß Perl 6 zurückgibt wenn man eine<br />
Division duch 0 versucht. Aber wie funktionieren die letztgenannten Beispiele?<br />
Perl 5 hätte hier unsanft angemeldet &quot;Range iterator outside integer range at ...&quot;,<br />
Perl 6 expandiert jedoch den Array erst wenn er tatsächlich gebraucht wird und<br />
dann auch nur bis zu dem benötigten Element. Diese &quot;lazy evaluation&quot; gehört zu den<br />
Einflüssen funktionaler Sprachen wie Haskell in Perl 6, die ich zu Begin ansprach.<br />
Sie bewirkt, daß eine &quot;for&quot;-Schleife, die über &quot;@zahlen&quot; iteriert, so lange läuft,<br />
bis ein Sprungbefehl das Verlassen der Schleife erzwingt oder das Betriebsystem<br />
aufhört zu arbeiten. Doch im Gegensatz zu Haskell gilt für Perl immer noch TIMTOWTDI.<br />
Wer seine Listen sofort expandiert haben möchte, kann dies mit &quot;eager&quot; erzwingen.</p>
<p>
Perl 6:<br />
	@zahlen = eager 5..*; # jetzt hängt das programm wirklich<br />
	$zahl = lazy &quot;$text:&quot; ~ berechne();</p>
<p>
Im Gegenzug ist es auch möglich mit &quot;lazy&quot; die &quot;lazy evaluation&quot; zu erzwingen, wo<br />
Perl per default &quot;eager&quot; evaluiert, wie bei einer Zuweisung in den Skalarkontext.<br />
Es empfiehlt sich jedoch dabei aufzupassen, da die Variable oder die Routine in<br />
dem Beispiel zu einem späteren Zeitpunkt andere Werte liefern können. Überhaupt<br />
erfordert die &quot;lazy evaluation&quot; etwas mehr Aufmerksamkeit um genau zu erkennen,<br />
wann etwas ausgeführt wird. Das folgende Beispiel filtert die numerisch geraden<br />
Zahlen aus einem Array und überweist sie in einen zweiten Array. Der verwendete<br />
feed-Operators dient der Weiterreichung von Arrayelementen um etwa Schwartz'sche<br />
Transformationen und ähnliches explizit zu formulieren. Neu daran ist, daß die<br />
Werte einzeln &quot;@out&quot; verlassen um sogleich das ganze Fließband an Befehlen zu<br />
passieren und im &quot;@in&quot; zu verschwinden. Im dritten Beispiel würde die gerade Zahl<br />
also zuerst halbiert und in &quot;@in&quot; gespeichert, bevor der nächste Wert aus &quot;@out&quot;<br />
entnommen wird. Diese häppchenweise Arbeitsweise gab den feed-ops ihren Namen.<br />
Das vierte Beispiel demonstriert, daß sie von links nach rechts zuweisen können<br />
und daß sich die Taktstraße auch aus mehreren Quellen speisen kann. Wegen der<br />
Schreibweise &quot;==&gt;&gt;&quot; folgt dem letzten Element aus &quot;@out1&quot; das erste Element aus<br />
&quot;@out2&quot;.</p>
<p>
Perl 6:<br />
	@in = grep { $%2 } &lt;== @out;<br />
	@in = grep { $%2 }, @out; # funktionsgleich<br />
	@in = map {$_ / 2} &lt;== grep { $_%2 } &lt;== @out;<br />
	@out1 ==&gt;&gt; @out2 ==&gt;&gt; grep { /\s/ } ==&gt; @in;</p>
<p>
Selbstverständlich unterbricht ein &quot;eager&quot; oder &quot;sort&quot; die &quot;lazy evaluation&quot; in<br />
solchen Befehlsfolgen.</p>
<p>
Befehle wie push, pop, shift und splice, die auch dafür geeignet sind, Arrays zu<br />
füttern, werden bereits genügend in der perldoc beschrieben. Bis auf Nuancen hat<br />
sich für diese Befehle nichts geändert, weswegen sie hier nicht erklärt werden.</p>
<h3 id="die_raubtierf_C3_BCtterung_geht_weiter">Die Raubtierfütterung geht weiter</h3>
<p>
Wenn einem grad nichts einfällt, kann ein Array natürlich auch mit Wiederholungen<br />
eines Wertes gefüllt werden:</p>
<p>
Perl 6:<br />
	@affen = &quot;gibbon&quot; xx 5;<br />
	# mir ist doch noch was eingefallen<br />
	@affen = &lt;gibbon makake&gt; xx 3;</p>
<p>
Anders als in Perl 5.10 unterscheidet &quot;x&quot; hier keinen Kontext. Es wiederholt, wie<br />
in der vorigen Folge gezeigt, immer einen String und erzeugt einen meist längeren<br />
String. &quot;xx&quot; wiederholt immer eine Liste, selbst wenn sie nur ein Element hat.<br />
Die Ergebnisse werden dann auch, wie anfangs beschrieben, an den Kontext des<br />
Empfängers angepasst. Was Perl 5 leider auch nicht kennt, ist das große &quot;X&quot;, der<br />
Kreuzoperator. Ohne Schleifen und Zusatzmodule können damit alle Kombinationen<br />
der Elemente mehrer Arrays erzeugt werden. Wichtigste Regel ist hier dabei, daß<br />
der linke Array vorrang hat, also zuerst alle Paare mit dem ersten linken Element<br />
gebildet werden, dann mit dem zweiten usw.</p>
<p>
Perl 6:<br />
	1,2 X 3,4 # (1,3),(1,4),(2,3),(2,4)</p>
<p>
Wie das Resultat aufgelöst wird, hängt wieder vom Kontext ab, wobei es an der Zeit<br />
ist, einen neuen, interessanten Kontext vorzustellen. Der &quot;slice&quot;-Kontext, erkennbar<br />
an seiner Sigil &quot;@@&quot;, verweist auf Arrays, die wiederum Arrayreferenzen enthalten.<br />
Slice bedeutet soviel wie Arraystück oder Scheibe. Der einfache Arraykontext würde<br />
einen flachen Array erzeugen. Oft möchte man das gerade nicht.</p>
<p>
Perl 6:<br />
	 $ 1,2 X 3,4 # <a href="http://www.perlfoundation.org/perl6/index.cgi?%5C(1%2C3)%2C%5C(1%2C4)%2C%5C(2%2C3)%2C%5C(2%2C4)" title="[click to create page]" class="incipient">\(1,3),\(1,4),\(2,3),\(2,4)</a><br />
	 @ 1,2 X 3,4 # 1,3,1,4,2,3,2,4<br />
	@@ 1,2 X 3,4 # <a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C3" title="[click to create page]" class="incipient">1,3</a>,<a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C4" title="[click to create page]" class="incipient">1,4</a>,<a href="http://www.perlfoundation.org/perl6/index.cgi?2%2C3" title="[click to create page]" class="incipient">2,3</a>,<a href="http://www.perlfoundation.org/perl6/index.cgi?2%2C4" title="[click to create page]" class="incipient">2,4</a></p>
<p>
Genauso kontextsensitiv ist auch der &quot;zip&quot; Operator, der ebenfalls aus bestehenden<br />
Arrays neue zusammenstellen kann. Er wird &quot;zip&quot; oder &quot;Z&quot; geschrieben und aus der<br />
zweiten Schreibweise läßt sich auch sein Vorgehen ableiten. (Man nehme zuerst ein<br />
Element aus dem linken Array, dann das erste aus dem rechten. Dann wieder zum <br />
ersten und zurück ... ). Zip heißt zu deutsch Reißverschluss, was den Mechanismus<br />
auch gut beschreibt.</p>
<p>
Perl 6:<br />
	 $ 1,2 Z 3,4 # <a href="http://www.perlfoundation.org/perl6/index.cgi?%5C(1%2C3)%2C%5C(2%2C4)" title="[click to create page]" class="incipient">\(1,3),\(2,4)</a><br />
	 @ 1,2 Z 3,4 # 1,3,2,4<br />
	@@ 1,2 Z 3,4 # <a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C3" title="[click to create page]" class="incipient">1,3</a>,<a href="http://www.perlfoundation.org/perl6/index.cgi?2%2C4" title="[click to create page]" class="incipient">2,4</a><br />
	 % 1,2 Z 3,4 # { 1 =&gt; 3, 2 =&gt; 4 }</p>
<p>
Besonders für die parallele Verarbeitung mehrer Arrays in einer Schleife ist das<br />
sehr praktisch. Dies zeigt allerdings die nächste Folge des Tutorials, weil es<br />
noch Wissen zu den inneren Verhaltensweisen anonymer Blöcke verlangt, was weit<br />
außerhalb des heutigen Themas liegt.</p>
<p>
Sowohl der Kreuz- als auch der Reißverschlussoperator kann mehrfach verkettet<br />
werden, die Ergebnisse werden lediglich entsprechend komplexer.</p>
<p>
Perl 6:<br />
	1,2 X 3,4 X 5,6 # (1,3,5),(1,3,6) ...</p>
<h3 id="giga_hyper_meta">Giga, Hyper, Meta ...</h3>
<p>
Mit dem großen Kreuz lässt sich sogar noch weit mehr anstellen wenn es circumfix<br />
(umschließend wie Klammern) um einen anderen Operator gesetzt wird. Dies eröffnet<br />
das völlig neue Feld der Metaoperatoren für Arrays. Operatoren für Skalare können<br />
somit auf Listen angewendet werden und für die Fülle der neuen Möglichkeiten muß<br />
niemand lange Listen an neue Befehlen lernen. Es reicht völlig die Arbeitsweise<br />
der drei Metaoperatoren zu verstehen.</p>
<p>
Der Kreuz-Metaoperator funktioniert auch fast wie der einfache Kreuzoperator. Auf<br />
jedes Kombinationspaar wird lediglich der rechte Operator angewendet. Am Beispiel<br />
ist das leicht nachvollziehbar:</p>
<p>
Perl 6:<br />
	&lt;a b&gt; X~ &lt;1 2&gt; # &lt;a1 a2 b1 b2&gt;<br />
	&lt;1 2 3&gt; X* &lt;2 3&gt; # &lt;2 3 4 6 6 9&gt;</p>
<p>
Der praktische Nutzen von solchem Code ist nicht nur daß er mindestens 5 Zeilen<br />
Perl 5 ersetzt, sondern daß er dem Interpreter auch erlaubt die Arbeitsschritte<br />
auf mehrere Prozessoren(kerne) zu verteilen, da es auch nicht darauf ankommt in<br />
welcher Reihenfolge die Werte berechnet werden, solang sie in der erwarteten<br />
Reihenfolge ankommen. Genau diese Parallelisierung der Datenverarbeitung erlaubt<br />
auch der nächste Metaop: der Hyperoperator. Er besteht aus zwei &quot;&gt;&quot; oder &quot;&lt;&quot;, kann<br />
aber auch mit den UTF-Symbolen namens Chevron geschrieben werden, welche genauso<br />
aussehen. Wie zu erwarten, war das Gegenstand kräftiger Diskussionen, während der<br />
Larry Wall seinen Standpunkt verteidigte: &quot;UTF ist schon lange Standart und man<br />
solle die Verwendung von UTF wenigstens ermöglichen. Alle &quot;UTF-Operatoren&quot; sind<br />
ohnehin optional und Perl 6-Quellcode wird intern eh immer als Unicode angesehen.&quot;</p>
<p>
Der klassische Anwendungsfall für Hyperoperatoren besteht darin, die ersten Werte<br />
zweier Arrays als Operanden zu verwenden und das Resultat als ersten Wert im<br />
Ergebnisarray zu speichern. Nächste Operanden sind die jeweils zweiten Werte u.s.w.<br />
Sind beide Arrays unterschiedlich lang wird mit leeren Werten aufgefüllt</p>
<p>
Perl 6:<br />
	@reste = &lt;5 3 7&gt; &gt;&gt;%&lt;&lt; &lt;2 7 5&gt;; # &lt;1 3 2&gt;<br />
	@summen = &lt;2 3 4&gt; &gt;&gt;+&lt;&lt; 1; # &lt;3 3 4&gt;</p>
<p>
Möchte man einen einzelnen Wert auf eine Liste anwenden, so reicht es, die Richtung<br />
des Hyperoperators umzukehren.</p>
<p>
Perl 6:<br />
	&lt;5 3 7&gt; &gt;&gt;+&gt;&gt; 1; # &lt;6 4 8&gt;</p>
<p>
Das breite Ende der Pfeile zeigt an, welche Seite die Dimension des Ergebnises<br />
bestimmt. Hätte das letzte Beispiel Variablen benutzt, ließe es sich aber noch<br />
elegant verkürzen.</p>
<p>
Perl 6:<br />
	@a = @a &gt;&gt;+&gt;&gt; 1;<br />
	@a &gt;&gt;+=&gt;&gt; 1; # dito<br />
	@a &gt;&gt;++; # noch kürzer</p>
<p>
Sehr nützlich ist auch, daß Hyperoperatoren sehr gut mit mehrdimensionalen Arrays<br />
umgehen können.</p>
<p>
Perl 6:<br />
	-« [<a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C%202" title="[click to create page]" class="incipient">1, 2</a>, 3] # [<a href="http://www.perlfoundation.org/perl6/index.cgi?-1%2C%20-2" title="[click to create page]" class="incipient">-1, -2</a>, -3]<br />
	[<a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C%202" title="[click to create page]" class="incipient">1, 2</a>, 3] »+» <a href="http://www.perlfoundation.org/perl6/index.cgi?4%2C%205%2C%206" title="[click to create page]" class="incipient">4, 5, 6</a> # [<a href="http://www.perlfoundation.org/perl6/index.cgi?5%2C%207" title="[click to create page]" class="incipient">5, 7</a>, 9]<br />
	[<a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C%202" title="[click to create page]" class="incipient">1, 2</a>, 3] «+» <a href="http://www.perlfoundation.org/perl6/index.cgi?4%2C%20%5B5%2C%206" title="[click to create page]" class="incipient">4, [5, 6</a>]<br />
	# == [<a href="http://www.perlfoundation.org/perl6/index.cgi?1%2C2" title="[click to create page]" class="incipient">1,2</a> «+» 4, 3 «+» <a href="http://www.perlfoundation.org/perl6/index.cgi?5%2C%206" title="[click to create page]" class="incipient">5, 6</a>] == [<a href="http://www.perlfoundation.org/perl6/index.cgi?5%2C%206" title="[click to create page]" class="incipient">5, 6</a>, <a href="http://www.perlfoundation.org/perl6/index.cgi?8%2C%209" title="[click to create page]" class="incipient">8, 9</a>]</p>
<p>
Im zweiten Beispiel bestimmt die linke Seite, wegen der Richtung der Operatoren,<br />
die Dimensionalität. Beim dritten ist es keine Seite und so wird auch jedes slice<br />
als Element angesehen und entsprechend &quot;ausmultipliziert&quot;.</p>
<p>
Die dritte Klasse an Metaoperatoren sind die Reduktionsoperatoren. Ihr Name ist<br />
redlich verdient, da sie die Dimension ihres Operanden reduzieren, oder zu deutsch:<br />
Sie machen aus einem Array einen Skalar, indem sie alle Arrayelemente miteinander<br />
anwenden. Reduktionsoperatoren werden in eckigen Klammern geschrieben.</p>
<p>
Perl 6:<br />
	<a href="http://www.perlfoundation.org/perl6/index.cgi?%2B" title="[click to create page]" class="incipient">+</a> 1..4 # 10 = 1+2+3+4<br />
	<a href="http://www.perlfoundation.org/perl6/index.cgi?~" title="[click to create page]" class="incipient">~</a> 'a'..'f' # 'abcdef'</p>
<p>
Trickreich und effektiv lassen sie sich auch mit Vergleichs- und Auswahloperatoren<br />
kombinieren.</p>
<p>
Perl 6:<br />
	$sorted = <a href="http://www.perlfoundation.org/perl6/index.cgi?%3C" title="[click to create page]" class="incipient"><</a> @a # wahr wenn sortiert<br />
	$wert = <a href="http://www.perlfoundation.org/perl6/index.cgi?%7C%7C" title="[click to create page]" class="incipient">||</a> @a # erster nicht leerer Wert im Array<br />
	$min = <a href="http://www.perlfoundation.org/perl6/index.cgi?min" title="[click to create page]" class="incipient">min</a> @zahlen # @zahlen.min ginge auch<br />
	$min, $max = <a href="http://www.perlfoundation.org/perl6/index.cgi?minmax" title="[click to create page]" class="incipient">minmax</a> @zahlen</p>
<p>
Aber auch Reihen, wie man sie beim Mathe-Wettbewerb &quot;Euler&quot; häufig braucht, <br />
lassen sich mit einer weiteren Schreibweise der Reduktionsoperatoren sehr knapp <br />
formulieren.</p>
<p>
Perl 6:<br />
	<a href="http://www.perlfoundation.org/perl6/index.cgi?%5C*" title="[click to create page]" class="incipient">\*</a> 1..3 # 1, 2 = 1*2, 6 = 2*3<br />
	<a href="http://www.perlfoundation.org/perl6/index.cgi?%5C%2B" title="[click to create page]" class="incipient">\+</a> ^10 # 0,1,3,6,10,15,21,28,36,45</p>
<p>
Diese Form liefert die Aufzählung aller Zwischenergebnisse eines Reduktionsops.<br />
Formal hieße sich das ungefähr als &quot;@ergebnis[$n] = @ergebnis[$n-1] op @input[$n]&quot;<br />
ausdrücken. Und auch an dieser Schreibweise erkennt man die Regel einer Huffman-Kodierung<br />
(Je seltener etwas menötigt wird, desto länger (seltsamer) ist sein Name).</p>
<h3 id="und_noch_ein_blick_in_die_quantenwelt">Und noch ein Blick in die Quantenwelt</h3>
<p>
Neben Larry Wall ist Damian Conway einer der Hauptgestalter der Perl 6-Syntax.<br />
Nicht nur die ableitbaren Grammatiken der &quot;rules&quot; basieren zu einem guten Teil<br />
auf seinem &quot;Parse::RecDescent&quot;, auch sein Modul &quot;Quantum::Superpositions&quot; ließ<br />
viele Perl-Programmierer erste Bekanntschaft mit Junctions schließen. Wie vieles<br />
wofür sich Damian begeistert, können auch Junctions als abgehoben und schwer <br />
zugänglich erscheinen. In funktionalen Sprachen wie Haskell erwiesen sie sich<br />
jedoch als hilfreich, um komplexe logische Verknüpfungen einfacher zu formulieren.<br />
Würde man in Perl 5 z.B. noch schreiben:</p>
<p>
Perl 5:<br />
	if ($farbe eq &quot;rot&quot; or $farbe eq &quot;blau&quot; or $farbe eq &quot;grün&quot;) {<br />
		print &quot;Sie wählten eine Grundfarbe, interessant.\n&quot;<br />
	}</p>
<p>
So geht das in Perl 6 auch junktiv.</p>
<p>
Perl 6:<br />
	if $farbe eq &quot;rot&quot; | &quot;blau&quot; | &quot;grün&quot; {<br />
		say &quot;Sie wählten eine Grundfarbe, interessant.&quot;<br />
	}</p>
<p>
Aus Perl 5 ist bekannt, daß &quot;|&quot; für ein logisches &quot;oder&quot;(or) steht, &quot;&amp;&quot; für &quot;und&quot;<br />
(and) und &quot;^&quot; für &quot;entweder oder&quot; (xor) steht. Neu ist, daß man den Sachverhalt:<br />
&quot;rot oder blau oder grün&quot; in einer Variable speichern kann. Das letzte Beispiel<br />
ginge damit so:</p>
<p>
Perl 6:<br />
	my $gfarben = &quot;rot&quot; | &quot;blau&quot; | &quot;grün&quot;;<br />
	if $farbe eq $gfarben ...</p>
<p>
Wem das nicht ganz geheuer kann auch einen vertrauten Array verwenden und dessen<br />
Elemente junktiv verknüpfen.</p>
<p>
	my @gfarben = &lt;rot blau grün&gt;;<br />
	if $farbe eq any(@gfarben) ...</p>
<p>
Sicher ließe sich anstatt &quot;any(@gfarben)<a href="http://www.perlfoundation.org/perl6/index.cgi?%7C" title="[click to create page]" class="incipient">auch die reduktive Variante<!-- wiki-renamed-link | --></a> @gfarben&quot;<br />
verwenden, allerdings ist ersteres weit eingängiger (und aus Quantum::Superpositions<br />
bekannt). In gleicher Weise entspricht das &quot;all<a href="http://www.perlfoundation.org/perl6/index.cgi?%26" title="[click to create page]" class="incipient">einem<!-- wiki-renamed-link & --></a>&quot; (and), &quot;one<a href="http://www.perlfoundation.org/perl6/index.cgi?%5E" title="[click to create page]" class="incipient">dem<!-- wiki-renamed-link ^ --></a>&quot;<br />
(xor) und &quot;none&quot; einem &quot;not&quot;.</p>
<p>
Perl 6:<br />
	if all(@tiere) ~~ all(@affen) { say &quot;nur affen hier ...<br />
	if all(@tiere) ~~ all(@affen) | $faultier { ...<br />
	if schau() | vergleich() eq any(@gfarben) { ...</p>
<p>
Selbstverständlich lassen sich Junctions auch schachteln. Mit ihnen kann man auch<br />
Operationen auf mehrere Werte parallel anwenden, ähnlich den Hyperoperatoren.</p>
<p>
Perl 6:<br />
	my $gfarben = &quot;rot&quot; | &quot;blau&quot; | &quot;grün&quot;;<br />
	$gfarben ~= 'e'; # &quot;rote&quot; | &quot;blaue&quot; | &quot;grüne&quot;;<br />
	(1|2) + (3&amp;4); # (4|5) &amp; (5|6)</p>
<p>
Am schönsten daran ist wohl, daß man so komplexe logische Regelwerke kombinieren<br />
kann und Perl alle Details überläßt.</p>
<h3 id="danke">Danke</h3>
<p>
Über Arrays in Perl 6 lassen sich noch viele weitere Neuerungen berichten. Dieses<br />
mal ging es vor allem um die damit zusammenhängenden Operatoren. In der nächsten<br />
Folge lautet das Thema Kontrollstrukturen. Es wird daran anknüpfen, da Schleifen<br />
oft für die Bearbeitung von Arrays und Hashes eingesetzt werden.</p>
<hr />
<p>
<a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_2" title="(34 months)  toc Perl is an operator based language Unlängst konnte ich herzlich lachen, als ich diesen Satz in ...">Previous Chapter<!-- wiki-renamed-link Perl 6 Tutorial Part 2 --></a> | <a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial" title="(38 months) This tutorial was written for foo Perl magazine http perl-magazin.de and was published from winter 2...">Overview<!-- wiki-renamed-link Perl 6 Tutorial --></a> | <a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_4" title="(34 months)  toc Still operators left Nach Operatoren f r Skalare und Operatoren f r Arrays ist sicher Operatore...">Next Chapter<!-- wiki-renamed-link Perl 6 Tutorial Part 4 --></a></p>
</div>
]]></description>
<author>Herbert Breunung</author>
<guid isPermaLink="true">http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_3</guid>
<pubDate>Fri, 06 Aug 2010 23:47:26 -0000</pubDate>
</item>

</channel>
</rss>