Map, Fold, Lambda ve Fonksiyonel Programlama Üzerine

Giriş

Son 5 aydır eski adı ile PLT-Scheme, yeni adı ile Racket kullanarak problemler çözüyor ve fonksiyonel programlamanın güzelliklerini görüyoruz . Her programcının hayatının belli bir bölümünü fonksiyonel programlama ile geçirmesi gerçek anlamda çok yararlı oluyor ve düşünce yapısını değiştiriyor. Bu konu farklı bir blog girdisinin konusu olacağı için konuya fazla eğilmeden başlıkta da belirttiğim şeyler hakkında bir şeyler karalamayı planlıyorum.

Bu blog girdisinde map, fold ve lambda’nın ne olduğuna ve nasıl çalıştığına değinip, bunları kullanarak çözülebilecek güzel bir problem yazacağım. Bahsedilen fonksiyonlar birçok programlama dillerinde mevcut ve hepsinin altında yatan mantık aynı. Yazının daha rahat anlaşılır olabilmesi adına Racket’in sözdizimine değinmek yararlı olacak. Genel olarak Racket’a giriş, high-order fonksiyonların tanımı üzerine yoğunlaşan bir yazı olacak.

(Kodların renklendirilmemesinden ötürükusura bakmayınız. Anladığım kadarıyla WordPress Racket için kod renklendirmesi desteklemiyor)

Racket, infix prefix notation diye tabir edilen, prosedürlerin önce geldiği, sonrasında parametrelerin yer aldığı bol parantezli bir dil. Tipik bir toplama işlemi

(+ 2 3)
(+ 2 3 4 5 6)

şeklinde yapılıyor. Burada +, iki veya daha çok sayı cinsinden parametre alabilen ve sayıların toplamını döndüren bir fonksiyon. Tıpkı matametikte olduğu gibi, iç içe geçmiş fonksiyonlar da yazabiliyoruz. 3 4 ve 5 sayılarını toplayıp, sonrasında elde edilen rakamı 2 ile çarpmak istersek;

(* 2 (+ 3 4 5))

yazmamız yeterli olacaktır. Bir fonksiyon tanımlamayı define prosedürü ile yapıyoruz. iki parametre alan ve bunları birbiri ile çarpan basit bir fonksiyonu aşağıdaki gibi tanımlayabiliriz.


(define (carp bir iki)

(* bir iki))

Daha fazlası için How to Design Programs kitabını okuyabilirsiniz. Şimdilik bu kadar işimizi görecek.

Lambda

Yukarıda, bir fonksiyon tanımladık ve buna bir isim verdik. Ancak her fonksiyona bir isim vermek zorunda mıyız? Hayır. Lambda bu noktada işimize yarıyor. Lambda’yı bize bir fonksiyon döndüren anonim bir fonksiyon olarak adlandırabiliriz. Örneğin bir parametre alan ve bunun karesini döndüren bir fonksiyon elde etmek istiyorsak


(lambda (x) (sqr x))

yazmamız yeterli olacaktır. Bu yukarıda yaptığımız toplama işlemindeki gibi kullanabiliriz. Hatırlayın, prosedürler önce ve parametreler sonra geliyor. Eğer lambda bize bir fonksiyon döndürüyorsa, bu fonksiyonu direkt olarak çağırabilir ve işimizi halledebiliriz. Öyleyse;

((lambda (x) (sqr x)) 2)

bize 4 sonucunu verecektir. Lambda, high-order fonksiyonları kullanırken çok işimize yarayacak. Devam etmeden önce bildiğiniz bir programlama dilini kullanarak bunun üzerinde biraz pratik yapmanız yararlı olacaktır.

High-Order Functions

High-order fonksiyonlar, genel olarak, en azından parametre olarak bir fonksiyon alan veya çıktı olarak bir fonksiyon döndüren fonksiyonlardır. Fonksiyonumuz bir veri almak yerine, bir fonksiyon alabilir ve bununla harikalar yaratabiliriz. İşte Racket’taki map, foldr, foldl, filter gibi fonksiyonlar bu kategoriye girer. Diğer programlama dillerinde de map, fold ve filter mevcut.

High-order fonksiyonlar, listeleri işlemede bize büyük kolaylıklar sağlıyor.  Map, listedeki her eleman üzerinde işlem yaparak, işlem sonrasında çıkan sonucu bir liste halinde döndürür. Filter ise, her eleman üzerinde işlem yaparak, bizim belirttiğimiz kurallara uyan liste elemanlarını seçip, bir liste döndürüyor. Adından da anlaşılacağı gibi, belli bir koşula bağlı olarak liste elemanlarını filtreliyor.

