Data abstractie

Een van de grondbeginselen van goed programmeren is de scheiding van programma en gegevens (data). Voorbeelden:
 
Opdracht Programma Data
Memory Based Learner learner/classifier instances: features, classe; frequentielijst: classe, frequentie
Overhoringsprogramma programma paren: Engels, Nederlands
Parser parser grammatikaregels: linker, rechter kant
Galgje programma woord, welke letters al geraden

Ten eerste betekent dit bijvoorbeeld dat de grammatikaregels niet als Scheme-functies van de parser ge´mplementeerd zijn, maar ergens in een lijst zitten.
Maar ten tweede moet ook het precieze formaat van die lijstelementen niet uitmaken. Zo kan ik de regel S -> NP VP uitdrukken als ( S NP VP ) of ( NP VP S ) of ( ( NP VP ) . S ). Al naar gelang waarvoor ik kies zouden in mijn parserprogramma uitdrukkingen als (car regel) of (car (reverse regel)) of (cdr regel) opduiken, als ik de linker kant van de regel (de S) bedoel. Dit is niet alleen onoverzichtelijk, maar ook erg onhandig als ik later besluit om van formaat te wisselen, want dan moet ik die uitdrukkingen op alle plaatsen vervangen. Beter is het om in dit geval een aparte functie "linker_kant" te maken, die als input een regel krijgt, en als output de linker kant levert. Alleen deze functie hoeft te "weten" hoe het formaat van die regels nou precies is. En alleen deze functie hoef ik dus aan te passen als ik van formaat wissel. Overal elders blijft gewoon (linker_kant regel) staan. Dit is data abstractie in een notedop.
Nog verder doorgevoerd wordt deze gedachte in object-georienteerd programmeren, waar elke regel samen met de functie "linker_kant" een apart object vormt, en de linker kant van de regel alleen via deze objectsfunctie toegankelijk is. Maar Scheme is niet object-georienteerd.
 

Voorbeeld

(define my-eof #!eof)                    ; gambit
(define my-file "stud.txt")              ; gambit
; (define my-eof eof)                    ; pcscheme
; (define my-file "C:/terug/stud.txt")   ; pcscheme

;;;;;;;;;;;;;;;;;;; initialisatie ;;;;;;;;;;;;

(define sb
   (lambda ()
      (define poort (open-input-file my-file) ) 
      (studbeheer-r (lees_lijst '() poort))
      (close-input-port poort)
)  )

(define lees_lijst
  (lambda (lijst poort)
    (define woord (read poort))
    (if (equal? my-eof woord)
	lijst
      (lees_lijst (cons woord lijst) poort))))

;;;;;;;;;;;;;;;;;;; hoofdprogramma ;;;;;;;;;;;;

(define studbeheer-r
   (lambda (ls)
      (display "Wilt u student t)oevoegen,") (newline)
      (display "op a)chternaam sorteren,")   (newline)
      (display "l)ijst afprinten")   (newline)
      (display "gemiddelde p)unten berekenen of")   (newline)
      (display "s)toppen")   (newline)
      (display "(toets t,a,l,p of s)") (newline)
      (let ((keuze (read)))
         (if (equal? keuze 's)
            (begin 
               (display "Tot ziens")
               (newline)
            )
            (begin               ; de "else"
               (newline)
               (cond ((equal? keuze 't) (set! ls (cons (nieuwe-stud) ls)))
                     ((equal? keuze 'a) (set! ls (sorteer ls)))
                     ((equal? keuze 'l) (druk-af ls))
                     ((equal? keuze 'p) (middel-punten 0 0 ls))
                     (else (display "Verkeerde letter!"))
               )
               (newline)
               (studbeheer-r ls)
)  )  )  )  ) 
    
;;;;;;;;;;;;;; hulpprogramma's ;;;;;;;;;;;;;

(define nieuwe-stud
   (lambda ()
      (display "Voornaam (als string!): ")
      (let ((voornaam (read)))
         (display "Achternaam (als string!): ")
         (let ((achternaam (read)))
            (display "Nummer: ")
            (let ((nummer (read)))
               (display "Punten: ")
               (let ((punten (read)))
                  (make-stud voornaam achternaam nummer punten)
)  )  )  )  )  )

(define sorteer    
   (lambda (ls)
      (if (null? ls)
         '()
         (begin 
            (set! ls (alpha-first ls))
            (cons (car ls)
                  (sorteer (cdr ls))
)  )  )  )  ) 
(define alpha-first
   (lambda (ls)
      (if (equal? 1 (length ls))
         ls
         (let ((rest (alpha-first (cdr ls))))
            (if (string

Opdracht

Pas het programma zo aan dat het i.p.v. met een file zoals dit:
( ( "Jacqueline" "Dake" ) 1 393)
( ( "Ashra" "Sugito" ) 2 575)
( ( "Jan" "Van Gerwen" ) 3 303)
( ( "Emiel" "Maarschalkerweerd" ) 4 676)
met een file zoals dit werkt:
( "Jacqueline" "Dake" 1 393)
( "Ashra" "Sugito" 2 575)
( "Jan" "Van Gerwen" 3 303)
( "Emiel" "Maarschalkerweerd" 4 676)
NB: Voor het gemak hebben we het boven zo geregeld dat het formaat in het file hetzelfde is als het interne dataformaat in het programma. Dit hoeft helemaal niet, en wordt ook vaak niet zo gedaan. Dus er zijn twee oplossingen mogelijk voor de opdracht (maar een is genoeg).