Open Source im professionellen Einsatz
Linux-Magazin 02/2001

Standard oder nicht Standard, das ist hier die Frage

Standards? Standards!

Der Scheme-Standard hat einen recht kleinen Umfang, also greifen Programmierer für größere Projekte zwangsläufig auf Erweiterungen zurück. Im Zentrum dieses Artikels stehen daher Standard-Scheme und seine Erweiterungen.

982

Vielleicht fragen Sie sich, warum sich Programmierer um Standards scheren sollten. Standards sind ganz allgemein kein Selbstzweck, sondern erlauben es dem Nutzer, eine gewisse Unabhängigkeit von Anbietern zu erhalten. Ich sehe mich auch bei Programmiersprachen in der Position eines Nutzers und binde mich daher ungern an Produkte, die nicht standardisiert sind oder die mir keinen Einfluss geben, etwaige Probleme umschiffen zu können. Stellen Sie sich vor, die Firma, derern Entwicklungswerkzeuge Sie einsetzen, verschwindet von Markt oder entschließt sich, das Produkt nicht weiterzuentwickeln. Selbst eine Verschärfung der Lizenzbedingungen kann schon fatale Folgen haben. Zur Lösung dieses Problems sind denkbar:

  • Nur Open-Source-Pakete nutzen (Python, Perl, Scheme, (X)Emacs, Eiffel, Common Lisp und viele mehr)
  • Programmwerkzeuge, die mehr als eine Implementierung haben (Eiffel, Common Lisp, Java, Scheme) und Möglichkeiten, auf einem Interpreter/Compiler geschriebene Progamme auf andere Implementierungen zu portieren.
  • Sprachen, die Standards besitzen, wovon es überraschenderweise wenige gibt (beispielsweise COBOL, C, C++, FORTRAN, Scheme, Common Lisp und ADA)

Scheme erfüllt alle drei Punkte; es gibt verschiedene kommerzielle und freie Implementierungen und es existiert ein - wenn auch kleiner - Standard.

Für "ernsthafte" Softwareerstellung jedoch ist man in Scheme wie auch in C auf Erweiterungen angewiesen. Dabei spielen Bibliotheken eine zentrale Rolle; die Slib ist Schemes "erweiterte Standardbibliothek", die in (fast) alle Implementierungen eingesetzt werden kann. Zunächst werde ich auf Standardscheme eingehen, im folgenden dann auf Erweiterungen entweder von DrScheme oder der Slib.

Eingabe/Ausgabe

In allen bisherigen Beispielen wurde die Ausgabe von der read-eval-print-loop angestoßen. Diese Schleife nützt selbstverständlich die Basismöglichkeiten der Sprache für die eigene Ein- Ausgabe. Ein- und Ausgabequellen heißen in Scheme Ports. Die Standardports kann man in Scheme mit den Funktionen current-input-port und current-output-port herausfinden. Der Eingabeport ist normalerweise die Tastatur, der Ausgabeport der Bildschirm. Für die Eingabe stehen in R5RS Scheme zur Verfügung: read, read-char, eof-object?, peek-char und char-ready?. Für die Ausgabe: write, write-char, display und newline. Zum Schreiben und Lesen von Dateien offeriert Scheme die Funktionen: call-with-input-file, call-with-output-file, with-input-from-file, with-output-to-file, open-input-file, open-output-file, close-input-port und close-output-port .

Im Listing 1 wird die Datei mit dem Namen from zum Lesen geöffnet, die Datei to zum Schreiben. Der Rückgabewert der open-* Funktionen ist jeweils ein Port, was Sie mit den *-port? Methoden überprüfen können. Der Aufruf von read-char und write-char erfolgt mit dem optionalen Portargument, was die die Ein- und Ausgabe auf die mit den Ports assoziierten Dateien "umlenkt". Das Beispiel-Programm kopiert die Datei Zeichen für Zeichen, und ist damit eine der ineffektivsten Methoden, um eine Datei zu kopieren. Wird das Ende der Datei erkannt, werden die Ports geschlossen. Die Rückgabewerte der close-* Funktionen sind unspezifiziert, daher erhalten Sie keine Rückmeldung über den Erfolg oder Misserfolg dieser Kopieraktion. Neben der dem zeichweisen Einlesen mit der Funktion read-char kann man mit read ganze Scheme-Programme einlesen .

(define (read-from-file from) 
  (call-with-input-file from 
    (lambda (port) 
      (eval (read port)))))

In diesem Beispiel erübrigt sich das explizite Öffnen und Schließen der Datei, da sich diese Aufgabe mittels der call-with-input-file-Funktion an Scheme delegieren lässt. call-with-input-file erwartet einen Dateinamen und eine Funktion mit einem Parameter (der dem geöffneten Port entspricht). Die Funktion öffnet die angegebende Datei, führt die Funktion aus und schließt den Port anschließend wieder.

