Nel semplice Schema R5RS, non esiste un sistema di moduli: solo il livello superiore thermore, la mentalità è che tutto può essere modificato, così puoi "personalizzare" la lingua come preferisci. Ma senza un sistema modulare questo non funziona bene. Ad esempio, io scrivo
(define (sub1 x) (- x 1))
in una libreria che si carica - e ora è possibile ridefinire -
:
(define - +) ; either this
(set! - +) ; or this
e ora è involontariamente rotto la biblioteca che si basava su sub1
decrementare suo ingresso per uno e di conseguenza le finestre si alzano quando le trascini verso il basso, o qualsiasi altra cosa.
L'unico modo per aggirare questo, che viene utilizzato da diverse biblioteche, è quello di "afferrare" la relativa definizione della funzione di sottrazione, prima che qualcuno possa modificarlo:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))
Ora le cose funzionerà "più fine ", poiché non è possibile modificare il significato della mia funzione sub1
modificando -
. (Tranne ... chi lo modifica prima di caricare la mia libreria ...)
In ogni caso, a causa di questo (e se si sa che il -
è quello originario quando la libreria viene caricata), alcuni compilatori lo rileveranno e vedranno che la chiamata -
sarà sempre la funzione di sottrazione effettiva e pertanto invieranno le chiamate ad essa (e inlining una chiamata a -
può alla fine risultare in codice assembly per sottrarre due numeri, quindi questo è un grande aumento di velocità). Ma come ho detto nel commento sopra, questo è più casuale della ragione attuale sopra.
Infine, R6RS (e diverse implementazioni regime prima che) ha risolto questo e ha aggiunto un sistema bibliotecario, quindi non c'è alcuna utilità per questo trucco: il codice sub1
è sicuro finchè altro codice nella sua libreria non sta ridefinendo -
in in qualche modo, e il compilatore può tranquillamente ottimizzare il codice basato su questo. Non c'è bisogno di trucchi intelligenti.
grazie per la risposta completa! – redwoolf