Best Practice - Dove dichiarare le variabili in Common Lisp?

4

Generalmente in linguaggi procedurali / imperativi, è consigliabile posizionare le dichiarazioni delle variabili il più vicino possibile all'utilizzo.

Questo sembra un po 'confuso in lisp, considerando che viene usato più codice se ci sono lets separati.

Dato un esempio di funzione che usa due lets :

(defun draw-box (new-image corners)
  (let ((h-len (- (alast (alast corners))
                  (alast (car corners))))
        (h-offset (alast (car corners))))
    (dotimes (i h-len)
      (setf (aref new-image (car (car corners)) (+ i h-offset) 0) 0)
      (setf (aref new-image (car (car corners)) (+ i h-offset) 1) 255)
      (setf (aref new-image (car (car corners)) (+ i h-offset) 2) 0)

      (setf (aref new-image (car (alast corners)) (+ i h-offset) 0) 0)
      (setf (aref new-image (car (alast corners)) (+ i h-offset) 1) 255)
      (setf (aref new-image (car (alast corners)) (+ i h-offset) 2) 0)))

  (let ((v-len (- (car (alast corners))
                  (car (car corners))))
        (v-offset (car (car corners))))
    (dotimes (i v-len)
      (setf (aref new-image (+ i v-offset) (alast (car corners)) 0) 0)
      (setf (aref new-image (+ i v-offset) (alast (car corners)) 1) 255)
      (setf (aref new-image (+ i v-offset) (alast (car corners)) 2) 0)

      (setf (aref new-image (+ i v-offset) (alast (alast corners)) 0) 0)
      (setf (aref new-image (+ i v-offset) (alast (alast corners)) 1) 255)
      (setf (aref new-image (+ i v-offset) (alast (alast corners)) 2) 0))))

Dove non userò v-len e v-offset fino a metà della funzione, sono titubante a dichiararlo nella parte superiore della funzione solo per usare solo un let .

Ciò che è generalmente considerato best practice quando si dichiarano variabili in funzioni più lunghe in cui si potrebbe usare una variabile solo più tardi nella funzione?

    
posta Joel Lord 06.12.2018 - 03:46
fonte

1 risposta

6

Il tuo approccio è corretto: noi leghiamo (piuttosto che dichiariamo , come in altre lingue) le variabili esattamente dove ne abbiamo bisogno. (Nel tuo caso, tuttavia, stai usando h-offset nella prima metà della tua funzione, solo senza che nomina it).

La logica è la stessa: leggibilità del codice.

Si noti che non è necessario associare una variabile monouso, è sufficiente scrivere

(dotimes (i (- (alast ...) (alast ...)))
  ...)

Nota anche che potresti voler apportare alcune altre modifiche (ad es., chiamata singola a setf e definizione di una funzione separata che modifica image ).

Nota anche che non dovresti ricalcolare cose come (alast (alast corners)) in un ciclo (suppongo che ogni alast abbia una velocità lineare), quindi dovresti probabilmente fare qualcosa del genere:

(defun draw-box (new-image corners)
  (let* ((corners-0 (car corners))
         (v-offset (car corners-0))
         (h-offset (alast corners-0))
         (corners-l (alast corners))
         (h-last (alast corners-l))
         (v-last (car corners-l)))
    (flet ((set-0-255-0 (x y)
             (setf (aref new-image x y 0) 0
                   (aref new-image x y 1) 255
                   (aref new-image x y 2) 0)))
      (loop for i = h-offset below h-last do
          (set-0-255-0 v-offset i)
          (set-0-255-0 v-last i))
      (loop for i = v-offset below v-last do
          (set-0-255-0 i h-offset)
          (set-0-255-0 i h-last)))))
    
risposta data 06.12.2018 - 15:30
fonte

Leggi altre domande sui tag