Robitex's Blog

Ideas in the web

Archivi Mensili: ottobre 2012

Napoli: tutto pronto per il GuITmeeting


GuITmeeting2012

Tra pochissimi giorni, Sabato 27 ottobre 2012 si terrà a Napoli il GuITmeeting 2012, uno dei più importanti tra i meeting organizzati dal GuIT, Gruppo utilizzatori italiani di TeX, che per la prima volta non si svolgerà nell’aula magna della scuola Sant’Anna di Pisa, ma nell’altrettanto prestigiosa sala del Centro congressi Partenope dell’Università degli Studi di Napoli Federico II.

Anch’io parteciperò molto volentieri essendo perfino riuscito a presentare un lavoro di cui vi posso dire solo il titolo: “La grafica ad oggetti con LuaTeX”.

Non mancate sarà una bellissima occasione

Qualsiasi cosa stiate facendo, collegatevi subito con il sito del GuIT alla pagina del modulo d’iscrizione 🙂 !
Grazie, ci vediamo a Napoli!

Iteratori in Lua


Costruzione di un iteratore in Lua

La costruzione di un iteratore in Lua si basa sulla creazione di una funzione che restituisce uno alla volta gli elementi dell’insieme nella sequenza desiderata. Una volta costruito l’iteratore, questo potrà essere impiegato in un ciclo foreach — che in Lua viene chiamato generic for — in modo molto efficiente.
Se per esempio si volesse iterare la collezione dei numeri pari compresi nell’intervallo da 1 a 10, avendo a disposizione l’apposito iteratore evenNum(first, last) che definiremo in seguito, potrei scrivere semplicemente:

for n in evenNum(1,10) do
   print(n)
end

ottenendo in console:

2
4
6
8
10

Numeri pari

Per definire questo iteratore dobbiamo creare una funzione che restituisce a sua volta una funzione in grado di generare la sequenza dei numeri pari. L’iterazione termina quando giunti all’ultimo elemento, la funzione restituirà il valore nullo ‘nil’, cosa che succede in automatico senza dover esplicitare un’istruzione di return.
Per prima cosa si calcola il numero pari successivo al numero di partenza dell’intervallo. Lo faremo usando la funzione math.ceil() che fornisce il numero arrotondato al primo intero superiore dell’argomento. Poi viene restituita la funzione in sintassi anonima che prima incrementa di 2 il numero pari precedente — ed ecco perché inizialmente viene sottratta la stessa quantità all’indice — e, se questo è inferiore all’estremo superiore dell’intervallo, verrà restituito l’indice corrente, il numero pari della sequenza:

-- iteratore dei numeri pari compresi
-- nell'intervallo [i, e]
function evenNum(i, e)
   -- primo numero pari della sequenza
   i = 2*math.ceil(i/2) - 2
   return function ()
             i = i + 2
             if i<=e then
                return i
             end
          end
end

Tecnicamente il sistema funziona perché ogni volta che viene chiamata una funzione, Lua crea le necessarie variabili in una nuova area di memoria, così che la funzione anonima possa lavorare correttamente. Ulteriori particolari possono essere reperiti nel libro ‘Programming in Lua‘, cosa consigliabile se si devono costruire iteratori in ambienti di produzione.

Naturalmente, l’implementazione data di evenNum() è solo una delle possibili soluzioni, e non è detto che non debbano essere considerate situazioni particolari come quella in cui si passa all’iteratore un solo numero o addirittura nessun argomento.

Stateless iterator

Una seconda versione del generatore di numeri pari può essere un buon esempio di un iteratore in Lua che non necessita di un area di memoria — chiamata closure — per un risultato ancora più efficiente.
Per capire come ciò sia possibile dobbiamo conoscere come funziona il ‘generic for’ in Lua; dopo la parola chiave ‘in’ esso si aspetta tre parametri: la funzione dell’iteratore da chiamare ad ogni ciclo, una variabile che rappresenta lo stato invariante, e la variabile di controllo.
Nel seguente codice la funzione evenNum() provvede a restituire i tre parametri necessari: la funzione nextEven() come iteratore, lo stato invariante che per noi è il numero a cui la sequenza dovrà fermarsi, e la variabile di controllo che è proprio il numero della sequenza dei numeri pari, e con ciò abbiamo realizzato un stateless iterator in Lua.
La funzione iteratrice nextEven() verrà chiamata ad ogni ciclo con nell’ordine lo stato invariante e la variabile di controllo, pertanto fate attenzione, dovete mettere in questo stesso ordine gli argomenti nella definizione.

-- even numbers stateless iterator
local function nextEven(last, i)
   i = i + 2
   if i<=last then
      return i
   end
end

local function evenNum(a, b)
   a = 2*math.ceil(a/2)
   return nextEven, b, a-2
end

-- example of generic for
for n in evenNum(10,20) do
print(n)
end

Lua non finisce mai di stupire…
Alla prossima!

%d blogger hanno fatto clic su Mi Piace per questo: