Grundlagen der funktionsorientierten Programmierung mit SCHEME/Datentypen

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</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>&nbsp;</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></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">&nbsp;</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">&nbsp;</td>
</tr>
<tr>
<th align="left" valign="top">Konstruktoren</th>
<td valign="top">&nbsp;</td>
<td valign="top">&nbsp;</td>
<td valign="top"><tt>string</tt></td>
<td valign="top">&nbsp;</td>
</tr>
<tr>
<th align="left" valign="top">Selektoren</th>
<td valign="top">&nbsp;</td>
<td valign="top">&nbsp;</td>
<td valign="top"><tt>string-ref<br />substring</tt></td>
<td valign="top">&nbsp;</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="4c82acbf5ba21">'|der Unterricht|</run></td>
<td><run id="4c82acbf5bb81">(quote Informatik)</run></td>
</tr>
</table>

<table border="1" cellspacing="1" cellpadding="4">
<tr>
<th width="100">&nbsp;</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>