Benutzer-Werkzeuge

Webseiten-Werkzeuge


scheme

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
scheme [2021-04-02 00:21:23] – [Racket] manfredscheme [2021-04-02 00:22:07] (aktuell) – [Racket] manfred
Zeile 1: Zeile 1:
 +====== Scheme ======
 +
 +**Aussprache: /ˈskēm/**
 +
 +Die erste funktionale Programmiersprache, die in den 60er Jahren entwickelt wurde, hieß //LISP//. Von //Lisp// wurden viele Dialekte entwickelt. Die beiden Dialekte, die zum Standard geworden sind, heißen //Common Lisp// und eben //Scheme//, d.h. **Scheme ist ein standardisierter Lisp-Dialekt**.
 +
 +//Scheme// ist keine rein-funktionale Programmiersprache. Vielmehr enthält sie auch Konzepte der imperativen Programmierung (Schleifen, Variablen).
 +
 +**//Scheme// liegt das Prinzip zugrunde, dass eine Programmiersprache nicht dadurch beschreibungsmächtig wird, dass man Feature über Feature häuft, sondern dadurch, dass man unnötige Einschränkungen entfernt. Aus diesem Grund ist //Scheme// auch der Lisp-Dialekt, mit dem kleinsten Sprachumfang.**
 +
 +Entwickelt wurde Scheme am //Massachusetts Institute of Technology// (MIT), wo auch die formale Spezifikation zur Verfügung steht, der so genannte Revised Report.
 +
 +  * [[http://de.wikipedia.org/wiki/Scheme|Scheme in Wikipedia]]
 +  * [[http://community.schemewiki.org/?scheme-faq-standards#implementations]]
 +  * [[http://schemers.org/|an improper list of Scheme resources]]
 +  * [[http://www.abyter.de/scheme3.htm|scheme - programmieren]]
 +  * [[http://www.johannes-bauer.com/scheme/]]
 +  * [[http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-1.html|Teach Yourself Scheme in Fixnum Days]]
 +  * [[http://mitpress.mit.edu/sicp/|Structure and Interpretation of Computer Programs]]
 +  * [[http://www.htdp.org/|How to Design Programs]]
 +  * [[http://www-pu.informatik.uni-tuebingen.de/pfg-2001/scheme/schintro-v14/schintro_toc.html|An Introduction to Scheme and its Implementation]]
 +
 +Die gebräuchlichen Dateiendungen für die Quellcodedateien von //Scheme// lauten **.scm** bzw. **.ss**.
 +
 +
 +===== Syntax =====
 +
 +  * [[http://www.michihiebl.de/?p=535|Die Programmiersprache Scheme]]
 +  * [[http://rosettacode.org/wiki/Trigonometric_functions#Scheme]]
 +
 +In Scheme gibt es nur Prefix-Operatoren im Stil von (funktion argumente) oder (operator operanden…). Eine simple Addition lautet:
 +
 +  (+ 2 3)      ---> 5
 +
 +Hierbei wird der Ausdruck 3 evaluiert, dann 2, und dann der ganze Ausdruck zu 5 evaluiert.
 +Analog verhält es sich bei:
 +
 +  (+ 2 (+ 1 2))      ---> 5
 +
 +Globale Variablen können mit
 +
 +  (define x 3)
 +
 +definiert werden.
 +Lokale Variablenbindungen lassen sich mit
 +
 +  (let ((x 4) (y 5)) body)
 +
 +definieren, wobei die globale Variable x von der Lokalen überdeckt wird. body ist der Bereich, in dem die lokalen Variablen x und y sichtbar sind.
 +
 +  (let ((x 4) (y 5)) (+ x y))       ---> 9
 +
 +Auch in Scheme gibt es Kontrollstrukturen wie if, else case, do, cond. Dabei ist do eine Schleife. Anders als in C gibt es hier keine Laufbedingung sondern eine Abbruchbedingung. Das kann anfangs zu Irritationen führen.
 +
 +  (do ((x 0 (+ x 1)))
 +      ((= x 10) (display "end"))
 +      (display x))
 +
 +Die Schleife läuft solange, bis x den Wert 10 erreicht.
 +
 +
 +===== integrierte Entwicklungsumgebung (IDE) =====
 +
 +
 +==== DrScheme / PLT Scheme ====
 +
 +**DrScheme** ist eine integrierte Entwicklungsumgebung (IDE) für die Programmiersprache //Scheme//. Die Software ist mit einer grafischen Benutzeroberfläche ausgestattet und ist Bestandteil von **PLT Scheme**. DrScheme kommt oft in Informatikkursen von Universitäten zum Einsatz.
 +
 +//PLT-Scheme// ist eine Kombination aus dem //MzScheme-Compiler// und der Entwicklungsumgebung //DrScheme//.
 +//MzScheme// kann auch alleine auf der Kommandozeile angewendet werden.
 +Für Anfänger bietet das Projekt die Sprache //Lazy Scheme// an.
 +
 +  * [[http://de.wikipedia.org/wiki/DrScheme]]
 +  * [[http://www.plt-scheme.org/software/drscheme/|PLT Scheme (inklusive DrScheme)]]
 +  * [[http://www.matheplanet.com/default3.html?call=article.php?sid=1129&ref=http%3A%2F%2Fwww.google.de%2Fsearch%3Fhl%3Dde%26source%3Dhp%26q%3DDrScheme%26meta%3D%26btnG%3DGoogle-Suche|korrekten Installation der Arbeitsumgebung der Programmiersprache Scheme]]
 +  * [[http://docs.plt-scheme.org/guide/]]
 +  * [[http://docs.plt-scheme.org/more/]]
 +  * [[http://docs.plt-scheme.org/quick/]]
 +  * [[http://docs.plt-scheme.org/reference/]]
 +
 +  Start mit DrScheme (http://docs.plt-scheme.org/guide/intro.html)
 +  ------------------
 +  1. Sprache / Sprache auswählen...       [Strg]+[L]
 +     folgendes auswählen:
 +          Module
 +  2. im oberen Text-Fenster folgendes eingeben:
 +          #lang scheme
 +  3. jetzt oben rechts auf "start" klicken,
 +     um die Sprache bzw. das Modul zu aktivieren
 +  
 +  Diese Angaben brauchen beim nächsten Start von DrScheme nicht
 +  erneut gemacht werden, es werden beim Start immer die letzten
 +  Einstellungen wieder hergestellt.
 +  
 +  Jetzt kann man im unteren Textfenster Scheme-Code eingeben.
 +  Will man ein Programm schreiben, kann man im unteren Fenster
 +  kleine Codeteile testen und sie dann im oberen Fenster einfühgen.
 +  Drückt man auf Start, ist im unteren Fenster die Ausgabe zu sehen.
 +  Will man das Programm aus dem oberen Fenster abspeichern, drückt
 +  man auf Speichern (Diskettensymbol) und vergibt einen Namen der
 +  auf ".ss" endet.
 +
 +
 +=== Dateioperationen ===
 +
 +Im folgenden ein PLT-Scheme-Test von mir, in dem ich diverse Möglichkeiten ausprobiert habe wie man Ausgaben in Dateien schreiben kann.
 +
 +  #lang scheme
 +  
 +  (require scheme/file)
 +  (define DATEIPFAD "test.txt")
 +  
 +  ; eine neue Datei wird zum schreiben angelegt
 +  (define o (open-output-file DATEIPFAD #:mode'text #:exists'replace ))
 +  (display "Yoda" o)
 +  (newline o)
 +  (display "hello" o)
 +  (write-char #\space o)
 +  (display 'world o)
 +  (newline o)
 +  (display "Hallo Welt!" o)
 +  (newline o)
 +  ;Datei wird geschlossen
 +  (close-output-port o)
 +  
 +  (port-count-lines-enabled 'any)
 +  
 +  ; vorhandene Datei wird zum lesen geöffnet
 +  ;(define i (open-input-file DATEIPFAD #:mode'text))
 +  ;;; nächstes Wort lesen
 +  ;;; "read" kann keine '"' lesen, sie werden als "closing" interpretiert
 +  ;(display (read i))
 +  ;(display (read i))
 +  ;(display (read i))
 +  ;(display (read i))
 +  ;(display (read i))
 +  ;(newline)
 +  ; Datei wird wieder geschlossen
 +  ;(close-input-port i)
 +  
 +  ; vorhandene Datei wird zum lesen geöffnet
 +  ;(define i (open-input-file DATEIPFAD #:mode'text))
 +  ;;; nächste Zeile als String in doppelten Anführungszeichen ausgeben
 +  ;(read-line i)
 +  ;(read-line i)
 +  ;(read-line i)
 +  ;(read-line i)
 +  ;(close-input-port i)
 +  
 +  ; Trennlinie ziehen
 +  ;(display "-------------------------")
 +  ;(newline)
 +  
 +  ;;; ganze Zeilen ausgeben
 +  ; vorhandene Datei wird zum lesen geöffnet
 +  (define j (open-input-file DATEIPFAD #:mode'text))
 +  (port-next-location j)
 +  ;;; jedes "read-line" liest eine Zeile und trennt den Zeilenumbruch ab
 +  (display (read-line j 'any))
 +  (newline)
 +  (port-next-location j)
 +  (display (read-line j 'any))
 +  (newline)
 +  (port-next-location j)
 +  (display (read-line j 'any))
 +  (newline)
 +  (port-next-location j)
 +  (display (read-line j 'any))
 +  (newline)
 +  (port-next-location j)
 +  (display (read-line j 'any))
 +  (newline)
 +  (port-next-location j)
 +  (close-input-port j)
 +  
 +  ;;; eine Eingabe von der Tastatur einlesen
 +  ;(read-syntax EINGABE)
 +  
 +  ; Trennlinie ziehen
 +  (display "-------------------------")
 +  (newline)
 +  
 +  ;;; ganze Datei ausgeben
 +  ; vorhandene Datei wird zum lesen geöffnet
 +  (define k (open-input-file DATEIPFAD #:mode'text))
 +  ;(port-count-lines-enabled j)
 +  (port-count-lines! k)
 +  ;;; jedes "read-line" liest eine Zeile und trennt den Zeilenumbruch ab
 +  ;(display (read-line k 'return-linefeed))
 +  (display (read-line k 'return))
 +  ;;; 1. Ausgabe: nächste Zeilennummer
 +  ;;; 2. Ausgabe: nächste Spalte
 +  ;;; 3. Ausgabe: nächste Position
 +  (port-next-location k)
 +  (close-input-port k)
 +  
 +  ; aktueller Speicherverbrauch
 +  (define MEM (current-memory-use))
 +  (display "aktueller Speicherverbrauch: ")
 +  (display MEM)
 +  (newline)
 +  
 +  ; Trennlinie ziehen
 +  (display "-------------------------")
 +  (newline)
 +  
 +  ; Größe der Datei in byte
 +  (display (file-size DATEIPFAD))
 +  (newline)
 +  
 +  ; Zeilenweise Ausgabe
 +  (display (file-exists? DATEIPFAD))
 +  ;(display (file->lines DATEIPFAD #:mode'text #:line-mode'any))
 +  (newline)
 +  
 +  ; in das Verzeichnis "/tmp" wechseln
 +  ;(current-directory "/tmp")
 +  
 +  ; Trennlinie ziehen
 +  (display "-------------------------")
 +  (newline)
 +  
 +  (display "Datei Zeichenweise ausgeben")
 +  (newline)
 +  (let ((ZEICHEN (file-size DATEIPFAD)))
 +    (call-with-input-file DATEIPFAD
 +      (lambda (T)
 +        (let loop ((i 0))
 +          (unless (>= i ZEICHEN)
 +            ;;; char-Code des nächsten Zeichens
 +            (display (read-char T))
 +            ;
 +            ;;; Tastaturcode des nächsten Zeichens
 +            ;(display (read-byte-or-special T))
 +            ;(newline)
 +            ;
 +            (loop (+ i 1))
 +            )
 +          )
 +        )
 +      )
 +    )
 +  
 +  ; Trennlinie ziehen
 +  (display "-------------------------")
 +  (newline)
 +  
 +  (display "Datei Zeilenweise ausgeben")
 +  (newline)
 +  (call-with-input-file DATEIPFAD
 +    (lambda (aport)
 +      (let loop ((lline (read-line aport 'return)))
 +        (when (not (eof-object? lline))
 +          (display lline)
 +          (newline)
 +          (loop (read aport))
 +          )
 +        )
 +      )
 +    )
 +
 +Die Ausgabe wurde in die Datei **test.txt** geschrieben:
 +
 +  cat test.txt
 +  Yoda
 +  hello world
 +  Hallo Welt!
 +
 +
 +===== Compiler =====
 +
 +
 +==== CHICKEN ====
 +
 +  * [[http://www.call-with-current-continuation.org/|CHICKEN Home Page]]
 +    * [[https://bitbucket.org/roti/chicken-installer/downloads|Chicken für Windows]]
 +  * [[http://chicken.wiki.br/|CHICKEN Wiki]]
 +
 +
 +=== Chicken als Taschenrechner ===
 +
 +  echo "(* 12 3000)" | csi -q
 +
 +
 +=== hallo_welt.scm ===
 +
 +  (display "Hallo Welt! ")
 +  (display (+ 3 5))
 +  (newline)
 +  (define nachricht1 "'Hallo Welt!', sagte sie.")
 +  (write nachricht1)
 +  (newline)
 +  (display nachricht1)
 +  (newline)
 +  (define nachricht2 "\"Hallo Welt!\", sagte sie.")
 +  (display nachricht2)
 +  (newline)
 +  (write (+ 3 4))
 +  (newline)
 +
 +
 +dynamisch gelinkt (ausführbare Datei ist 12kB groß):
 +
 +  csc hallo_welt.scm
 +
 +
 +link with static CHICKEN libraries:
 +
 +  csc -static-libs hallo_welt.scm
 +
 +
 +**generate completely statically linked executable** (ausführbare Datei ist 1,8MB groß):
 +
 +  csc -static hallo_welt.scm
 +
 +
 +  ./hallo_welt
 +  Hallo Welt! 8
 +  "'Hallo Welt!', sagte sie."
 +  'Hallo Welt!', sagte sie.
 +  "Hallo Welt!", sagte sie.
 +  7
 +
 +
 +=== datei.scm ===
 +
 +  ; http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-11.html
 +  ; http://groups.csail.mit.edu/mac/projects/scheme/documentation/scheme_3.html#SEC30
 +  
 +  
 +  ; unbound variable: create-directory
 +  ; unbound variable: change-directory
 +  ; unbound variable: current-directory
 +  ;(create-directory "testneu")
 +  ;(change-directory "testneu")
 +  ;(current-directory)
 +  
 +  
 +  
 +  (define o (open-output-file "test.txt"))
 +  
 +  (display "Yoda" o)
 +  (newline o)
 +  
 +  (display "hello" o)
 +  (write-char #\space o)
 +  (display 'world o)
 +  (newline o)
 +  
 +  (display "Hallo Welt!" o)
 +  (newline o)
 +  
 +  (close-output-port o)
 +  
 +  
 +  
 +  (define i (open-input-file "test.txt"))
 +  ; (read-char i)
 +  
 +  (define j (read i))
 +  (display j)
 +  (newline)
 +  
 +  (close-input-port i)
 +  
 +  
 +  
 +  ; Datei automatisch öffnen und schließen
 +  (call-with-input-file "test.txt"
 +        (lambda (T)
 +        (define ANZAHL 7)
 +        ;(define ANZAHL (vector-length T))
 +        ;(display ANZAHL)
 +        ;(newline)
 +                (let loop ((i 0))
 +                        (unless (>= i ANZAHL)
 +                                (display (read T))
 +                                (newline)
 +                                (loop (+ i 1))
 +                        )
 +                )
 +        )
 +  )
 +  
 +  
 +  ; unbound variable: change-directory
 +  ;(display (file-stat "test.txt"))
 +  
 +  
 +  ;(define argv-count (vector-length argv))
 +  ;
 +  ;(let loop ((i 0))
 +  ;  (unless (>= i argv-count)
 +  ;    (display (vector-ref argv i))
 +  ;    (newline)
 +  ;    (loop (+ i 1))))
 +
 +
 +=== argumente.scm ===
 +
 +  * [[http://www.linux-magazin.de/heft_abo/ausgaben/2001/01/funktioneller_gehts_nicht/(offset)/4]]
 +
 +  (display "Sie haben \"")
 +  (display (car (argv)))
 +  (display "\" aufgerufen!")
 +  (newline)
 +  (newline)
 +  (write (car (argv)))
 +  (newline)
 +  (print "print " (car (argv)))
 +  (newline)
 +  (display (flatten (argv) ))
 +  (newline)
 +  
 +  
 +  
 +  (define argv-count (vector-length argv))
 +  
 +  (let loop ((i 0))
 +    (unless (>= i argv-count)
 +      (display (vector-ref argv i))
 +      (newline)
 +      (loop (+ i 1))))
 +
 +
 +=== squares.scm ===
 +
 +  (define (square x) (* x x))
 +  (display (square 3))
 +  (newline)
 +
 +
 +=== squares1.scm ===
 +
 +  (do 
 +        ; Initialize variables
 +        ( 
 +                (i 1 (+ i 1))
 +        )
 +  
 +        ; while condition
 +        (
 +                (> i 10)
 +        )
 +    
 +        ; loop body
 +        (display (* i i))
 +        (display " "   
 +  )
 +
 +
 +=== squares2.scm ===
 +
 +  (do ( (i 1 (+ i 1)) ) ( (> i 10) )
 +        (display (* i i))
 +        (newline)    
 +  )
 +
 +
 +=== squares_lambda.scm ===
 +
 +  (define square (lambda (x) (* x x)))
 +
 +
 +=== define.scm ===
 +
 +  (define pi 3.14159)
 +  (define radius 10)
 +  (define umfang (* 2 pi radius))
 +  (display umfang)
 +  (newline)
 +
 +
 +=== foo.scm ===
 +
 +  (define (fac n)
 +        (if (zero? n)
 +                1
 +                (* n (fac (- n 1)))))
 +  (write (fac 10))
 +  (newline)
 +
 +
 +=== status.scm ===
 +
 +  ; ist wahr: #t
 +  (display (= 2 (+ 4 -2)))
 +  (newline)
 +  
 +  ; ist falsch #f
 +  (display (< 2 (+ 4 -2)))
 +  (newline)
 +  
 +  ; ist wahr: #t
 +  (display (< 1 (+ 4 -2)))
 +  (newline)
 +  
 +  ; so vergleicht man Symbole
 +  (display (eq? 2 (+ 4 -2)))
 +  (newline)
 +  
 +  ; so vergleicht man Objekte, Zahlen, Zeichen und Zeichenketten
 +  (display (eqv? 2 (+ 4 -2)))
 +  (newline)
 +
 +
 +=== env.scm ===
 +
 +  (define HOME (getenv "HOME"))
 +  (display HOME)
 +  (newline)
 +  
 +  (define shell (getenv "SHELL"))
 +  
 +  (display shell)
 +  (newline)
 +
 +
 +==== MzScheme ====
 +
 +  mzc --exe hallo_welt hallo_welt.ss
 +  mzc --gui-exe hallo_welt hallo_welt.ss
 +
 +
 +==== Racket ====
 +
 +Racket ist eine multi-paradigmatische Programmiersprache in der Lisp-Scheme-Familie. Sie ist Nachfolger des Scheme-Dialekts PLT Scheme. Racket ist auch eine integrierte Entwicklungsumgebung (IDE) mit umfangreicher Bibliothek.
 +
 +  * [[https://de.wikipedia.org/wiki/Racket_(Programmiersprache)]]
 +  * [[http://www.racket-lang.org/]]
 +
 +
 +==== GNU-Guile - Scheme als GNU-Standard-Programmiersprache ====
 +
 +  * [[http://www.computerbase.de/lexikon/GNU_Guile]]
 +  * [[http://www.gnu.org/software/guile/|Offizielle GNU-Guile-Website]]
 +
 +//GNU-Guile (kurz Guile, selten Guile Scheme)// ist ein Interpreter für die Programmiersprache //Scheme//, einen LISP-Dialekt. //Guile// ist als Programmbibliothek implementiert, die in andere Programme eingebunden werden kann, um deren Erweiterbarkeit zu fördern. //Guile// wurde mit dem Ziel geschaffen, als „offizielle“ Skript- und Erweiterungssprache des GNU-Projektes zu dienen, auch wenn noch längst nicht alle GNU-Projekte Guile unterstützen und der Script-FU von GIMP auf die „Konkurrenz“ TinyScheme setzt.
 +
 +Der Guile-Interpreter erweitert Scheme unter anderem um folgende Fähigkeiten:
 +
 +  * Ein erweitertes Modulsystem
 +  * Vollen Zugriff auf POSIX-Systemaufrufe
 +  * Netzwerkunterstützung
 +  * Multithreading
 +  * Dynamisches Linken
 +  * Eine Schnittstelle zur Ausführung Scheme-fremder Funktionsaufrufe
 +  * Verbesserte Verarbeitung von Zeichenketten
 +
 +Es gibt auch noch zwei grundsätzliche Unterschiede zur Scheme Definition([Clinger]):
 +
 +  * Guile ist case sensitive
 +  * eine leere Liste '() unterscheidet sich nicht von falsch #f
 +
 +In Zukunft soll Guile auch andere Skriptsprachen wie Perl und PHP unterstützen. Zurzeit wird jedoch CTAX unterstützt, eine C-ähnliche Sprache. Eines der zukünftigen Ziele von Guile ist es, aus jeder beliebigen anderen Sprache nach Scheme „übersetzen“ und aus diesen portablen Bytecode erzeugen zu können; Guile wäre dann eine sprachneutrale Laufzeitumgebung.
 +
 +Guile unterstützt XML, XPath, und XSLT, die //Forms// von SXML, SXPath und SXSLT. Die S-expression-basierte XML Verarbeitung wird ebenfalls unterstützt.
 +
 +=== Geschichte ===
 +
 +Die Ursprünge von Guile liegen in einer Diskussion, die von Richard Stallman gestartet wurde und die später unter dem Namen „the Tcl Wars“ bekannt geworden ist: Stallman behauptete, dass Tcl nicht leistungsfähig genug sei, um als Erweiterungsprache zu dienen. Aus diesem Grund startete er das Guile Projekt. Damals existierte zwar die Scheme-Definition, aber es gab noch keinen Interpreter, so wurde mit Guile der erste einigermaßen standardkonforme Interpreter geschaffen. Zu nennen ist Tom Lord, einer der Hauptprogrammierer, der damals bei Cygnus Solutions (später Red Hat) beschäftigt war.
 +
 +Die ersten Versionen wurden vor 1995 von SIOD („Scheme in One Defun“) und dem SCM-Interpreter abgespalten.