Fonksiyonel Programlama

Bölüm 15
Fonksiyonel
Programlama Dilleri
ISBN 0-321-49362-1
15. Bölüm konuları
•
•
•
•
•
•
•
•
Giriş
Matematiksel fonksiyonlar
Fonksiyonel programlama dillerinin temelleri
İlk fonksiyonel programlama dili LISP
Scheme
Haskell
Fonksiyonel dillerin uygulama alanları
Fonksiyonel ve komut dillerinin karşılaştırması
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-2
Giriş
• Komutlu diller direkt olarak von Neumann
mimarisi ne dayalı
– Birinci öncelik verimlilik, yazılım geliştirmeye
uygunluk değil
• Fonksiyonel dillerin tasarımı matematiksel
fonksiyonlara dayalı
– Sağlam kuramsal temel. Kullanıcıya yakın.
Üzerinde çalışacağı makine ile uyumunu önemli
değil.
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-3
Matematiksel fonksiyonlar
• Matematiksel fonksiyon: bir kümeden başka
bir kümeye eşleme
• lambda ifadesi: fonksiyonun
parametrelerini belirtir.
cube = (x).x * x * x
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-4
Lambda ifadeleri
• Lambda ifadeleri isimsiz fonksiyonları
belirtir
• Lambda ifadelerinin parametrelere
uygulanışı: parametreler fonksiyondan
sonra yazılır.
ör: ((x). x * x * x)(2)
(cevap: 8)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-5
Yüksek-sıralı fonksiyon
• Yüksek-sıralı (higher-order) fonksiyon,
başka bir fonksiyonu parametre olarak alır
ve/veya netice olarak verir
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-6
Fonksiyon bileşimi (composition)
• İki fonksiyonu parametre olarak alıp, birinci
fonksiyonu, ikinci fonksiyonun neticesine
uygulayan tek bir fonksiyon veren yüksek
sıralı bir fonksiyon.
Gösterim: h  f ° g
h (x)  f ( g ( x))
f (x)  x + 2 ve g (x)  3 * x ise
h  f ° g = (3 * x)+ 2
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-7
Hepsine-uygula
• Bir fonksiyon ve bir listeyi parametre olarak
alıp, fonksiyonu listenin her elemanına
uygulayan yüksek sıralı fonksiyon.
Gösterim: 
h (x)  x * x ise
( h, (2, 3, 4))bize (4,9,16)verir
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-8
Fonksiyonel programlama dillerinin
temelleri
• Amaç: mümkün olduğunca matematik
fonksiyonlarını taklit etmek
• Hesaplama yöntemi: Fonksiyon ugulama
• Değişkenler tek atamalık (bir tür sabit)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-9
Atıfsal saydamlık (referential
transparency)
• Saf bir fonksiyonel programlama dilinde, bir
fonksiyonun parametrelere uygulanması
her zaman ayni neticeyi verir (çağrılmanın
nerde olduğunun önemi yok)
• Yerel olmayan tanımlanmışlara
erişilmediğinde geçerli
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-10
LISP veri tipleri ve yapıları
• Veri tipleri: önceleri sadece atomlar ve
listeler
• Liste şekli: parantez içinde alt listeler ve
atomlar
ör: (A B (C D) E)
• LISP listeleri, hafızada tekli bağlamalı
listeler şeklinde saklanır.
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-11
LISP tercümesi
• '(A B C) A, B ve C atomlarından oluşan listedir
• (A B C) B ve C parametrelerine uygulanan A
fonksiyonudur
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-12
Scheme
• 1970’lerde gerçeklenmiş, benzerlerine göre
daha “temiz”, modern ve basit LISP lehçesi
• Statik etki alanı kullanır
• Fonksiyonlar birinci sınıf varlık
– İfadelerin değeri ve listelerin elemanı olabilirler
– Değişkenlere atanabilir, parametre olarak
geçilebilirler
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-13
Hesaplama
• Parametreler hesaplanır (sıra belirsiz)
• Parametrelerin değerleri fonskiyon
gövdesinde paremetrelerin yerlerine
konur.
• Gövdedeki son ifadenin değeri
fonksiyonun değeridir
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-14
Basit fonksiyonlar
•
Aritmetik: +, -, *, /, ABS, SQRT,
REMAINDER, MIN, MAX
ör: (+ 5 2) bize 7 verir
•
QUOTE – tek parametre alır, parametreyi
hesaplamadan verir
–
Listeleri fonksiyon çağırması olarak
değerlendirmemek için kullanılır
–
QUOTE tek tırnak olarak da yazılabilir.
'(A B) ile (QUOTE (A B)) ayni şeyi ifade eder
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-15
Fonksiyon tanımı: LAMBDA
• Lambda ifadeleri (isimsiz fonksiyonlar)
– Şeklini  notasyonundan alır
ör: (LAMBDA (x) (* x x))
x bağlı değişken olarak anılır (bound
variable)
• Lambda ifadeleri uygulanabilirler
ör: ((LAMBDA (x) (* x x)) 7)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-16
Özel fonksiyon: DEFINE
•
•
Foksiyon tanımlamaya yarayan ve sembollere
değer bağlamaya yarayan özel şekil
İki türü var:
1. Sembolü değere bağlamak için
ör: (DEFINE pi 3.141593)
Kullanım örneği: (DEFINE two_pi (* 2 pi))
2. İsimleri lambda ifadelerine bağlamak için
ör: (DEFINE (square x) (* x x))
şuna eşdeğer:
(DEFINE square (lambda (x) (* x x)))
Kullanım örneği: (square 5)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
-
1-17
Özel fonksiyon: DEFINE…
• DEFINE için hesplama süreci diğer
fonksiyonlara göre farklı. İlk parametre hiç
hesplanmaz. Ikinci parametre hesaplanır ve
birinciye bağlanır.
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-18
Çıktı (output) fonksiyonları
• (DISPLAY expression)
• (NEWLINE)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-19
Sayısal yüklem (predicate) fonksiyonları
• #T doğru, #F yanlış demek.
• =, <>, >, <, >=, <=
• EVEN?, ODD?, ZERO?, NEGATIVE?
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-20
Kontrol akışı: IF
• Seçim
(IF predicate then_exp else_exp)
ör:
(IF (<> count 0)
(/ sum count)
0)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-21
Kontrol akışı: COND
• Çoklu seçim
(COND
(predicate_1
(predicate_2
...
(predicate_n
(ELSE expr
expr {expr})
expr {expr})
expr {expr})
{expr}))
• Önce doğru olan ilk şart bulunur, o şartın
sağındaki son değer cevaptır.
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-22
COND örneği
(DEFINE (compare x y)
(COND
((> x y) “x is greater than y”)
((< x y) “y is greater than x”)
(ELSE “x and y are equal”)
)
)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-23
CONS ve LIST liste fonksiyonları
• CONS iki parametre alır. Birincisi bir atom
veya liste, ikincisi bir liste. Birinci
parametrenin ikinci parametrenin başına
koyulmuş halini yeni bir liste olarak verir.
ör: (CONS 'A '(B C)) bize ‘(A B C)verir.
• LIST aldığı parametrelerin listesini verir.
Ör: (LIST 'a 'b 'c) bize '(a b c)
verir.
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-24
CAR ve CDR liste fonksiyonları
• CAR liste cinsinden parametre alır, ilk
elemanını verir
• Ör: (CAR '(A B C)) bize A verir
(CAR '((A B) C D)) bize '(A B) verir
• CDR liste cinsinden parametre alır, listenin
ilk elemanı dışındakileri liste olarak verir
Ör: (CDR '(A B C)) bize '(B C)verir
(CDR '((A B) C D)) bize '(C D)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-25
EQ? yüklem fonksiyonu
• EQ? İki sembol alır, ayni iseler #T, farklı
iseler #F verir
ör: (EQ? 'A 'A) bize #T verir
(EQ? 'A 'B) bize #F verir
– Not: liste ile çağrılırsa, sonuç güvenilir değil
– EQ? sayısal atomlarla çalışmaz
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-26
LIST? ve NULL? Yüklem fonksiyonları
• LIST? tek parametre alır, eğer parametresi
liste ise #T, değilse #F verir
• NULL? tek parametre alır, eğer parametresi
boş liste ise #T, değilse #F verir
–
Ör: (NULL? ‘()) bize #T verir
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-27
Örnek Scheme fonksiyonu: member
• member bir atom ve bir liste alır. Eğer atom
listenin üyesi ise #T, değilse #F verir.
(DEFINE (member atm lis)
(COND
((NULL? lis) #F)
((EQ? atm (CAR lis)) #T)
((ELSE (member atm (CDR lis)))
))
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-28
Örnek Scheme fonksiyonu: equalsimp
• equalsimp iki tane liste alır, eşitseler #T ,
değilseler #F verir.
(DEFINE (equalsimp lis1 lis2)
(COND
((NULL? lis1) (NULL? lis2))
((NULL? lis2) #F)
((EQ? (CAR lis1) (CAR lis2))
(equalsimp(CDR lis1)(CDR lis2)))
(ELSE #F)
))
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-29
Örnek Scheme fonksiyonu: append
• append iki liste alır, birleştirilmiş olarak geri verir
(DEFINE (append lis1 lis2)
(COND
((NULL? lis1) lis2)
(ELSE (CONS (CAR lis1)
(append (CDR lis1) lis2)))
))
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-30
Scheme yapısı: LET
(LET (
(name_1 expression_1)
(name_2 expression_2)
...
(name_n expression_n))
body
)
• Tüm ifadelerin değerini bul ve değişkenlere bağla,
sonra gövdeyi (body) çağır
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-31
LET örneği
(DEFINE (quadratic_roots a b c)
(LET (
(root_part_over_2a
(/ (SQRT (- (* b b) (* 4 a c)))(* 2 a)))
(minus_b_over_2a (/ (- 0 b) (* 2 a)))
(DISPLAY (+ minus_b_over_2a root_part_over_2a))
(NEWLINE)
(DISPLAY (- minus_b_over_2a root_part_over_2a))
))
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-32
Scheme yüksek sıralı fonksiyonu
Bir fonksiyonu listenin tüm elemanlarına uygula:
(DEFINE (mapcar fun lis)
(COND
((NULL? lis) ())
(ELSE (CONS (fun (CAR lis))
(mapcar fun (CDR lis))))
))
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-33
Kod üreten fonksiyonlar
• Fonksiyon önce kod üretir, sonra kodun
değerini bulur
• EVAL foksiyonu sayesinde
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-34
Sayılardan oluşan listeyi topla
((DEFINE (adder lis)
(COND
((NULL? lis) 0)
(ELSE (EVAL (CONS '+ lis)))
))
• Önce liste başına + operatorünü koy, sonra bu
yeni listeyi EVAL kullarak çalıştır (listenin değerini
bul)
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-35
Haskell
•
•
•
•
•
Statik etki alanı
Kuvvetli tipli
Tip çıkarımı
Desen eşleme (pattern matching)
Saf fonksiyonel
fact 0 = 1
fact n = n * fact (n – 1)
fib 0 = 1
fib 1 = 1
fib (n + 2) = fib (n + 1) + fib n
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-36
Başka örnekler
fact n
| n == 0 = 1
| n > 0 = n * fact(n – 1)
sub
|
|
|
n
n < 10
n > 100
otherwise
= 0
= 2
= 1
square x = x * x
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-37
Listeler
• Liste notasyonu: Elemanlar köşeli parantez içinde
ör: directions = ["north",
"south", "east", "west"]
• Uzunluk operatörü: #
ör: #directions = 4
• .. Operatorü ile aritmetik seriler
ör: [2, 4..10] = [2, 4, 6, 8, 10]
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-38
Listeler...
• Liste birleştirme operatörü: ++
ör: [1, 3] ++ [5, 7] = [1, 3, 5, 7]
• CONS, CAR, CDR : operatorü ile
ör: 1:[3, 5, 7]=[1, 3, 5, 7]
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-39
Factoriyel yeniden
product [] = 1
product (a:x) = a * product x
fact n = product [1..n]
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-40
Liste kapsamlama (comprehension)
• Küme notasyonu
• İlk 20 pozitif tamsayının karesi:
[n * n | n ← [1..20]]
• Bir tamsayının tüm çarpanları:
factors n = [i | i ← [1..(n div 2)],
(n mod i) == 0]
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-41
Quicksort
sort [] = []
sort (a:x) =
sort [b | b ← x; b <= a] ++
[a] ++
sort [b | b ← x; b > a]
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-42
Tembel hesaplama (lazy evaluation)
• Bir dil eğer tüm fonksiyon parametrelerinin tamamen
hesplanmasını gerektiriyorsa, bu dile sıkı (strict) denir. Aksi
halde dile gevşek (nonstrict) denir. Gevşek diller daha
verimlidirler ve sonsuz listelere olanak tanırlar.
• Tembel hesaplama: Sadece ihtiyacın olan ifadelerin değerini
bul.
• Pozitif sayılar
positives = [0..]
• 16 tam karemidir?
member b [] = False
member b(a:x) = (a == b)||member b x
squares = [n * n | n ← [0..]]
member 16 squares
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-43
Member yeniden
• member eğer aradığımız eleman listedeyse çalışır.
Aksi hade sonsuza kadar gider. Aşağıdaki
fonksiyonun öyle bir sorunu yok.
member2 n (m:x)
| m < n = member2 n x
| m == n = True
| otherwise = False
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-44
Fonksiyonel dillerin uygulama alanları
• LISP, Haskell vs. yapay zekada kullanılır
–
–
–
–
Biigi temsiliyeti (knowledge representation)
Makine öğrenmesi (machine learning)
Doğal dil işleme (natural language processing)
Konuşma ve görme modellemesi
• Scheme bazı üniversitelerde
programlamaya giriş dersi olarak kullanılır
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-45
Fonksiyonel ve komut dillerinin
karşılaştırması
• Komut dilleri:
–
–
–
–
Verimli çalışma
Karmaşık semantik
Karmaşık sentaks
Paralellik programcının sorumluluğunda
• Fonksiyonel diller:
–
–
–
–
Verimsiz çalışma
Basit semantik
Basit sentaks
Programlar otomatik olarak paralel hale
getirilebilir
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-46
Özet
• Fonksiyonel diller, değişkenler, atamalar ve döngüler gibi
komut dillerine ait yapılar yerine, fonksiyon uygulaması, şartlı
ifadeler, özyineleme ve yüksek seviyeli fonksiyonlar
kullanırlar
• LISP önceleri saf bir fonksiyonel dil olarak başladı ama
sonraları komut dilleri yapıları dahil edildi
• Scheme sadece statik etki alanı kullanan bir LISP lehçesidir
• Haskell sonsuz listeleri ve küme kapsamlarını (list
comprehension) destekleyen tembel bir fonksiyonel dildir
• Saf fonksiyonel dillerin komutlu dillere göre avantajları vardır
ama komutlu dillere göre varolan bilgisayar mimarileri
üzerinde daha yavaş çalıştıklarından çok yaygın kullanıma
ulaşmadılar
Tercüme edip geliştiren: Doç. Dr. Zeki Bayram, DAÜ
1-47