package main

// Y = 𝜆𝑓.(𝜆𝑥.𝑓(𝑥𝑥))(𝜆𝑥.𝑓(𝑥𝑥))

import "fmt"

type (
	F func(string, int)

	FF func(F) F

	YF func(YF) F
)

func Y(ff FF) F {
	g := func(y YF) F {
		return ff(func(name string, n int) {
			y(y)(name, n)
		})
	}
	return g(g)
}

func Print(p F) F {
	return func(name string, n int) {
		if n > 0 {
			fmt.Printf("%d. %s \n", n, name)
			p(name, n-1)
		}
	}
}

func main() {
	printMyName := Y(Print)
	printMyName("Fathir", 1000)
}