Neprogramátor/Nová slovesa: definice funkcí

Čaroděj vymýšlí kouzelné věty, které pak kouzelná hůlka vykoná. Velmi často se ale stane, že kouzelná hůlka nezná sloveso, které čaroděj v kouzelné větě používá. Pak je potřeba, aby čaroděj kouzelnou hůlku nové sloveso naučil.

Pro kouzelnou hůlku je neznámé sloveso třeba přičti-jedna-k:

(přičti-jedna-k 5)

Čaroděj ví, jak by hůlka takovou větu měla vykonat -- k číslu pět přičíst jedničku:

(+ 1 5)

Protože čaroděj ví, co kouzelná věta (přičti-jedna-k 5) s novým slovesem přičti-jedna-k znamená, může kouzelnou hůlku nové sloveso naučit tím, že jí v kouzelném jazyce vysvětlí, cože to nové kouzelné sloveso přičti-jedna-k udělá s každým podstatným jménem číslo:

(define (přičti-jedna-k číslo)
  (+ 1 číslo))

Když se potom ve větě (přičti-jedna-k číslo) použije místo číslo konkrétní informace, tedy podstatné jméno 5, z kouzelné věty (přičti-jedna-k 5) se stane (+ 1 5) a z kouzelné věty (přičti-jedna-k 6) se stane (+ 1 6). Nové kouzelné sloveso přičti-jedna-k je vlastně jméno pro větu (+ 1 číslo).

Sloveso define čaroděj už používal pro pojmenování informací:

(define délka 20)

Trochu oklikou se dá říci, že sloveso je také taková informace; informace o tom, co se má stát s nějakými podstatnými jmény. Použití kouzelného slovesa define proto tak nějak dává smysl.

Zdvořilá sčítačka editovat

Občas se stane, že se čaroděj nudí nebo ho přestanou bavit kalkulačky, které neodpovídají celou větou. Rozhodne se tedy, že naučí kouzelnou hůlku slušně odpovídat na dotazy o sčítání dvou čísel:

(sečti 4 9)

Akceptovatelný výsledek by mohl být třeba "Součet čísel 4 a 9 je 13.". Součet čísel 4 a 9 je v kouzelném jazyce (+ 4 9). Kouzelné sloveso string-append slouží ke spojování textů a když chce čaroděj použít v textu číslo, vzpomene si na kouzelné sloveso number->string. Kouzelná věta je tedy:

(string-append "Součet čísel "
               (number->string 4)
               " a "
               (number->string 9)
               " je "
               (number->string (+ 4 9))
               ".")

Jak kouzelnou hůlku naučit nové kouzelné sloveso sečti?

(define (sečti první-číslo druhé-číslo)
  (string-append "Součet čísel "
                 (number->string první-číslo)
                 " a "
                 (number->string druhé-číslo)
                 " je "
                 (number->string (+ první-číslo druhé-číslo))
                 "."))

Trable s balením krabic editovat

Přemlouváním kouzelné hůlky, aby byla při sčítání zdvořilá, čaroděj stejně jen prokrastinuje a vyhýbá se skutečnému problému, totiž balení krabic.

Přesněji tedy problému, jak kouzelnou hůlku naučit, aby rozuměla (kolik-papíru 20 10 2) (520 cm2) a (kolik-papíru 13 17 6.5) (832 cm2) a (kolik-stuhy 20 10 2) (68 cm) a (kolik-stuhy 13 17 6.5) (86 cm).

Jak na to, čaroděj ví. Buď:

(let ((délka 20)
      (šířka 10)
      (výška 2))
  (+ (* 2 (* délka šířka))
     (* délka výška) (* šířka výška)
     (* délka výška) (* šířka výška)))

nebo:

(define délka 20)
(define šířka 10)
(define výška 2)
(+ (* 2 (* délka šířka))
   (* délka výška) (* šířka výška)
   (* délka výška) (* šířka výška))

Větě (kolik-papíru 20 10 2) se říká volání funkce kolik-papíru s argumenty 20, 10 a 2. (Argumenty jako aktuální hodnoty.)

Větě (kolik-papíru délka šířka výška) se říká hlavička funkce s parametry délka, šířka a výška. Hlavička funkce se používá při definici nové funkce, tedy při pojmenovávání kouzelné věty, tedy když čaroděj učí kouzelnou hůlku nové kouzelné sloveso.

