Deskripsi algoritma Anda terlalu samar untuk dievaluasi saat ini. Tapi, berikut beberapa hal yang perlu dipertimbangkan.
CPS
Bahkan, ada cara untuk mengubah kode apa pun menjadi bentuk yang hanya menggunakan panggilan ekor. Ini adalah transformasi CPS. CPS ( Continuation-Passing Style ) adalah bentuk kode pengekspresian dengan meneruskan setiap fungsi sebagai kelanjutan. Kelanjutan adalah gagasan abstrak yang mewakili "sisa dari suatu kompuasi". Dalam kode yang dinyatakan dalam bentuk CPS, cara alami untuk memverifikasi kelanjutan adalah sebagai fungsi yang menerima nilai. Dalam CPS, alih-alih fungsi yang mengembalikan nilai, melainkan menerapkan fungsi yang mewakili kelanjutan saat ini untuk "dikembalikan" oleh fungsi.
Misalnya, pertimbangkan fungsi berikut:
(lambda (a b c d)
(+ (- a b) (* c d)))
Ini dapat diungkapkan dalam CPS sebagai berikut:
(lambda (k a b c d)
(- (lambda (v1)
(* (lambda (v2)
(+ k v1 v2))
a b))
c d))
Itu jelek, dan sering lambat, tetapi memang memiliki keuntungan tertentu:
- Transformasi dapat sepenuhnya otomatis. Jadi tidak perlu menulis (atau melihat) kode dalam bentuk CPS.
- Dikombinasikan dengan thunking dan trampolining , ini dapat digunakan untuk memberikan optimisasi panggilan-tail dalam bahasa yang tidak memberikan optimisasi panggilan-panggilan. (Optimalisasi Tail-call dari fungsi tail-recursive langsung dapat dicapai melalui cara lain, seperti mengubah panggilan rekursif menjadi sebuah loop. Tetapi rekursi tidak langsung tidak sepele untuk dikonversi dengan cara ini.)
- Dengan CPS, kelanjutan menjadi objek kelas satu. Karena kelanjutan adalah inti dari kontrol, ini memungkinkan setiap operator kontrol untuk diimplementasikan sebagai perpustakaan tanpa memerlukan dukungan khusus dari bahasa. Misalnya, goto, pengecualian, dan threading kooperatif semua dapat dimodelkan menggunakan kelanjutan.
TCO
Tampak bagi saya bahwa satu-satunya alasan untuk khawatir dengan ekor-rekursi (atau ekor-panggilan pada umumnya) adalah untuk keperluan optimasi ekor-panggilan (TCO). Jadi saya pikir pertanyaan yang lebih baik untuk ditanyakan adalah "apakah kode hasil transformasi saya yang ekor-panggilan dioptimalkan?".
Jika kita sekali lagi mempertimbangkan CPS, salah satu karakteristiknya adalah bahwa kode yang diekspresikan dalam CPS hanya terdiri dari ekor-panggilan. Karena semuanya adalah panggilan ekor, kita tidak perlu menyimpan titik kembali ke stack. Jadi semua kode dalam bentuk CPS harus dioptimalkan untuk panggilan ekor, bukan?
Ya tidak cukup. Anda tahu, sementara itu mungkin tampak bahwa kita telah menghilangkan tumpukan, semua yang telah kita lakukan hanyalah mengubah cara kita mewakilinya. Tumpukan sekarang merupakan bagian dari penutupan yang mewakili kelanjutan. Jadi CPS tidak secara ajaib membuat semua kode panggilan ekor kami dioptimalkan.
Jadi jika CPS tidak bisa membuat semuanya TCO, apakah ada transformasi khusus untuk rekursi langsung yang bisa? Tidak, tidak secara umum. Beberapa rekursi adalah linier, tetapi beberapa tidak. Rekursi non-linear (misalnya, pohon) hanya harus mempertahankan jumlah variabel dari suatu tempat.