Note: Testo rimosso dalla rev 3  e Testo aggiunto nella rev4

Cos’e una funzione lambda o closure? Si tratta, sostanziualmente, di una funzione anonima.

Quello che fate quando usate each():

 array.each { |argomenti| codice }

in realta’ e’ equivalente a

 def f(argomenti)
  codice
 end
 for i in array
  f(i)
 end
/pre>

non e'e’ un caso che in ruby si possa creare una funzione anonima, cioe'cioe’ un oggetto @Proc@Proc scrivendo:

<pre>
oggetto= lambda {|args| codice}
<oggetto/pre>
Le= funzionilambda {|args| anonime sono talmente utili che sono state introdotte in molti dei linguaggi modernicodice:}

Le C#,funzioni anonime sono talmente utili che sono state introdotte in molti dei linguaggi moderni: C#, python, ruby sono degli esempi.

C'e

C’e una differenza sottile tra le lambda di C#/python e quelle di ruby/lisp (la definizione di _verevere chiusure lessicali_.e'lessicali.e’ ambigua,ambigua, in ogni caso).caso).

In realta'realta’ la differenza e’ molto sottile. Definiamo lo scope lessicale. In pratica significa che una funzione fa riferimento a delle variabili basandosi su quello che viene definito intorno a se direttamente nel testo, e' _molto_non sottile.al Definiamomomento lo _scope lessicale_. In pratica significa che una funzione fa riferimento a delle variabili basandosi su quello che viene definito intorno a se direttamente nel testo, e non al momento dell'esecuzionedell’esecuzione del codice.

Sembra complicato ma non lo e',e’, guardate:guardate:

<pre>
 >> def esponenziale(num)
 >>  proc { num=num*num }
 >> end
 => nil
 >> b=esponenziale(2)
 => #<Proc:0x027d61d8@(irb):2>
 >> a=esponenziale(3)
 => #<Proc:0x027d61d8@(irb):2>
 >> a.call
 => 9
 >> b.call
 => 4
 >> a.call
 => 81
 >> a.call
 => 6561
 >> b.call
 => 16 
</pre>

cosa succede? succede che l'oggettol’oggetto @Proc@Proc si _chiude_chiude sopra alle variabili che si trovano nel suo pezzettino di codice. Non importa se poi noi usiamo altri valori (ad esempio, richiamando @esponenziale()@esponenziale() con un altro parametro.

Perche'

Perche’ questo sistema e'e’ diversa da quello di pythonPython e C#? ((*pregasi((pregasi verificare, nn sono esperto di python, faccio riferimento a "PaulPaul Graham":http://store.yahoo.com/paulgraham/accgen.html*))Graham))

<pre>
 >>> def esponenziale(n):
 ...  lambda a: n=n*n
 ...
   File "<stdin>", line 2
 SyntaxError: can't assign to lambda
</pre>

Python ha delle _chiusurechiusure lessicali_lessicali nelle quali si ha riferimento all'all’oggetto, ma non alla variabile stessa. Il comportamento va emulato, chiudendo la variabile in un altro oggetto, ma non alla variabile stessa. Il comportamento va emulato, chiudendo la variabile in un altro oggetto

<pre>
  def esponenziale(n):
   ary=[n]
   def f():
    ary.append(ary.pop()**2)
    return ary[0]
   return f
</pre>

Ma stiamo divagando :)

Un'altra

Un’altra cosa affascinante che possiamo fare con le chiusure lessicali e'e’ la condivisione di variabili tra diverse procedure:

<pre>
 >> def add_sub(default)
 >>   return proc {default+=1},proc {default-=1}
 >> end
 => nil
 >> add,sub=add_sub(10)
 => [#<Proc:0x0275a968@(irb):25>, #<Proc:0x0275a878@(irb):25>]
 >> add
 => #<Proc:0x0275a968@(irb):25>
 >> add.call 
 => 11
 >> sub.call
 => 10
 >> sub.call
 => 9
 >> add.call
 => 10
 >> add.call
 => 11
 >> add.call
 => 12
 >> sub.call
 => 11
<add_sub/(predefault>)


 >>   return proc {default+=1},proc {default-=1}
 >> end
 => Ovviamentenil
 >> add,sub=add_sub(10)
 => vi[#<Proc:0x0275a968@(irb):25>, #<Proc:0x0275a878@(irb):25>]
 >> stareteadd
 => #<Proc:0x0275a968@(irb):25>
 >> chiedendo a cosa cavolo vi serve qesta cosaadd.call 
 => Beh11
 ,>> capiretesub.call
 => 10
 >> lsub'.utilitacall
 ',=> 9
 >> forseadd,.call
 => 10
 >> pensandoadd.call
 => 11
 >> cheadd.call
 => 12
 >> trasub.call
 => 11

Ovviamente, vi starete chiedendo a cosa cavolo vi serve qesta cosa. Beh, capirete l’utilita’, forse, pensando che tra le altre cose,cose, un blocco,blocco, cioe'cioe’ un oggetto proc, cioe'cioe’ una chiusura lessicale,lessicale, e'e’ quello che definisce il comportamento di un @Thread@Thread

<pre>
 Thread.newThread.new { codice}codice}
</pre>
Created on December 30, 2005 14:15 by Ruby Fan (151.37.158.228)