Biraz daha açacak olursak. Map, kendisine ilk parametre olarak, tek bir parametre kabul eden ve sonuçta bir şey döndüren bir fonksiyon alıyor, ikinci parametre olarak da üzerinde bu fonksiyonun uygulanacağı liste alıyor. Sonrasında, listenin her elemanını teker teker alıp, o fonksiyona parametre olarak veriyor, fonksiyondan dönen sonucu yeni bir liste halinde bize sunuyor. Listedeki her sayıyı bir arttıran bir map ifadesi şu şekilde yazabiliriz;


(map (lambda (parametre) (+ 1 parametre)) (list 1 2 3 4 5))

Burada dikkatinizi lambda’ya çekmek istiyorum. Map ilk parametre olarak bir fonksiyon alıyor demiştik. Bu fonksiyonu dışarıda bir yerde tanımlamak yerine, lambda ile o fonksiyonu oluşturduk ve map’e parametre olarak verdik. İstersek listedeki her elemanın karesini de şu şekilde alabilirdik;


(map sqr (list 1 2 3 4 5))

Sqr fonksiyonu, bir parametre alan ve sonucunda o sayının karesini döndüren bir fonksiyondur. Burada lambda’nın ve map’in ne iş yaptığını daha iyi görebileceğinizi umuyorum. Genellikle high-order fonksiyonları kullanırken fonksiyonlar dışarıda tanımlanmaz ve lambda ile hızlı bir biçimde işlem yapılır.

Filter da map ile aynı mantıkta çalışıyor ancak kendisine parametre olarak aldığı fonksiyonun boolean bir veri, yani doğru veya yanlış döndürmesini bekler. Bunu her liste elemanının kontrolünü sağlıyor gibi düşünebiliriz. Eğer o liste elemanı fonksiyona giriyor, ve sonucunda True dönüyor ise, o eleman çıktıdaki listede yer alacaktır. (1 3 4 5 7 88) listesindeki 4ten büyük elemanları almak için aşağıdaki kodu kullanabiliriz.


(filter (lambda (x) (> x 4)) (list 1 3 4 5 7 88))



Tekrar hatırlatmak isterim. Listedeki her eleman sıra ile fonksiyona parametre olarak gönderiliyor, eğer fonksiyondan dönen sonuç True ise, sonrasında döndürülecek olan listeye ekleniyor, değilse zaten listede yer almıyor.

Fold, map ve filter’dan biraz daha karışık. Map gibi birinci parametre olarak fonksiyon alıyor ancak bu fonksiyon iki parametreli. Sonraki parametre olarak iterasyona başlamak için bir veri, ve en son olarak da üzerinde işlem yapacağı listeyi alıyor. Tipik bir foldr prosedürü şu şekilde;


(foldr (lambda (x y) (* x y)) 1 (list 2 3 4 5))

Foldr, listenin sağından başlayarak işlem yapıyor ve akümülatif çalışıyor. Buradaki mantık şu. Listeyi işlerken, fold’a verdiğimiz fonksiyonun ilk parametresi, yani buradaki “x”, her zaman listenin elemanları, “y” ise bir önceki fonksiyon çağrısından dönen sonuç. Listeyi işlemeye başlarken, fonksiyonun ilk çağrılışında, daha önce bir fonksiyon çağrısı olmadığı ve sonuç dönmediği için, “y” parametresi, fold’a verdiğimiz ikinci parametre oluyor. Yani fold başlarken, “x” 5, “y” 1 değerini alıyor ve fonksiyona giriyor. Bu fonksiyon da her iki değeri çağırıp “5” sonucunu döndürüyor. Şimdi sıra listenin ikinci elemanında. “x” parametresi 4 değerini alıyor, bir önceki çağrıdan gelen 5 sonucu da “y” değeri oluyor. İkisi çarpılıyor ve 20 sonucu çıkıyor. Sıra üçüncü elemanda. “x” 3 değerini alıyor, “y” 20 değerini alıyor ve çarpılarak sonuç 60 çıkıyor. Ve sıra geldi son elemana. Son “x” 2 değerini alırken “y” 60 değerini alıyor ve foldr fonksiyonumuz 120 değerini döndürüyor.

