Grundlagen der funktionsorientierten Programmierung mit SCHEME/Datentypen
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>SchemeJS</language>
''Datentypen'' beschreiben den ''Wertebereich'' von Daten.<br />
Damit wird festgelegt, welche speziellen Operationen mit den Daten ausgeführt werden können.<br />
== Ausgewählte Datentypen in Scheme ==
<!-- code id="4c76c650210dd" hidden>(require-extension (srfi 13))</code -->
<table border="1" cellspacing="1" cellpadding="4">
<tr>
<th> </th>
<th>Zahlen</th>
<th>Zeichen</th>
<th>Zeichenketten</th>
<th>Wahrheitswerte</th>
</tr>
<tr>
<th align="left" valign="top">Beispiele</th>
<td valign="top"><tt>12<br />-0.25<br />3e-04<br />2/3</tt> (DrRacket)</td>
<td valign="top"><tt>#\a #\B<br />#\+<br />#\space<br />#\tab<br />#\newline</tt></td>
<td valign="top"><tt>"Informatik"<br />"Heute ist ein schoener Tag"<br />"12.03"<br />"(+ 1.5 2.3)"</tt></td>
<td valign="top"><tt>#t<br />#f</tt></td>
</tr>
<tr>
<th align="left" valign="top">Operatoren</th>
<td valign="top"><tt>+, -, *, /<br />expt<br />abs, sqr, sqrt<br />sin, cos, tan<br />asin, acos, atan</tt></td>
<td valign="top"> </td>
<td valign="top"><tt>string-append<br />string-length</tt></td>
<td valign="top"><tt>not, and, or</tt></td>
</tr>
<tr>
<th align="left" valign="top">Prädikate</th>
<td valign="top"><tt>number?</tt></td>
<td valign="top"><tt>char?<br />char=?<br />char<?</tt></td>
<td valign="top"><tt>string?<br />string=?<br />string<?</tt></td>
<td valign="top"> </td>
</tr>
<tr>
<th align="left" valign="top">Konstruktoren</th>
<td valign="top"> </td>
<td valign="top"> </td>
<td valign="top"><tt>string</tt></td>
<td valign="top"> </td>
</tr>
<tr>
<th align="left" valign="top">Selektoren</th>
<td valign="top"> </td>
<td valign="top"> </td>
<td valign="top"><tt>string-ref<br />substring</tt></td>
<td valign="top"> </td>
</tr>
<tr>
<th align="left" valign="top">Anwendungen</th>
<td valign="top">
<run id="4c76c0a04fb1c">(+ 2.3 4.5)</run>
<run id="506b7cb128705">(sin 1.25)</run>
<run id="4c76cc4792ae6">(expt -3 4)</run>
</td>
<td valign="top">
<run id="4c913ce3b4af8">(char? #\B)</run>
<run id="506b7cb1287a7">(char=? #\A #\A)</run>
<run id="4c913ce3b4c59">(char<? #\k #\b)</run>
</td>
<td valign="top">
<run id="4ca256b632e13">(string #\D #\u)</run>
<run id="506b7cb12883d">(string-ref "Info" 2)</run>
<run id="4ca256b632f7e">(substring "Kurs" 1 3)</run>
</td>
<td valign="top">
<run id="4c836d2799ac7">(< 4 1)</run>
<run id="4c836d2799c1e">(>= 4 1)</run>
<run id="506b7cb128931">(or (< 4 1) (< -1 5))</run>
</td>
</tr>
</table>
Zusätzlich gibt es Operatoren zur ''Konvertierung'' zwischen Daten unterschiedlicher Datentypen:
<run id="4c76c2ae86ced">
(string->list "Informatik")
</run>
<run id="539d5d9bd14e5">
(list->string '(#\o #\k))
</run>
<run id="4c76c2ae86e1c">
(number->string 12.34)
</run>
<run id="539d5d9bd15ed">
(number->string 12 2)
</run>
<run id="539d5d9bd16d4">
(number->string 12 16)
</run>
<run id="4c76c2ae86f43">
(string->number "2/3")
</run>
== Symbole ==
Mit der ''Quotierung'' kann die Evaluation von Ausdrücken unterdrückt werden:
<table>
<tr>
<td><run id="4c82acbf5b4a0">hallo</run></td>
<td><run id="4c82acbf5b609">'hallo</run></td>
</tr>
</table>
Damit wird zusätzlich die Definition eines Datentyps ''Symbol'' sinnvoll.<br />
Symbole sind nichtnumerische und nichtstrukturierte (d.h. atomare) Ausdrücke, deren Evaluation mit <tt>quote</tt> unterdrückt wird.
'''Beispiele:'''
<table>
<tr>
<td><run id="4c82acbf5b767">'x</run></td>
<td><run id="4c82acbf5b8c3">'11er</run></td>
<td><run id="5ba5ec8048cf6">'a-b</run></td>
<td><run id="4c82acbf5bb81">(quote Informatik)</run></td>
</tr>
</table>
<table border="1" cellspacing="1" cellpadding="4">
<tr>
<th width="100"> </th>
<th width="100">Syntax</th>
<th width="480">Beispiele</th>
</tr>
<tr>
<th align="left" valign="top">Prädikat</th>
<td valign="top"><tt>symbol?</tt></td>
<td><run id="4c82acbf5bce5">(symbol? 'pi)</run><br /><run id="4c82acbf5be46">(symbol? '1)</run></td>
</tr>
<tr>
<th align="left" valign="top">Konvertierungen</th>
<td valign="top"><tt>symbol->string<br />string->symbol</tt></td>
<td><run id="4c82acbf5bfa7">(symbol->string 'name)</run><br /><run id="4c82acbf5c103">(string->symbol "12")</run></td>
</tr>
</table>
Wir wissen bereits aus der [[Grundlagen der funktionsorientierten Programmierung mit SCHEME/Einführung in die Kommunikation mit Scheme|Einführung in die Kommunikation mit Scheme]]:<br />
Mit <tt>define</tt> kann man an ein Symbol einen Wert binden.
Symbole, an die Werte gebunden sind, heißen ''Variablen''.
<run id="4c82acbf5c260">
(define 11er "Wahlgrundkurs Informatik")
11er
</run>
Mit der Prozedur <tt>eval</tt> kann die Evaluation von Symbolen bei Bedarf erzwungen werden:
<run id="505798794a22e">
(define zahl 3.25)
(eval 'zahl)
</run>
Die Evaluation von Symbolen spielt bei der ''Symbolverarbeitung'' eine große Rolle.<br />
Wir wollen sie an dieser Stelle nur andeuten:
<code id="505798794a10b">
(define x 2)
(define y 3)
</code>
<run id="505798794a330">
(list '+ x y)
</run>
<run id="505798794a42b">
(eval (list '+ x y))
</run>
== Aufgaben ==
<ol>
<li>
Testen Sie die oben angegebenen Beispiele ausführlich.
</li>
<li>
Nachfolgend ist eine Prozedur zur universellen Datentypprüfung (''universal datacheck'') implementiert.<br />
Untersuchen Sie damit weitere Datentypen und -strukturen.
<code id="4c76cc4792989">
(define udc
(lambda (struktur)
(cond
[(number? struktur) "Datentyp ZAHL!"]
[(char? struktur) "Datentyp ZEICHEN!"]
[(string? struktur) "Datentyp ZEICHENKETTE!"]
[(symbol? struktur) "Datentyp SYMBOL!"]
[(list? struktur) "Datenstruktur LISTE!"]
[(pair? struktur) "Datenstruktur PAAR!"]
[(procedure? struktur) "Datenstruktur PROZEDUR!"]
[else
"Undefinierter Datentyp!"])))
</code>
<run id="4c76cc479300d">
(udc sqrt)
</run>
</li>
</ol>