Rufen wir diese Funktion einmal mit der folgenden Datei ( fact.scm )auf:

(define (fact n) 
  (if (= n 0)  
      1 
      (* n  (fact (- n 1))))) 
 
> (read-from-file "fact.scm") 
> (fact 10) -> 3628800

Mit read wird der in einer Datei stehende Scheme-Code eingelesen und geparst, mit eval ausgewertet, das Resultat dieser Auswertung steht Ihnen dann zur Verfügung. Auch das Kommandoprompt von Scheme arbeitet auf die gleiche Weise. Bitte probieren Sie es einfach einmal aus. Es handelt sich hierbei nicht um ein besonderes Merkmal von Scheme, sondern gilt auch für andere Lisps. Damit kennen Sie nun schon alle "Standardfunktionen" zur Ein- Ausgabe in Scheme. Kommen zusätzlich Dateien und Verzeichnisse ins Spiel, müssen Sie auf Erweiterungen Ihres Schemes und/oder Möglichkeiten der Slib zurückgreifen.

Listing 1: Beispiel für Eingabe/Ausgabe: Kopieren einer Datei

(define (my-copy-file from to) 
  ;; Standard Scheme bietet keine Möglichkeit zu testen 
  ;; ob Dateien existieren und/oder welche Rechte sie haben
  ;; diese Funktion arbeitet also nur zufällig :( 
  (let ((ip (open-input-file from)) 
        (op (open-output-file to))) 
    (do ((ch (read-char ip) (read-char ip))) 
      ((eof-object? ch)  
       (begin  
         (close-input-port ip) 
         (close-output-port op))) 
      (write-char ch op))))

Warnung: Wer dieses Programm unbearbeitet benutzt, wird mit Datenverlusten nicht unter 1 GB "bestraft" ;-).

Vektoren und Zeichenketten

Bisher haben wir uns nur am Rande mit Zeichenketten (Strings) beschäftigt. Scheme bietet auch Funktionen zur Bearbeitung von Zeichenketten an, die aber ebenfalls wieder fast nur die Basisfunktionalität abdecken. Zeichenketten sind in Scheme Vektoren oder Felder, sie sind wie in C Null-indiziert, das heißt, das erste Zeihen einer Zeichenkette findet man an der Position Null.

Einzelne Zeichen in Scheme werden mit #name dargestellt , so ist beispielsweise #a der Buchstabe 'a'.

Zeichenketten kann man vergleichen, aneinanderhängen, aufsplitten, kopieren, in Listen umwandeln und/oder aus Listen generieren.

Die Arbeitsweise der Funktion in Listing 2 dürfte Ihnen keine Schwierigkeiten mehr bereiten. Die Funktion erwartet zwei Parameter; beim ersten handelt es sich um eine Funktion, die auf jeweils ein Zeichen angewandt wird, was man an dem Aufruf (fun ch) erkennen kann; beim zweiten um die Zeichenkette, die verarbeitet werden soll. str-len ermittelt die Länge der übergebenen Zeichenkette. Ein neuer String der gleichen Länge wird angelegt und zum Rückgabewert der Funktion gemacht. Die do Schleife durchläuft die übergebende Zeichenkette, wendet die übergebende Funktion auf jedes einzelne Zeichen an und schreibt das Ergebnis der Funktion an die entsprechende Stelle des Rückgabewertes (beachten Sie die Initialisierung von i mit 0!). Sie können diese Funktion so anwenden:

(string-to char-upcase "was_auch_immer") 
-> WAS_AUCH_IMMER

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Wechsel auf der Brücke

    Scripting funktioniert nicht nur bei den üblichen Verdächtigen wie Bash, Korn-Shell und Python, sondern auch mit Scheme. Im Zentrum des Artikels stehen darum die Shell-Programmierung mit Scheme sowie die Programmierung fürs Internet.

  • Wir können auch anders

    Bisher vorgestellte Programme waren in funktionaler Weise implementiert. Schemes Stärken liegen zwar hauptsächlich in diesem Bereich, jedoch gibt es auch die Möglichkeit, objektorientiert vorzugehen.

  • Funktioneller gehts nicht

    Nachdem im vorherigen Teil die Basiselemente der Scheme-Programmierung vorgestellt wurden, soll in diesem Artikel ein essentieller Vorteil von Scheme die Hauptrolle spielen, nämlich die funktionale Programmierung.

  • PLT-Scheme 4.0 mit vielen Neuerungen

    PLT-Scheme, ein Softwarepaket bestehend aus Scheme-Implementierung und Entwicklungsumgebung, ist in Version 4.0 erschienen. Die Entwickler haben rund ein Jahr in die neue Release investiert.

  • Chicken Scheme in Version 4.8.0

    Die freie Scheme-Implementierung Chicken ist in Version 4.8.0 für Linux, Windows und Mac OS X erhältlich.

comments powered by Disqus

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.