Basit olarak lambda, map, filter ve fold bu işlere yarıyor. Geliştirip daha farklı şeyler yapmak pratikle kazanılabilecek bir şey. Kullanım alanında sınır mevcut değil. Örnek olarak, map içerisinde fold kullanıp, çıkan sonucu filtreleyebilir ve oradan dönen liste üzerinde de işlem yapabiliriz. Bu noktada “sky is the limit” :)

Soru

Elimizde içerisinde sayı listesi barındıran bir liste olsun. Örneğin ((1 2) (3) (4 5)). Tasarlayacağımız fonksiyon da bu listeyi alıp, kartezyen çarpımlarını yine sayı listesi barındıran bir liste halinde döndürsün. Yani fonksiyonumuza ((1 2) (3) (4 5)) verdiğimizde bize ((1 3 4) (1 3 5) (2 3 4) (2 3 5)) döndürmeli.

Lakin burada bazı kısıtlamalar var. Tasarlayacağımız fonksiyon sadece map, filter, fold kullanabilir ve fonksiyonun gövdesinde “if, else” gibi ifadeler kullanmamamız gerekiyor. Sadece, high-order fonksiyonlara verdiğimiz fonksiyonlar içerisinde (lambda) “if, else” kullanabiliriz. Mümkünse google’da benzer sorular için aramayın, üzerinde düşünmek gerçekten güzel bir beyin jimnastiği oluyor.

Bunu istediğiniz programlama dilinde çözebilirsiniz. Ben Racket’da yorumları silersek normalde 12 satır, biraz sıkıştırırsak 8 satırda çözdüm ve high-order fonksiyonlar konusunda çok pratiğim olmadığı için yaklaşık olarak 2 saat vaktimi aldı. Sonuçta gayet iyi bir pratik oldu tabi. Çözdüğünüz zaman yorum olarak girmenizi gerçekten isterim. Yaklaşım ve düşünce farklarını görmek ve bunun üzerinde tartışmak yararlı olacaktır.

Her listeden bir eleman, ve küçük parçalara ayırın da ipucunuz olsun :)

Bilgisayar Bilimleri

Özgür Yazılım ile ilgili birçok etkinliğe ev sahipliği yapmış, Turing günlerini düzenleyen, aktif olarak Özgür Yazılım kullanan ve Türkiye’nin ilk Bilgisayar Bilimleri bölümü olan Bilgi Üniversitesi Bilgisayar Bilimleri bölümü kapanma tehlikesi ile karşı karşıya.

Umuyoruz ki sizlerin de desteği ile bu gidişe bir dur denecek. Daha ayrıntılı bilgi için şu adresten yararlanabilirsiniz.

SID Remix

Commodore64’e sahip ol(a)madım ancak o günlerdeki ortama büyük bir hayranlık duyuyorum. SID gibi sınırlı bir çip ile üretilen müzikler gerçekten harika ve şaşırtıcı. Çocukluğumda adını dahi hatırlayamadığım bir konsolda mario, tetris vs. oynamışlığım ve biraz da olsa o tadı alabilmişliğim var ama tabi ki bazı şeylerin yerini asla tutmayacak.

commodore-ready.gif (389×275)

7dx 2010’a katılmamla bu ortamı yaşama fırsatı buldum ve en çok keyif aldığım şey SID müziklerinin sürekli çalması idi. Öyle ki, artık akıllara kazınmış oyun müziklerinin yeniden yapılmış halleri de mevcuttu. Oradaki insanlarla biraz sohbet ettikten sonra hala aktif olarak bu tür müziklerin yapıldığını ve bir topluluk sitesinde paylaşıldığını öğrendim.

Birden fazla remix sitesi olmasına rağmen en rahat kullanılabilir ve geniş olan RKO var. (http://remix.kwed.org) Parçaları beğeni sırasına göre listeleyebiliyorsunuz ve ücretsiz olarak indirebiliyorsunuz. Yüzlerce remix var ve ben henüz ilk sayfayı dinleyebildim. En az 2 hafta kadar kafamı meşgul edecek gibi görünüyor :)

Aşağıda şu ana kadar dinlediğim ve beğendiğim parçalar mevcut. Siz de onlarla başlamayı deneyebilir ve sonrasında RKO’yu kullanıop keşfetmeyi deneyebilirsiniz. İyi dinlemeler.

Machinae Supremacy – The Great Gianna Sisters
m00g – Tristess
X-formZ – To Be On Top
Mordi – Sweet (feat Gibs)
o2 – Comic Bakery
SIDrip Alliance – From First To Last

2. ACM İstanbul Buluşması

ACM, Dünya çapında hesaplama ve bilgisayar alanında çalışan eğitimci, araştırmacı ve profesyonellerin oluşturduğu en köklü topluluklardan biridir. Amaçları arasında alanın sorunlarına çözümler sunmak ve üyeler arası iletişimi desteklemek bulunur.

ACM Chapter‘ları çeşitli yerel etkinlikler ve buluşma imkanları sunarak üyelerinin ve hesaplama alanında çalışan tüm topluluğun gelişimi için çalışır. (http://acm-turkey.org/)

İlki 3 Kasım 2010’da yapılmış olan ACM İstanbul buluşmaların ikincisi 5 Ocak 2011 tarihinde 17-18 saatleri arasında İstanbul Bilgi Üniversitesi, Dolapdere Kampüsü, Mahkeme Salonunda gerçekleşecek. Bu buluşmanın başlığı RobinViz- Güvenilirlik Temelli Biyoenformatik Ağ Görselleştirimi. Konuşmanın dili Türkçe olmakla birlikte eğer herhangi bir ön kayıt zorunluluğu mevcut değil.

İlk toplantıyı kaçırmış olmanız büyük bir olasılık ancak üzülmenize gerek yok, Bilgi VideoCS sayfasından konuşmanın tamamını izleyebilirsiniz.

Şifreli E-posta Gönderirken

Eminim ki birçoğumuz gerektiğinde, kişisel bilgilerinin güvenliği için e-postalarını şifreliyor ve bu yolla tamamiyle güvenli olduğunu düşünüyor. Açık anahtar ile şifreleme yaparken kendimizi güvende hissedebiliriz ancak bu noktada benim son zamanlarda dikkatimi çeken bir durumu paylaşmak ihtiyacı hissettim.

Her ne kadar e-postaların tamamının şifrelendiğini düşünsek de, e-posta başlıkları (header) sunucuya açık bir şekilde iletilmek zorunda. Durum böyle olunca, e-postaların başlıkları da açık bir şekilde gidiyor ve şifrelenmiyor. Eğer denemek isterseniz kendinize şifreli bir e-posta atın ve kullandığınız e-posta istemcisinin “başlıkları göster” özelliğinden faydalanarak size mesajın tam olarak nasıl iletildiğini görün. Genellikle “başlıkları göster” özelliği, e-postanın okunduğu ekranda “h” tuşuna basılarak aktif edilebiliyor. Öncelikli olarak bunu deneyebilirsiniz, eğer işe yaramıyorsa bir fikrim yok maalesef.

Bir dahaki sefere şifreli e-postaların başlığında önemli bir bilgi bulundurmamaya dikkat ediniz. Bilmeyen insanları bilgilendiriniz. Belki bu ileride bir gün hayatınızı kurtarır, kim bilir?

Özgür Yazılım ve Linux Günleri 2011

Özgür Yazılım ve Linux Günleri yine İstanbul Bilgi Üniversitesi, Dolapdere Kampüsü’nde yapılacak. Etkinlik tarihi 1 nisan 2011 Cuma ve 2 Nisan 2011 Cumartesi olarak belirlenmiş durumda.

Takvimlerinizi şimdiden ayarlayın ve kaçırmayın derim! Özgür yazılım ile ilgilenen birçok insanın yanısıra Türkiye’de bilgisayar bilimleri konusunda kaliteli eğitim veren sayılı insanlarla sohbet edebilir ve fikir alışverişi yapabilirsiniz. Semineler ve etkinlikler de cabası.

2011’de görüşmek üzere.

Hamsi

NIST tarafından 2008 yılında başlatılan ve 2012 yılında sha-3 olarak sunulacak şifreleme algoritma yarışması için finalistler birkaç gün öncesinde belli oldu. Finalistler arasında BLAKE, Grøstl, JH, Keccak, ve Skein mevcut.

Sunulan çalışmalar arasında 2. tura kadar gelmiş ancak finale kalamamış bir çalışma var ki kendisi dikkatimi çekti. Tamamen rastlantısal olarak karşılaşmamla ile birlikte hakkında pek fazla haber/bilgi olmaması dikkatimi çekmedi değil. Çalışmanın adı Hamsi, Özgül Küçük tarafından geliştirilmiş. Web sayfasında yazdığına göre Grindahl and Serpent algoritmalarını kullanmakla birlikte o alandaki yeni fikirleri de içerisinde barındırıyor. Kriptoloji konusunda derin bir bilgi birikimine sahip olmadığım için konu hakkında kapsamlı bir yazı yazamayacağım ancak eğer ilginizi çekiyorsa, bahsedilen algoritmaların analizleri ve tasarımları birkaç google araması ile ulaşılabilir.

Uluslararası bir  yarışmada böyle bir başarının elde edilebileceğini ve bu tür şeylerin yapılabileceğini görmek güzel, aynı zamanda takdir edilesi. Umuyorum ki ileride bu alanda çok daha iyi konuma gelinecektir.

Twitter Hatası ve Türkiye’deki Yayıncılar Üzerine

logo.png (224×55)

Türkiyede yayıncılık gerçekten içler acısı bir halde. Etrafta bulunan teknoloji siteleri kaynak göstermeden habersiz, habercilik etiği nedir bilmeyen insanlardan oluşuyor.

Duymadıysanız, Twitter’da çok basit bir şekilde kullanılabilen bir açık ortaya çıktı. Web üzerinden “accept <username>” yazdığınızda “username” kişisi sizi otomatik olarak takip etmiş oluyor (idi) isteği dışında..

Bu açığı bulan ve paylaşan kişi Bora Kırca ‘dır. İncisözlük’teki şu girdisi ile paylaşmıştır. Girdinin yazıldığı saate bakarsanız 16:28’i görürsünüz. Aklınızda bulunsun bu saat, twitter ile ilgili haberi başka web sayfalarında gördüğünüz zaman saatine dikkat ederek ne kadar doğru olduğunu görebilirsiniz.

Haberi ilk anda ShiftDelete.Net kaynak göstermeden, sanki kendileri bulmuşcasına yayınladı. Haberi yayınlayan kişinin gerçekten etik anlayışını çok merak ediyorum. Orijinal içerik 16:28’de yayınlandı, 17:00’da yaptığınız bu haber için nasıl “İlk kez SDN’de” diyebiliyorsunuz? Gerçekten habercilik anlayışınız ve sunduğunuz magazinsel içerik içler acısı bir halde. Habercilik etiğini ayaklar altına alarak, insanlara magazinsel haber pompalamayı ve bundan kazanç sağlamayı çok iyi biliyorsunuz. Sağolun SDN takımı, iyi ki varsınız! Eminim ki böyle devam edeceksiniz. Gerçekten ülkenin sizin gibi insanlara ihtiyacı var.

Diğer bir içler acısı durum ise Webrazzi. SDN kadar olmasa da, haberlerinde sonradan kaynak gösterdiler. Ancak şu soru akla geliyor ki, sonradan kaynak gösterilecekse, neden haberi yazarken bu aklınıza gelmedi? Birkaç link eklemek ve 1 cümle yazı yazmak gerçekten zor değil. Şu sayfada Webrazzi’nin yayınladığı ingilizce içerik mevcut. Bu içerik ilk olarak kaynaksız yayınlandı ve Avrupa’nın büyük teknoloji sitelerinden bir tanesi olan TechCrunch ‘da yer aldı. TechCrunch makalesine bakarsanız açığı bulan kişi hakkında herhangi bir bilgi bulamazsınız. Sanki her şeyi Webrazzi bulmuş ve yayınlıyor gibi bir izlenim mevcut. İngilizce yayında da düzeltmiş olsalar da, zaten TechCrunch’da ana sayfa haberi olarak yeterince “profit” kazanıldı. Sonradan “eea, biz düzelttik ama” demek çok da mantıklı görünmüyor bana.. Yine de sonradan düzelttikleri için kendilerine teşekkür etmek gerekiyor.

Neyse ki Avrupada’ki yayıncıların bir etik anlayışı var ki, CNET Incisozluk’ten bahsetmeyi ihmal etmemiş. Haber Slashdot ‘a da düşmüş durumda. Yarın yabancı kaynaklı ana haber bültenlerinde “Türkler Twitter’ı hackledi” şeklinde haberler göreceğizdir. Şu günlerde TheRegister, NYTimes, BBC gibi sayfalara gazetelerin internet sayfalarına göz atmayı unutmayın.

Bu arada dünyanın en aptal hatası anketi yapılırsa, bana haber verebilirseniz sevinirim. Oyumu bundan yana kullanacağımdır.