Anonymous Functions in Delphi

Lambda Functions( λ-calculus)

Programlamada isimsiz procedure veya fonksiyonlar kullanmak yeni bir olay değil. Bu deyim ilk kez Alonzo Church tarafından 1936 da kullanılmış.
C# diline 3.0 da delphi ye ise Delphi 2009 da eklenmiş bir özellik.Python programlama dilindede oldukça yaygın bir kullanımı var.Java gibi bir programlama dilinde ise henüz bulunmuyor ama Java 7 ile dile eklenmesi planlanıyor.
Bu özellik sayesinde Procedure veya function lazım olduğu anda yazıyorsunuz önceden bir tanımlama yapmıyorsunuz.Yani procedure de neyin nasıl yürütüleceği bilinmiyor.

Neden İsimsiz Function/Procedure

Elbette her şeyin bir nedeni vardır.
Programlamada procedure ve function yazmamızın sebebi kod tekrarlarını azaltmaktır. Bazen bir kaç satırlık ve tekrar kullanımı az olan fonksyionlarda yazarız. Function yazarak kod kalabalığından kurtulmayı umduğumuz halde function yazmak kodumuzu daha karışık hale getirebiliyor.
Bu aşamada lambda function bize yardımcı olabilir.Mesala elimizdeki bir dizide her elemana bir değer ekleyip yeniden kullanmak istesek veya arama ve sıralama işlemleri için karşılaştırma işlemleri yapmak istesek lambda function yazabiliriz.
İşte temel kullanım türleri

  • Değişken Atamak
  • Event Olarak Kullanılabilir
  • Prametrelere kod bloğu geçmek için kullanılabilir
  • Method pointer lara nazaran daha kolay olduğu için kullanılabilir

Mevzuyu fazla uzatmadan delphi ile bu işin nasıl yapıldığını gösterelim.

Nasıl Yapılır

Öncelikle gerekli tanımlamızı yapıyoruz.Bu tanımlama ile procedure ün tipi ve parametre sayısı belirtiliyor.

 
TSimpleProcedure=reference to procedure;
 

Sonrasında isimsiz procedure kod içinde yazılıyor ve kullanılıyor.

 
procedure TForm1.Button1Click(Sender: TObject);
var
p1:TSimpleProcedure;
begin
p1 := Procedure
begin
  showmessage('deneme');
end;
p1();
end;
 

İşte böyle birşey. Bunu ilk kez gören Delphi programıcılarına biraz garip gelebilir. Çünkü delphi de her şey tanımlama bloklarında tanımlanıp daha sonra kullanılıyor. Burada procedure kod içinde yazılmış oluyor.
Aşağıdaki örnekte procedure'e bir lambda function yazılarak değer geçiliyor. Hiç bir ön tanımlama olmamasına dikkat edin.

 
//    Procedure Hesapla(a:integer); şeklinde bir proc olduğunu düşünün
  Hesapla(  (function(x:integer):integer  begin    result :=x*x;  end)(5)  );
 

Ama benim denememde bu kod derlendiği halde çalışmadı. Çalışma anında Access violation veya Privilege error verdi.
Şimdilik en iyisi ön tanımlama yaparak kullanmak :) Yani bu şekilde

 
  f1 := function(x:integer):integer  begin    result :=x*x;  end;
  Hesapla( f1(5));
 

Eğer Hesapla procedure şu şekilde yazmış olsaydık rahatça parametreye kod bloğu verebilirdik.

 
    Procedure Hesapla(sayi:integer;aFunc:TSimpleFunction);
begin
  ShowMessage(inttostr(aFunc(sayi)));
end;
 

işte bu şekilde kullanımı olur.

 
  Hesapla(5, function(x:integer):integer  begin    result :=x*x;  end);
 

MultiThread sistemler yazarken kullandığımız TThread.Synchronize da artık kod parametresi alıyor.

 
  TThread.Synchronize(AThread,Procedure begin form1.caption := 'Canvas değişsin' end );
 
    • No Related Post
bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark bookmark
tabs-top

1 Comment »

  1. çok güzel bir olay bence bu. özellikle 3. kod blogundaki gibi yazılabilmesi güzel bir zemin olmuş. LINQ alternatifi bişey için altyapı oluşuyor olabilir. ya da bu bir eksikti ve yapıldı bilmiyorum. Teşekkürler bilgi için.

    comment-bottom

RSS feed for comments on this post. TrackBack URL

Leave a comment