Domanda

Sto cercando di dare un senso al qui (di seguito esempi) esempio. Non capisco che Parametrizzazione costruire. La documentazione per esso sono qui , ma non aiutano. Che cosa fa?

È stato utile?

Soluzione

parameterize viene usato per avere valori che sono "come ambito in modo dinamico". Si ottiene un parametro con make-parameter. Il parametro si comporta come una funzione: lo chiamano con nessun ingresso e si ottiene il suo valore, lo chiamano con un valore e sarà impostato il valore. Ad esempio:

> (define p (make-parameter "blah"))
> (p)
"blah"
> (p "meh")
> (p)
"meh"

Molte funzioni (tra cui molti quelli primitivi) utilizzano parametri come un modo per personalizzare il proprio comportamento. Per esempio printf stamperà roba utilizzando la porta che è il valore del parametro current-output-port. Ora, dire che hai qualche funzione che consente di stampare qualcosa:

> (define (foo x) (printf "the value of x is ~s\n"))

In genere chiama questa funzione e vedere qualcosa di stampato sullo schermo - ma in alcuni casi si desidera utilizzarla per stampare qualcosa su un file o qualsiasi altra cosa. Si potrebbe fare questo:

(define (bar)
  (let ([old-stdout (current-output-port)])
    (current-output-port my-own-port)
    (foo some-value)
    (current-output-port old-stdout)))

Un problema di questo è che è noioso da fare - ma questo è facilmente risolto con una macro. (In realtà, PLT ha ancora un costrutto che lo fa in alcune lingue:. fluid-let), ma ci sono più problemi qui: che cosa succede se la chiamata a foo risultati in un errore di runtime? Questo potrebbe lasciare il sistema in cattivo stato, dove tutto l'output va alla porta (e non sarà nemmeno vedere un problema, dal momento che non stamperà nulla). Una soluzione per questo (che fluid-let usa troppo) è quello di proteggere il salvataggio / ripristino del parametro con dynamic-wind, che fa in modo che se c'è un errore (e di più, se sai di continuazioni), allora il valore è ancora ripristinato.

Quindi la domanda è qual è il punto di avere parametri invece di utilizzare globali e fluid-let? Ci sono due problemi che non si possono risolvere con solo globali. Uno è quello che succede quando si dispone di più thread - in questo caso, l'impostazione del valore temporaneamente influenzerà gli altri thread, che possono ancora da stampare sullo standard output. Parametri risolvono questo avendo un valore specifico per-thread. Succede che ogni filo "eredita" il valore dal thread che ha creato e cambiamenti in un filo sono visibili solo in quel filo.

L'altro problema è più sottile. Diciamo che avete un parametro con un valore numerico, e si desidera effettuare le seguenti operazioni:

(define (foo)
  (parameterize ([p ...whatever...])
    (foo)))

In Scheme, "chiama coda" sono importanti - sono lo strumento di base per la creazione di loop e molto altro ancora. parameterize fa qualche magia che gli permette di cambiare il valore del parametro temporaneamente, ma conservano ancora queste chiamate di coda. Per esempio, nel caso di cui sopra, è ottenere un loop infinito, piuttosto che ottenere un errore di overflow dello stack - quello che succede è che ognuno di queste espressioni parameterize possono in qualche modo rilevare quando c'è un parameterize in precedenza che non ha bisogno di più tempo per fare la sua pulizia.

Infine, parameterize effettivamente utilizza due parti importanti di PLT per fare il suo lavoro: utilizza cellule discussione per implementare valori per filo, e utilizza segni di continuazione per poter conservare coda chiamate. Ognuna di queste caratteristiche è utile in sé.

Altri suggerimenti

parameterize imposta i parametri particolari valori specificati per la durata del blocco, senza influenzare i valori al di fuori di esso.

Parametrizzazione è un mezzo attraverso il quale è possibile ri-bind in modo dinamico i valori all'interno di una funzione già esistente, senza utilizzare lambda a farlo. In pratica a volte è molto più facile da usare parametrizzare per ri-bind valori all'interno di una funzione piuttosto che essere necessario per passare gli argomenti e legarli con lambda.

Ad esempio, dire che una libreria che si utilizza emette HTML per stdout, ma per motivi di convenienza che si desidera catturare quel valore in una stringa e di eseguire ulteriori operazioni su di esso. Il progettista libreria ha almeno due scelte da fare che facile per voi: 1) accettare una porta di uscita come un argomento della funzione o 2) parametrizzare il valore di corrente di uscita-porte. 1 è brutto e una seccatura. 2 è più bello dal momento che il comportamento più probabile è quello di stampare su stdout, ma nel caso in cui si desidera stampare una stringa di porta che si può solo parametrizzare la chiamata a tale funzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top