Aus Raspberry Pi Geek 07-08/2020

Typen, Module, Plots und Makros in der Programmiersprache Julia

© Mikekiev, 123RF

Modulbauweise

Pit Noack

Die noch junge Programmiersprache Julia wartet mit vielen praktischen Funktionen auf. Teil 2 unseres Workshops beschreibt unter anderem den Einsatz von Makros und Modulen.

Der erste Teil unserer Julia-Einführung aus Ausgabe 05-06/2020 [1] stellt die Grundlagen dieser auf wissenschaftliches Rechnen spezialisierten Sprache vor. Der vorliegende Teil taucht tiefer in die zum Teil anspruchsvolle Materie ein. Die Mühe lohnt sich, denn die Sprache steht in ernsthafter Konkurrenz zu Matlab, Mathematica und sogar C++. Julia [2] punktet mit einer sehr aktiven Community, einem stetig wachsenden Ökosystem und kombiniert die Flexibilität von Skriptsprachen wie Python oder Ruby mit rasanter Ausführungsgeschwindigkeit.

Dieser Beitrag setzt die Kenntnis des ersten Teils und die darin beschriebene Installation von Julia voraus. Aktuell steht Version 1.4.1 bereit. Welche Rolle Objektorientierung in Julia spielt, zeigt der Kasten “Objektorientierung light”. In welchen Pfaden die Programmiersprache ihre Daten auf Ihrem System speichert, entnehmen Sie der Tabelle “Speicherorte”.

Objektorientierung light

Auch wenn hier von Objekten und Konstruktoren die Rede ist: Julia ist keine objektorientierte Sprache im Stil von Python, Java oder C++. Das zeigt sich schon am sparsamen Vererbungsmechanismus sowie an der Unveränderlichkeit benutzerdefinierter Typen. Im RGB-Beispiel quittiert Julia eine Zuweisung wie grey.r = 42 mit der Fehlermeldung: immutable struct of type RGB cannot be changed. Möchten Sie mit veränderlichen Typen arbeiten, dann setzen Sie das Schlüsselwort mutable vor die Typdefinition.

Zudem speichern Objektattribute zwar auch Funktionen, doch diese haben mit den Objektmethoden im Stil von Python oder Java wenig gemein. Um eine hohe Ausführungsgeschwindigkeit bei dynamischer Typisierung zu erreichen, setzt Julia voll und ganz auf die in Teil 1 dieser Serie vorgestellte Mehrfachverteilung (Multiple Dispatch): Methoden sind auf mehr oder weniger spezifische Argumenttypen hin definiert. Julia reicht Funktionsaufrufe abhängig von diesen Typen an die passende Methode weiter. Der LLVM-Compiler sorgt dann für eine optimierte und maschinennahe Ausführung des Funktionsaufrufs.

Standardbibliothek

~/bin/julia-1.4.1/share/julia/stdlib/v1.4/

Metadaten verfügbarer Packages

~/.julia/registries/General

Geladene Packages

~/.julia/packages

Vorkompilierte Packages

~/.julia/compiled

REPL-History

~/.julia/logs/repl_history.jl

Eigene Typen definieren

Julia erlaubt es, mit dem Schlüsselwort struct maßgeschneiderte Datentypen zu entwerfen. Listing 1 beschreibt einen Typ zum Speichern von Farbwerten in der RGB-Codierung: Drei Werte zwischen 0 und 255 repräsentieren den Rot-, Grün- und Blauanteil.

Listing 1

# file rgb.jl
import Base.*
struct RGB
  r::UInt8
  g::UInt8
  b::UInt8
end
RGB(grey) = RGB(grey, grey, grey)
*(c::RGB, x) = RGB(round(c.r*x), round(c.g*x), round(c.b*x))

Die Zeilen 5 bis 7 deklarieren die entsprechenden Attribute r, g und b vom Typ UInt8 – also vorzeichenlose 8-Bit-Ganzzahlen, die exakt den geforderten Wertebereich von 0 bis 255 abbilden. Die Typisierung ist optional, im gegebenen Fall aber sinnvoll.

Zusammen mit dem Datentyp erzeugt Julia automatisch einen Default-Konstruktor, der je Attribut ein Argument erwartet. Zeile 10 definiert einen weiteren Konstruktor mit nur einem Argument, der einen Grauwert liefert – alle drei Attribute erhalten denselben Wert. Das Beispiel zeigt: Konstruktoren stellen für Julia letztlich ganz gewöhnliche Methoden dar.

Die Zeile 11 definiert die attributweise Multiplikation eines RGB-Objekts mit dem Argument x. Da dieses auch aus einem nicht ganzzahligen Wert bestehen könnte, erfordert das eine Rundung mittels round(). Andernfalls würde der aufgerufene Default-Konstruktor sich mit einer Fehlermeldung über mangelnde Präzision beschweren.

Zur Erinnerung: Der Begriff Funktion steht in Julia für den Bezeichner einer Funktion. Bei Methoden handelt es sich um konkrete Implementierungen einer Funktion auf bestimmte Argumenttypen. Wenn Sie im interaktiven Modus methods(*) eingeben, erhalten Sie eine Liste von 358 zugeordneten Methoden. Um eine weitere für Multiplikation zu definieren, gilt es, diese aus dem Modul Base zu importieren (Listing 1, Zeile 2). Über Module erfahren Sie im Folgenden mehr. Wenn Sie methods(*) nach dem Einbinden des RGB-Typs ausführen, zählt die Liste 359 Methoden und führt auch die RGB-Multiplikation auf.

Listing 2 zeigt die Anwendung des Typs RGB im interaktiven Modus. Zunächst müssen Sie die entsprechende Datei per include() ausführen. Die Zeilen 2 und 4 erzeugen RGB-Objekte, die ein reines Rot und einen dunklen Grauwert repräsentieren. Julia zeigt vorzeichenlose Ganzzahlen der Farbwerte in der Hexadezimal-Schreibweise an. Zeile 6 wendet die für RGB-Objekte spezifizierte Multiplikation auf den Grauwert an. Beachten Sie: Das ursprüngliche Objekt bleibt unverändert; die Multiplikation liefert ein neues RGB-Objekt mit veränderten Werten.

Listing 2

> include("rgb.jl");
> red = RGB(255, 0, 0)
RGB(0xff, 0x00, 0x00)
> grey = RGB(64)
RGB(0x40, 0x40, 0x40)
> grey * 3
RGB(0xc0, 0xc0, 0xc0)
> grey_img = fill(grey, 3, 3)
3×3 Array{RGB,2}:
[...]
> grey_img .* 3
3×3 Array{RGB,2}:
[...]

In Zeile 8 füllt die Funktion fill() ein zweidimensionales Array aus 3 mal 3 Feldern mit Grauwerten. Zeile 11 zeigt, dass die RGB-Multiplikation auch für Arrays beliebiger Dimensionalität funktioniert: Sie müssen lediglich den Punkt-Operator vor den Aufruf der Multiplikation setzen.

Die Entwickler legen Wert darauf, dass Julia mit benutzerdefinierten Datentypen genauso flott rechnet wie mit elementaren. Das haben wir für den Typ RGB erfolgreich getestet: Es spricht nichts dagegen, ein 4K-Bild als zweidimensionales Array von RGB-Objekten zu repräsentieren. Dergleichen würde man in Python oder Java kaum versuchen wollen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 8 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben