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:
oggetto= lambda {|args| codice} <oggetto/pre>Le=funzionilambda {|args|anonimesonotalmenteutilichesonostateintrodotteinmoltideilinguaggimodernicodice:}
Le C#,funzioni anonime sono talmente utili che sono state introdotte in molti dei linguaggi moderni: C#, python, ruby sono degli esempi.
C’e una differenza sottile tra le lambda di C#/python e quelle di ruby/lisp (la definizione di _verevere chiusure lessicali_.e
In
Sembra complicato ma non lo e
>> 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’ 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))
>>> 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
def esponenziale(n): ary=[n] def f(): ary.append(ary.pop()**2) return ary[0] return f</pre>
Ma stiamo divagando :)
Un’altra cosa affascinante che possiamo fare con le chiusure lessicali e'e’ la condivisione di variabili tra diverse procedure:
>> defadd_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> >>chiedendoacosacavoloviserveqestacosaadd.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
Thread.newThread.new {codice}codice}</pre>