La Ipsilona Kombinatoro En Ses Paŝoj

Esperante  Angle
25a de Novembro 2017
Laste ŝanĝita: 1a de Decembro 2017

Unue, decidu. Kaj faru ĝin. Estas la nur maniero por atingi ion.
―Lacus CLYNE, Gundam SEED Destiny

Multe da ni estis instruitaj ke, por difini rikuran proceduron, la rikura alvoko devas uzi la nomon de la rikuran proceduron. La ipsilona kombinatoro (angle), tamen, permesas onin por presti rikuron, sen referenci la nomatan identigilon.

Enhavotabelo

Kio?

La ipsilona kombinatoro estas la fonto de kaj inspiro kaj frustro de multaj homoj. Elvokas sensacion kiel eŭreka tuj oni pasis la muron, sed ankaŭ faras nin por skrapi niajn kapojn kiam ne faras sencon por trairi la labirinton. Ĉi tiu artikolo celas porti miajn proprajn metodojn kiel derivi la ipsilonan kombinatoron. Eble ne estas la plej eleganta maniero, tamen eblas fari por vi.

En la kodaj ekzemploj en ĉi tiu artikolo, la > simbolo montras la invitan simbolon de via skima realigo.

Paŝo 1a: Difinu la bazan proceduron

Ni komencu per difini proceduron nomata foo kiu komputas la sumadon de pozitiva entjero, malsupren al nul. En la sekvanta kodaĵo, la rikura alvoko okazas kiam foo estas aplikata en la else-a parto de la kondiĉo.

> (define foo
    (lambda (n)
      (if (zero? n)
          0
          (+ n (foo (- n 1))))))
> (foo 100)
5050

Vi rimarkis, ke mi difinis foo per eksplicita lambda. Vi vidos postnelonge kial.

Paŝo 2a: Funkcivokarigu la rikuran alvokon

Ni dismembrigu tiun proceduron pli detale, per pli rudimentaj eroj, kaj vi aplikos ĝin, per funkcivokarigi (angle currying).

> (define foo
    (lambda (f)
      (lambda (n)
        (if (zero? n)
            0
            (+ n ((f f) (- n 1)))))))
> ((foo foo) 100)
5050

La plia lambda estis bezonata ĉar vi bezonis havi manieron por abstrakti la rikuran alvokon. Tiaokaze, vi uzis la identigilon f por kunligi la rikuran proceduron, kiu estas foo, mem. La stranga ((f f) …) estas bezonata, tial ke vi devas fari la saman proceduran alvokan metodon uzata interne: ((foo foo) 100).

Paŝo 3a: Apliku la proceduron al si mem

Vi nun estas troprofitonta ĉi tiun kvaliton, por uzi sennomatan aliro—ne per la foo identigilo.

> (((lambda (f)
      (lambda (n)
        (if (zero? n)
            0
            (+ n ((f f) (- n 1))))))
    (lambda (f)
      (lambda (n)
        (if (zero? n)
            0
            (+ n ((f f) (- n 1)))))))
   100)
5050

Konstatu, ke nun, vi ne plu uzos la foo nomon por referenci la difinon, krom poste.

Paŝo 4a: Abstraktu la enan alvokon

Sekve, vi bezonas movi la (f f) parton ekster, por izoli la ĝeneralan (ipsilona kombinatoro), el la specifa (foo) kodo.

> (((lambda (f)
      ((lambda (p)
         (lambda (n)
           (if (zero? n)
               0
               (+ n (p (- n 1))))))
       (lambda (v) ((f f) v))))
    (lambda (f)
      ((lambda (p)
         (lambda (n)
           (if (zero? n)
               0
               (+ n (p (- n 1))))))
       (lambda (v) ((f f) v)))))
   100)
5050

Dum la aplikaĵo de alvoko, la identigilo p estos kunligata al (lambda (v) ((f f) v)), kaj la identigilo v estos kunligata al (- n 1).

Paŝo 5a: Izolu la kombinatoron

Sekve, vi izolos la ipsilonan kombinatoro, el la foo proceduro.

> (((lambda (x)
      ((lambda (f)
         (x (lambda (v) ((f f) v))))
       (lambda (f)
         (x (lambda (v) ((f f) v))))))
    (lambda (p)
      (lambda (n)
        (if (zero? n)
            0
            (+ n (p (- n 1)))))))
   100)
5050

Vi anstataŭigu la difinon specifa al foo, per x. Ĉi tio bezonas vin, denove, por krei la enhavatan lambda. Tial ke x estas kunligata al la komputata proceduro, vi ne plu bezonas ripeti ĝin.

Paŝo 6a: Difinu la kombinatoron

Fine, vi eksplicite kreos apartan proceduran difinon por la ipsilona kombinatoro mem, kaj la foo proceduro.

> (define y
    (lambda (x)
      ((lambda (f)
         (x (lambda (v) ((f f) v))))
       (lambda (f)
         (x (lambda (v) ((f f) v)))))))
> (define foo
    (lambda (p)
      (lambda (n)
        (if (zero? n)
            0
            (+ n (p (- n 1)))))))
> (define f (y foo))
> (f 100)
5050

Finaj rimarkoj

Kiam la kurtaj konceptoj estas komprenata, estos facila por kapti la ŝajne malfacilegajn ideojn. Mi esperas, ke ĉi tiu artikolo estas utila por fari vin kompreni la ipsilonan kombinatoron, funkcivokarigi, kaj proceduran aplikon.