Track
/
Clojure
Clojure
/
Esercizi
/
Trasformazione di coordinate
Trasformazione di coordinate

Trasformazione di coordinate

Esercizio di apprendimento

Introduzione

Le closure sono un pattern di programmazione in Clojure che permette di usare all'interno di una funzione le variabili di uno scope lessicale esterno. Clojure supporta le closure in modo trasparente e spesso vengono usate senza sapere cosa siano.

;; Top-level definitions are global-scope
(def dozen 12)

;; Functions create a new scope.
;; Referencing the outer variable here is a closure.
(fn [n] (* dozen n))

Closure per conservare lo stato e passare i valori

Usare un atom permette di conservare parte dello stato:

;; This function closure increments the counter's state
;; in the outer lexical context.
;; This way the counter can be shared between many calling contexts.

(def increment
  (let [counter (atom 0)]
    (fn [] (swap! counter inc))))

Ogni chiamata successiva a increment incrementa il suo contatore:

(increment)
;;=> 1
(increment)
;;=> 2

Istruzioni

La tua azienda di design ha lavorato principalmente con trasformazioni CSS per costruire pagine web. Dopo qualche discussione, si è deciso di iniziare a usare Clojure per eseguire alcuni calcoli in modo dinamico. Alcuni dei tuoi colleghi hanno meno esperienza con Clojure, quindi decidi di usare una closure per creare trasformazioni riutilizzabili per coppie di coordinate {x, y}.

1. Traslare le coordinate

Implementa la funzione translate2d che restituisce una funzione che fa uso di una closure per eseguire una traslazione 2d ripetibile di una coppia di coordinate.

(def move-coordinates-right-2px (translate2d 2 0))
(def result (move-coordinates-right-2px 4 8))
;; result => [6 8]

2. Scalare le coordinate

Implementa la funzione scale2d che restituisce una funzione che fa uso di una closure per eseguire una scalatura 2d ripetibile di una coppia di coordinate.

Per questo esercizio, supponi che i valori di scalatura siano solo positivi.

(def double-scale (scale2d 2 2))
(def result (double-scale 6 -3))
;; result => [12 -6]

3. Combinare le funzioni di trasformazione

Combina due funzioni di trasformazione per eseguire una trasformazione ripetibile. Questa operazione è spesso chiamata composizione di funzioni, dove il risultato della prima funzione 'f(x)' viene usato come input della seconda funzione 'g(x)'.

(def move-coordinates-right-2px (translate2d 2 0))
(def double-coordinates (scale2d 2 2))
(def composed-transformations 
  (compose-transform move-coordinates-right-2px 
                     double-coordinates))
(def result (composed-transformations 0 1))
;; result => [4 2]

4. Salvare i risultati delle funzioni

Implementa la funzione memoize-transform. Prende una funzione da memoizzare, poi restituisce una nuova funzione che ricorda gli input della funzione fornita, così che l'ultimo valore restituito possa essere «ricordato» e calcolato una sola volta se viene chiamata di nuovo con gli stessi argomenti.

La memoizzazione è talvolta chiamata programmazione dinamica: permette di eseguire operazioni costose una sola volta, dato che il loro risultato viene ricordato.

(def triple-scale (scale2d 3 3))
(def memoized-scale (memoize-transform triple-scale))

(memoized-scale 4 3)
;; => [12, 9], this is computed since it hasn't been computed before for the arguments

(memoized-scale 4 3)
;; => [12, 9], this is remembered, since it was computed already
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Clojure Exercism

Vuoi iniziare Trasformazione di coordinate?

Iscriviti a Exercism per imparare e padroneggiare Clojure con 12 concetti105 esercizi e il mentoring di persone reali, tutto gratis.