(define (kolik-papíru délka šířka výška)
  (+ (* 2 (* délka šířka))
     (* délka výška) (* šířka výška)
     (* délka výška) (* šířka výška)))

Volání funkce

(kolik-papíru 20 10 2)

pak vrátí 520 (centimetrů čtverečních).

Kouzelná věta pro výpočet délky stuhy zní:

(+ (* 2 délka) (* 2 šířka) (* 4 výška))

Jak kouzelnou hůlku naučit nové kouzelné sloveso kolik-stuhy?

(define (kolik-stuhy délka šířka výška)
  (+ (* 2 délka) (* 2 šířka) (* 4 výška)))

Zdvořilé balení krabic editovat

Čaroděj by mohl naučit kouzelnou hůlku, aby na věty se slovesy kolik-papíru a kolik-stuhy odpovídala celou větou. Většinou to ale neudělá. Čaroději se hodí, že výsledek vykonání takových kouzelných vět je číslo, protože pak může použít kouzelná slovesa pro čísla a kouzelnou hůlku nechat třeba rozhodnout, která krabice je větší:

(define (první-krabice-větší? délka-první šířka-první výška-první
                              délka-druhé šířka-druhé výška-druhé)
  (if (> (kolik-papíru délka-první šířka-první výška-první)
         (kolik-papíru délka-druhé šířka-druhé výška-druhé))
    #t
    #f))
(první-krabice-větší? 20 10 2 13 17 6.5)

Co kouzelná hůlka na větu nahoře?

#f

Lze kouzelnou větu, která vytvoří nové sloveso první-krabice-větší?, zjednodušit?

Nápověda: Lze vynechat kouzelné sloveso if?

Ano, lze:

(define (první-krabice-větší? délka-první šířka-první výška-první
                              délka-druhé šířka-druhé výška-druhé)
  (> (kolik-papíru délka-první šířka-první výška-první)
     (kolik-papíru délka-druhé šířka-druhé výška-druhé)))

To ale neznamená, že s kouzelnou hůlkou nemůže komunikovat společensky. Stačí kouzelnou hůlku naučit nová slovesa, třeba řekni-kolik-papíru a řekni-kolik-stuhy. Když kouzelná hůlka vykoná kouzelnou větu

(řekni-kolik-papíru 20 10 2)

vrátí text:

"Na krabici délky 20, šířky 10 a výšky 2 je potřeba 520 centimetrů čtverečních papíru."

Jak čaroděj kouzelnou hůlku naučí kouzelné sloveso řekni-kolik-papíru?

(define (řekni-kolik-papíru délka šířka výška)
  (string-append "Na krabici délky " (number->string délka)
                 ", šířky " (number->string šířka)
                 " a výšky " (number->string výška)
                 " je potřeba "
                 (number->string (kolik-papíru délka šířka výška))
                 " centimetrů čtverečních papíru."))

Jak čaroděj kouzelnou hůlku naučí kouzelné sloveso řekni-kolik-stuhy?

(define (řekni-kolik-stuhy délka šířka výška)
  (string-append "Na krabici délky " (number->string délka)
                 ", šířky " (number->string šířka)
                 " a výšky " (number->string výška)
                 " je potřeba "
                 (number->string (kolik-stuhy délka šířka výška))
                 " centimetrů stuhy."))

Která krabice je větší? editovat

Protože kouzelná hůlka teď zná kouzelná slovesa jako první-krabice-větší? nebo řekni-kolik-papíru, může čaroděj kouzelnou hůlku naučit ještě kouzelné sloveso řekni-která-krabice-je-větší. Takové sloveso se použije třeba v kouzelné větě

(řekni-která-krabice-je-větší 20 10 2 13 17 6.5)

na kterou kouzelná hůlka odpoví:


"Větší je druhá krabice. Na krabici délky 13, šířky 17 a výšky 6.5 je potřeba 832.0 centimetrů čtverečních papíru."

Jak čaroděj kouzelnou hůlku naučí kouzelné sloveso řekni-která-krabice-je-větší?

(define (řekni-která-krabice-je-větší
          délka-první šířka-první výška-první
          délka-druhé šířka-druhé výška-druhé)
  (if (první-krabice-větší? délka-první šířka-první výška-první
                            délka-druhé šířka-druhé výška-druhé)
    (string-append
      "Větší je první krabice. "
      (řekni-kolik-papíru délka-první šířka-první výška-první))
    (string-append
      "Větší je druhá krabice. "
      (řekni-kolik-papíru délka-druhé šířka-druhé výška-druhé))))

Čaroděj učí kouzelnou hůlku nová slovesa postupně a často používá kouzelných sloves a podstatných jmen, která kouzelnou hůlku již naučil. Čaroděj potřebuje vědět, která kouzelná slovesa na sobě závisí, protože kdyby na nějaké zapomněl, kouzelná hůlka by mu nerozuměla.

Kouzelné sloveso řekni-která-krabice-je-větší závisí na první-krabice-větší? a řekni-kolik-papíru.

Obě kouzelná slovesa první-krabice-větší? i řekni-kolik-papíru závisí na kolik-papíru.

Kouzelné sloveso kolik-papíru závisí už jen na slovesech pro čísla, která kouzelná hůlka dobře zná.

Čaroděj chce kouzelnou hůlku naučit řekni-která-krabice-má-delší-stuhu. Která všechna (!) slovesa musí čaroděj kouzelnou hůlku naučit? Jak to udělá?

(define (řekni-která-krabice-má-delší-stuhu
          délka-první šířka-první výška-první
          délka-druhé šířka-druhé výška-druhé)
  (if (delší-stuhu-má-první? délka-první šířka-první výška-první
                             délka-druhé šířka-druhé výška-druhé)
    (string-append
      "Delší stuhu má první krabice. "
      (řekni-kolik-stuhy délka-první šířka-první výška-první))
    (string-append
      "Delší stuhu má druhá krabice. "
      (řekni-kolik-stuhy délka-druhé šířka-druhé výška-druhé))))
(define (delší-stuhu-má-první?
          délka-první šířka-první výška-první
          délka-druhé šířka-druhé výška-druhé)
  (> (kolik-stuhy délka-první šířka-první výška-první)
     (kolik-stuhy délka-druhé šířka-druhé výška-druhé)))
(define (řekni-kolik-stuhy délka šířka výška)
  (string-append "Na krabici délky " (number->string délka)
                 ", šířky " (number->string šířka)
                 " a výšky " (number->string výška)
                 " je potřeba "
                 (number->string (kolik-stuhy délka šířka výška))
                 " centimetrů stuhy."))
(define (kolik-stuhy délka šířka výška)
  (+ (* 2 délka) (* 2 šířka) (* 4 výška)))

Potom kouzelná hůlka na kouzelnou větu

(řekni-která-krabice-má-delší-stuhu 20 10 2 13 17 6.5)

odpoví:


"Delší stuhu má druhá krabice. Na krabici délky 13, šířky 17 a výšky 6.5 je
potřeba 86.0 centimetrů stuhy."

Jaké jsou rozměry krabic splňující, že první krabice je větší, ale druhá má delší stuhu?

Třeba:

(řekni-která-krabice-je-větší 5 5 5 1 1 10)

"Větší je první krabice. Na krabici délky 5, šířky 5 a výšky 5 je potřeba 150 centimetrů čtverečních papíru."

(řekni-která-krabice-má-delší-stuhu 5 5 5 1 1 10)

"Delší stuhu má druhá krabice. Na krabici délky 1, šířky 1 a výšky 10 je potřeba 44 centimetrů stuhy."

Slovníček kouzelného jazyka editovat

Kouzelné sloveso define může čaroděj použít k tomu, aby kouzelnou hůlku naučil nové kouzelné sloveso. To udělá tak, že napíše, jak by nová kouzelná věta (používající nové kouzelné sloveso) měla vypadat a co by se mělo stát s podstatnými jmény použitými v nové kouzelné větě:

(define (nové-kouzelné-sloveso podstatná-jména oddělená mezerami)
  (co-vykonat-s podstatná-jména oddělená mezerami))

Kde kouzelné sloveso co-vykonat-s musí kouzelná hůlka znát předem.

◄ Neprogramátor/Vykonat či nevykonat: predikáty a podmínkové výrazy Nová slovesa: definice funkcí