Tracks
/
Clojure
Clojure
/
Ejercicios
/
Transformación de coordenadas
Transformación de coordenadas

Transformación de coordenadas

Ejercicio de aprendizaje

Introducción

Los closures son un patrón de programación en Clojure que permite usar variables de un ámbito léxico externo dentro de una función. Clojure admite los closures de forma transparente, y muchas veces se usan sin saber qué son.

;; 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))

Closures para guardar estado y pasar valores

Usar un atom permite conservar algo de estado:

;; 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))))

Cada llamada sucesiva a increment incrementa su contador:

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

Instrucciones

Tu empresa de diseño ha trabajado principalmente con transformaciones CSS para crear páginas web. Después de algunas conversaciones, se decidió empezar a usar Clojure para hacer algunos cálculos de forma dinámica. Algunos de tus compañeros tienen menos experiencia con Clojure, así que decides usar una clausura para crear transformaciones reutilizables para pares de coordenadas {x, y}.

1. Traslada las coordenadas

Implementa la función translate2d que devuelve una función que hace uso de una clausura para realizar una traslación 2D repetible de un par de coordenadas.

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

2. Escala las coordenadas

Implementa la función scale2d que devuelve una función que hace uso de una clausura para realizar un escalado 2D repetible de un par de coordenadas.

Para este ejercicio, asume solo valores de escalado positivos.

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

3. Compón funciones de transformación

Combina dos funciones de transformación para realizar una transformación repetible. A esto se le suele llamar composición de funciones, donde el resultado de la primera función 'f(x)' se usa como argumento de la segunda función '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. Guarda los resultados de las funciones

Implementa la función memoize-transform. Recibe una función para memorizar y después devuelve una función nueva que recuerda los argumentos de la función recibida, de modo que el último valor devuelto se pueda «recordar» y solo se calcule una vez si se vuelve a llamar con los mismos argumentos.

A la memorización a veces se le llama programación dinámica; permite que las operaciones costosas se hagan solo una vez, ya que su resultado se recuerda.

(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
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Clojure Exercism

¿Todo listo para empezar Transformación de coordenadas?

Regístrate en Exercism para aprender y dominar Clojure con 12 conceptos105 ejercicios y mentoría humana real, todo gratis.