ho trovato un modo utilizzando continuazioni di avere lambda anonimi si dicono e quindi utilizzando le macro Racket per mascherare la sintassi in modo che il lambda anonima sembra avere un operatore "autonomo". Non so se questa soluzione sia possibile in altre versioni di Scheme poiché dipende dalla funzione di continuazione chiamata-composable di racket e la macro per nascondere la sintassi utilizza i parametri di sintassi.
L'idea di base è questa, illustrata con la funzione fattoriale.
((lambda (n)
(call-with-values
(lambda() (call-with-composable-continuation
(lambda (k) (values k n))))
(lambda (k n)
(cond
[(= 0 n) 1]
[else (* n (k k (- n 1)))])))) 5)
La continuazione k è la chiamata alla funzione fattoriale anonima, che prende due argomenti, il primo essendo la continuazione stessa. In modo che quando nel corpo eseguiamo (k k N) che è equivalente alla funzione anonima che si chiama (nello stesso modo che farebbe un lambda ricorsivo chiamato).
Quindi mascheriamo il modulo sottostante con una macro. RACCHETTE sintassi parametri permettono la trasformazione di auto (args ...) a (kk ARGS ...)
modo che possiamo avere:
((lambda-with-self (n)
(cond
[(= 0 n) 0]
[(= 1 n) 1]
[else (* n (self (- n 1)))])) 5)
Il programma completo Racket per fare questo è:
#lang racket
(require racket/stxparam) ;required for syntax-parameters
( define-syntax-parameter self (λ (stx) (raise-syntax-error #f "not in `lambda-with-self'" stx)))
(define-syntax-rule
(lambda-with-self (ARG ...) BODY ...)
(lambda (ARG ...)
(call-with-values
(lambda()(call/comp (lambda (k) (values k ARG ...))))
(lambda (k ARG ...)
(syntax-parameterize ([self (syntax-rules ()[(self ARG ...) (k k ARG ...)])])
BODY ...)))))
;Example using factorial function
((lambda-with-self (n)
(cond
[(= 0 n) 0]
[(= 1 n) 1]
[else (* n (self (- n 1)))])) 5)
Questo risponde anche alla mia precedente domanda sulle differenze tra i diversi tipi di continuazioni. Different kinds of continuations in Racket
questo funziona solo perché a differenza di call-con-corrente di continuazione, call-con-componibile di continuazione di non interrompere di nuovo ad un prompt di continuità, ma invoca la continuazione nel luogo è stato invocato.
fonte
2012-09-11 18:22:39
Ascolta, ascolta. Nota che questo è anche un problema con "return" come appare nella maggior parte delle lingue (Java, C, ecc.). –
Credo che tecnicamente si possa rendere l'identificatore 'self' lessicale rispetto alla forma lambda. Puoi persino farlo da solo se hai "syntax-case". Sono d'accordo comunque, comunque. I nomi espliciti sono generalmente preferibili a quelli anaforici. –
@Matthias: In effetti, "può" e "dovrebbe" sono totalmente diversi, specialmente in questo contesto. ;-) Mi stavo occupando del perché fornire un 'sé' di default è una pessima idea, in generale. –