Grundlagen der funktionsorientierten Programmierung mit SCHEME/Bedingte Ausdrücke

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
== Bedingte Ausdrücke in Scheme ==

<code id="4c7ebb194160f" hidden>(require-extension (srfi 13))</code>

Bedingte Ausdrücke sind Programmstrukturen, mit denen der ''Wert'' eines Ausdrucks von bestimmten ''Bedingungen'' abhängig gemacht werden kann.

<table border="1" cellspacing="1" cellpadding="4">
<tr>
<th width="37%">Grundform</th>
<th width="30%">Alternative</th>
<th width="33%">Fallauswahl</th>
</tr>
<tr>
<td>

<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="160" width="500" valign="top">
<code id="4c9cb9191269f">
(define gewichtspruefer
  (lambda (masse)
    (cond
      [(< masse 60) 'leichtgewicht]
      [(< masse 80) 'normalgewicht]
      [(< masse 100) 'schwergewicht]
      [else
       'uebergewicht])))
</code>
</td>
</tr>
<tr>
<td height="100" width="500" valign="top">
<eval id="4c7ebb1941f9b">(gewichtspruefer 75)</run>
</td>
</tr>
</table>

</td>
<td>

<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="160" width="500" valign="top">
<code id="4c7ebb1941871">
(define my-abs
  (lambda (x)
    (if (< x 0)
        (- x)
        x)))
</code>
</td>
</tr>
<tr>
<td height="100" width="500" valign="top">
<eval id="4c7ebb19420c5">(my-abs -3.45)</run>
</td>
</tr>
</table>

</td>
<td>

<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="160" width="500" valign="top">
<code id="4c9e20fdaaf21">
(define vokal?
  (lambda (zeichen)
    (case zeichen
      [(#\a #\e #\i #\o #\u) #t]
      [(#\A #\E #\I #\O #\U) #t]
      [else #f])))
</code>
</td>
</tr>
<tr>
<td height="100" width="500" valign="top">
<eval id="4c9e20fdab08f">(vokal? #\o)</run>
</td>
</tr>
</table>

</td>
</tr>
<tr>
<td valign="top">
'''Beachte:'''<br />
<ul>
<li>die angegebenen Bedingungen werden in der vorgegebenen Reihenfolge evaluiert,</li>
<li>sobald sich zum ersten Mal der Wahrheitswert <tt>#t</tt> ergibt, werden keine weiteren Bedingungen untersucht
(selbst dann nicht, wenn ein fehlerhafter Ausdruck wie <tt>(/&nbsp;4&nbsp;0)</tt> erscheint) – die Evaluation wird an dieser Stelle beendet,</li>
<li>else wird immer zu <tt>#t</tt> evaluiert, sodass bei seiner Evaluation immer der nachfolgende Ausdruck abgearbeitet wird.</li>
</ul>
</td>
<td valign="top">
'''Beachte:'''<br />
<ul>
<li>der <tt>else</tt>–Teil kann grundsätzlich entfallen,</li>
<li>in beiden Teilen darf nur ein Ausdruck stehen, anderenfalls muss mit
<tt>(begin&nbsp;<Ausdruck>&nbsp;...&nbsp;<Ausdruck>)</tt> ein ''zusammengesetzter Ausdruck'' gebildet werden,</li>
<li>unbestimmten Rückgabewerten, wie
<pre>
(define my-sqrt
  (lambda (x)
    (if (>= x 0) (sqrt x))))
</pre> 
sollten vermieden werden.</li>
</ul>
</td>
<td valign="top">
'''Beachte:'''<br />
<ul>
<li>zunächst wird der nach <tt>case</tt> folgende Ausdruck evaluiert,</li>
<li>in einer Suche von oben nach unten wird festgestellt, in welcher Auswahlmenge sein Wert vorkommt,</li>
<li>der zu dieser Menge gehörende Ausdruck wird evaluiert und als Wert des gesamten <tt>case</tt>–Ausdrucks zurückgegeben,</li>
<li>falls der Wert in keiner Menge enthalten ist, bildet der Wert nach <tt>else</tt> das Resultat.</li>
</ul>
</td>
</tr>
</table>

== Aufgaben ==

<ol>
<li>
=== Signumfunktion ===

Schreiben Sie eine Prozedur für die einstellige Funktion <tt>signum</tt>, die als Funktionswerte
-1, 1 oder 0 entsprechend des Vorzeichens der als Argument übergebenen Zahl zurückgibt.<br />
'''Beispiele:'''
<pre>
(signum -337.8436) --> -1
(signum 0)         -->  0
(signum 34/45)     -->  1
</pre>

<code id="4c7ebb1941ac3">
(define signum
  (lambda (x)
    ...))
</code>

<check>
(and (= (signum -337.8436) -1) (= (signum 0) 0) (= (signum 34/45) 1))
</check>

<eval id="4c7ebb1942316">
(signum -337.8436)
</run>
</li>
<li>
=== Klassenstärkenprüfer ===

Lehrer und Schüler bewerten Klassenstärken etwa mit folgenden Einschätzungen:
* 10 ... 15: geringe Klassenstärke,
* 16 ... 20: ideale Klassenstärke,
* 21 ... 25: normale Klassenstärke,
* 26 ... 32: hohe Klassenstärke,
Alle anderen Schülerzahlen sind unzulässig.
Implementieren Sie einen "Klassenstärkenprüfer" als bedingten Ausdruck mit den Sprachelementen:
* <tt>cond</tt>
* <tt>if</tt>
* <tt>case</tt>.

<code id="4c7ebb1941bef">
(define klassenstaerke1
  (lambda (anzahl)
    (cond
      ...)))
</code>

<eval id="4c7ebb194248a">
(klassenstaerke1 12)
</run>

<code id="4c7ebb1941d1d">
(define klassenstaerke2
  (lambda (anzahl)
    (if
      ...)))
</code>

<eval id="4c7ebb19425b3">
(klassenstaerke2 21)
</run>

<code id="4c7ebb1941e4e">
(define klassenstaerke3
  (lambda (anzahl)
    (case
      ...)))
</code>

<eval id="4c7ebb19426de">
(klassenstaerke3 38)
</run>
</li>
</ol>