... (if (string (voornaam (car ls)) (voornaam (car rest))) ...Als we op nummer willen sorteren zouden we opnieuw kopietjes van die functies moeten maken, maar dit keer met:
... (if (< (nummer (car ls)) (nummer (car rest))) ...
Dit kan handiger. Het toverwoord is "functionele argumenten". Het enige verschil tussen de drie sorteerfuncties boven was het gebruik van verschillende vergelijkings- en toegangsfuncties. We schrijven nu een algemene sorteer-functie en geven de specieke vergelijkings- en toegangsfunctie als argument mee:
(define sorteer (lambda (ls vergelijking toegangsfunctie) (if (null? ls) '() (begin (set! ls (alpha-first ls vergelijking toegangsfunctie)) (cons (car ls) (sorteer (cdr ls) vergelijking toegangsfunctie) ) ) ) ) ) (define alpha-first (lambda (ls vergelijking toegangsfunctie) (if (equal? 1 (length ls)) ls (let ((rest (alpha-first (cdr ls) vergelijking toegangsfunctie))) (if (vergelijking (toegangsfunctie (car ls)) (toegangsfunctie (car rest))) (cons (car ls) rest) (cons (car rest) (cons (car ls) (cdr rest) ) ) ) ) ) ) ) >(define stud '( ( ( "Jacqueline" "Dake" ) 1 393) ( ( "Ashra" "Sugito" ) 2 575) ( ( "Jan" "Van Gerwen" ) 3 303) ( ( "Emiel" "Maarschalkerweerd" ) 4 676) ) ) > (sorteer stud string voornaam) ((("Ashra" "Sugito") 2 575) (("Emiel" "Maarschalkerweerd") 4 676) (("Jacqueline" "Dake") 1 393) (("Jan" "Van Gerwen") 3 303)) > (sorteer stud string>? achternaam) ((("Jan" "Van Gerwen") 3 303) (("Ashra" "Sugito") 2 575) (("Emiel" "Maarschalkerweerd") 4 676) (("Jacqueline" "Dake") 1 393)) > (sorteer stud < nummer) ((("Jacqueline" "Dake") 1 393) (("Ashra" "Sugito") 2 575) (("Jan" "Van Gerwen") 3 303) (("Emiel" "Maarschalkerweerd") 4 676)) > (sorteer stud > punten) ((("Emiel" "Maarschalkerweerd") 4 676) (("Ashra" "Sugito") 2 575) (("Jacqueline" "Dake") 1 393) (("Jan" "Van Gerwen") 3 303))
Voorbeelden voor gebruik van "map":
> (map string-length '("as" "qwe" "" "irtuoyiuero" "pppp")) (2 3 0 11 4) > (map number? '(1 q 2 w 3 e r 4 5 t)) (#t #f #t #f #t #f #f #t #t #f) > (map car '( (a s d) (f g h) (j k l) ) ) (a f j)Deze functie kunnen we nu ook zelf schrijven:
(define my-map-1 (lambda (func ls) (if (null? ls) '() (cons (func (car ls) ) (my-map-1 func (cdr ls)) ) ) ) )Hoe pas je "map" nou toe als je zoiets wilt als "tel bij elk element 1 op"?
> (define hulp-functie (lambda (i) (+ 1 i))) > (map hulp-functie '(1 2 3)) (2 3 4)of korter met een anonieme functie:
> (map (lambda (i) (+ 1 i)) '(1 2 3)) (2 3 4)Maar "map" kan meer. Tot nu toe hadden we het alleen gebruikt met functies die maar één argument namen. Hier zijn voorbeelden met meerdere argumenten:
> (map + '(1 2 3) '(4 5 6)) (5 7 9) > (map + '(1 2 3) '(4 5 6) '(7 8 9)) (12 15 18) > (map cons '(a b c) '((1 2) (3 4) (5 6))) ((a 1 2) (b 3 4) (c 5 6)) > (map equal? '(a s d f) '(a w e f)) (#t #f #f #t) > (map +) *** ERROR IN (stdin)@199.1 -- Wrong number of arguments passed to procedure (map '#Ook dit kunnen we zelf schrijven (dat wordt wel een beetje ingewikkelder). Let op het gebruik van de nieuwe vorm van "lambda" en de toepassing van "apply":) > (map + '(1 2 3) '(4 5 6) '(7 8)) *** ERROR IN (stdin)@201.1 -- Lists are not of equal length (map '# '(1 2 3) '(4 5 6) '(7 8))
(define my-map-n (lambda input ; LET OP: lambda met flexibel aantal argumenten ; (display "input=") (display input) (newline) (let ((func (car input)) (args (cdr input))) (if (null? (car args)) '() (cons (apply func (my-map-1 car args) ) (apply my-map-n (cons func (my-map-1 cdr args) ) ) ) ) ) ) ) > (my-map-n + '(1 2 3) '(4 5 6) '(7 8 9)) (12 15 18)En alsof het allemaal nog niet genoeg is kunnen we functies behalve als argumenten ook nog als "return values" gebruiken. Dit is de functie die een functie teruggeeft die zijn argument met een bepaald bedrag verhoogt:
> (define verhoog (lambda (met-wat) (lambda (argument) (+ met-wat argument)))) > (map (verhoog 1) '(1 2 3)) (2 3 4) > (map (verhoog 5) '(1 2 3)) (6 7 8)En we hoeven natuurlijk niet altijd op te tellen:
> (define doe-iets (lambda (wat met-wat) (lambda (argument) (wat met-wat argument)))) > (map (doe-iets + 1) '(1 2 3)) (2 3 4) > (map (doe-iets - 5) '(1 2 3)) (4 3 2) ; nee, hier komt niet (-4 -3 -2) uit! > (map (doe-iets string-append "de ") '("man" "vrouw" "hond" "kat")) ("de man" "de vrouw" "de hond" "de kat")
> (filter number? '(1 q 2 e 3 r 4 5 t y)) (1 2 3 4 5) > (filter symbol? '(1 q 2 e 3 r 4 5 t y)) (q e r t y) > (filter list? '(1 q 2 e 3 r 4 5 t y)) () > (filter (lambda (ls) (not (null? ls))) '( (a s d) () (1 2) ("oiu") () )) ((a s d) (1 2) ("oiu"))