Ho una funzione ricorsiva che deve recurse fino a quando non trova un determinato risultato. Tuttavia nel corpo della mia funzione dopo la mia prima chiamata ricorsiva potrei fare altri calcoli o eventualmente ricorrere nuovamente. Ma se ricevo e trovo il risultato che sto cercando, mi piacerebbe semplicemente fermarmi da qualsiasi ricorsivo che stavo facendo e restituire quel risultato per evitare di fare calcoli inutili.Torna alla chiamata di livello superiore di una funzione ricorsiva in Lisp
In una normale chiamata ricorsiva una volta raggiunto il "caso base" che viene restituito alla funzione che ha chiamato, viene restituito a quello che lo ha chiamato e così via. Mi piacerebbe sapere come tornare alla prima volta in cui è stata chiamata la funzione e non dover restituire qualcosa per tutti quei passaggi intermedi.
Per il mio ricorsione base che potrebbe scrivere una funzione come questa:
(defun recurse (x)
(if (= x 10)
(return-from recurse x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse 1)
E 'stato scritto per illustrare quello che voglio dire circa la funzione che esegue più calcoli dopo una chiamata ricorsiva. E, come scritto, questo non restituisce nemmeno il valore a cui sono interessato poiché faccio delle stampe dopo che ho restituito il valore a cui tengo. (Nota: il comando return-from è estraneo qui poichè potrei semplicemente scrivere "x" al suo posto. È lì solo per tracciare paralleli quando cerco di tornare alla ricorsione di primo livello nel mio secondo esempio qui sotto.)
Ora, se voglio abbandonare tutti quelli extra "Riscatto!" printings Potrei racchiudere tutto in un blocco e poi tornare a quel blocco invece:
EDIT: Ecco un wrapper di funzioni per il mio esempio originale. Questo esempio dovrebbe essere più chiaro ora.
(defun recurse-to-top (start)
(block top-level
(labels ((recurse (x)
(if (= x 10)
(return-from top-level x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse start))))
E l'esecuzione di questo blocco continua ad andare fino a 10 "si trova" e poi torna a dal blocco di livello superiore senza stampa estranei, proprio come volevo. Ma questo sembra un modo davvero goffo per ottenere questa funzionalità. Mi piacerebbe sapere se esiste un modo standard o "migliore" per ottenere questo tipo di comportamento.
Nel tuo esempio con un blocco "Riscatto!" è * mai * stampato, quindi perché è lì in primo luogo? Credo che il tuo vero codice abbia qualcosa di più che è stato perso nel tuo esempio. – uselpa
, ad esempio, '(defun recurse (x) (if (= x 10) x (recurse (+ x 1))))' fa esattamente quello che vuoi. – uselpa
Hai frainteso la mia domanda. Il punto della stampa all'interno della mia funzione è di dimostrare una funzione ricorsiva che potrebbe fare le cose dopo una chiamata ricorsiva. Nel primo esempio si vede che ciascuna delle funzioni di stampa viene eseguita perché si verificano dopo ogni volta che la ricorsione ritorna. Il secondo esempio è stato scritto per mostrare un potenziale modo per aggirare questo problema tornando fino al livello più alto della mia chiamata ricorsiva, quindi non facendo altri comandi. Ho lasciato il comando di stampa lì proprio per mostrare che in quell'esempio non verrà eseguito. – Nyles