Scala’da Döngü İfadeleri

Herkese merhaba!

Bir önceki yazımda programlamanın en temel konularından olan koşul ifadelerinden bahsetmiştim. Bu yazımda da ikinci bir temel kavram olan döngülerden ve bunların Scala’daki işleyişlerinden bahsedeceğim. Scala’da while ve for döngüleri olmak üzere 2 çeşit döngü var.

Haydi başlayalım!

while Döngüsü

Bu döngüler while özel kelimesi, sonrasında bir koşul ve sonrasında bu koşul sağlandığı sürece tekrar tekrar çalıştırılacak olan ifade(ler)den oluşan yapılardır. Yapısı Java’daki ile aynıdır. Örneklere bakalım.


// Java
int i = 1;
while (i <= 10) {
System.out.println(i + "!");
i++;
}
System.out.println("Önüm, arkam, sağım, solum, sobe!");
// Scala
var i = 1
while (i <= 10) {
println(i + "!")
i += 1
}
println("Önüm, arkam, sağım, solum, sobe!")
// Romantik Scala geliştiricisi
while (true) {
println("Seni seviyorum!")
}

Yukarıdaki örnekte saklambaç oyununda ebe olan bir arkadaşın kodlarını görüyorsunuz. 🙂 Gördüğünüz gibi Scala’daki while döngülerinin Java’dakinden pek bir farkı yok. Bu örnekte koşulun zaman içinde değişmesi gerektiği için var kullandık. Java’daki i++” ifadesi yerine Scala’da i += 1″ ifadesini kullandığımızı görüyorsunuz. Scala’da ++ ve  işlemleri yok. Çünkü Scala fonksiyonel programlamayı öne çıkarıyor ve bir şeylerin değerini değiştirmek fonksiyonel programlama felsefesine aykırı. Benzer şekilde, Java’da bir döngüden break özel kelimesiyle çıkabiliyorken Scala’da bunu da yapamıyorsunuz. Uygulamanın akışını bu şekilde değiştirmek de fonksiyonel programlamaya ve Scala’ya göre hoş bir davranış değil. 🙂 Son olarak da bir sonsuz döngü görüyorsunuz. Java ile aralarında bir fark yok. Yalnız kullanırken dikkatli olmakta fayda var çünkü az önce belirttiğim gibi break kullanamıyorsunuz. Bunu çözmenin birkaç yolu var ama bence en güzeli while döngüsü kullanmaktan kaçınmak. Eğer gerçekten while kullanmanız ve döngüyü bir noktada kesmeniz gerekiyorsa bunu daha sonra detaylıca anlatabilirim.

for Döngüsü

Gelelim for döngüsüne. Scala’da for döngüsü oldukça gelişmiş özelliklere sahip. Hatta aslında sadece bir döngü değil. Scala’da basit bir döngüden daha fazlasını yapan for’lar için “for döngüsü” yerine “for comprehension yani “for anlaması/kavraması” da deniliyor. Şimdi en temel halinden daha gelişmiş özelliklerine doğru örneklere bakalım.


// Java
for (int i = 1; i <= 10; i++) {
System.out.println(i + "!");
}
System.out.println("Önüm, arkam, sağım, solum, sobe!");
// Scala
for (i <- 1 to 5) println(i + "!")
for (j <- 6 until 11) {
println(j + "!")
}
println("Önüm, arkam, sağım, solum, sobe!")

Yukarıdaki örnekte Java kısmında çok basit bir for döngüsü görüyorsunuz. Bir değişken tanımlayıp değerini 0 yapıyor, belirli bir koşul tanımlıyor ve döngünün her aşamasında bu değişkenin değerini artırıyor. Şimdi aynı döngünün/döngülerin Scala’daki karşılığına bakalım.

8. ve 9. satırlardaki döngüler aslında fonksiyonel döngüler. Bir değişken tanımlayıp bunun değerini değiştirerek çalışmıyorlar. to ve until kelimelerine dikkat edin. to kelimesi ile 1’den 5’e kadar sayı aralığı üretiyoruz. Aslında buradaki to, 1 değeri üzerinde çağrılan bir metod. Bu tür metod çağrılarına ileride değineceğim. Böylece “1 to 5” ifadesi scala.collection.immutable.Range.Inclusive türünde, içinde 1’den 5’e kadar (5 dahil) sayılar olan bir Range, yani aralık, oluşturuyor. Daha sonra da for döngüsü, bu Range üzerindeki her eleman için, elemanlara i ismiyle erişecek şekilde çalışıyor. Burada üzerinde döndüğümüz Range içinde Int türünde sayılar olduğundan, i‘nin türü, tür çıkarımı sonucunda Int olarak belirleniyor. Döngünün gövdesi tek bir ifadeden oluşacaksa 8. satırda görebileceğiniz gibi süslü parantezleri yazmayabiliyoruz ama bu şekilde yazım pek tavsiye edilmiyor. Süslü parantezleri hep kullanmakta fayda var.

9. satırda da to yerine until kullanımına örnek olması için yazdığım başka bir döngü var. 10’a kadar saymaya kaldığımız yerden devam ediyoruz. Bu sefer (önceki döngüde 5’i dahil ettiğimiz için) 6 üzerinde until‘i çağırarak 6’dan 11’e kadar (11 hariç), scala.collection.immutable.Range türünde bir Range üretiyoruz. Bu seferki döngümüzde her elemana j ismiyle ulaşacağız.

Buradaki Scala for döngüleri aslında Java’daki gelişmiş for döngüleri gibi bir koleksiyon üzerindeki her bir elemanı ziyaret ederek çalışıyor ve her elemana ulaşacağımız bir değişken adı tanımlıyoruz. Bunu yaparken kullandığımız <- (küçüktür ve kısa çizgi) işaretine dikkat edin. 🙂

Yukarıdaki örnek basit bir sayma işlemine karşılık geliyordu. Java’da bunun için de koşullar yazıyor olsak da Scala’da to ve until ifadeleriyle saymayı kolayca yapabildiğimizi gördük. Şimdi biraz daha ilerleyelim ve döngümüze farklı koşullar ekleyelim.


// Java
for (int i = 1; i <= 20; i += 2) {
for (j = i; j <= i * 2 && j < 14; j++) {
System.out.print("[" + i + ", " + j + "] ");
}
}
// Scala
for {
i <- 1 to 20 by 2
j <- i to (i * 2) if j < 14
} {
print("[" + i + ", " + j + "] ")
}

Burada daha karmaşık koşulları ve ilerleme ifadeleri olan, değerleri birbiriyle bağlantılı olan iç içe 2 döngü yazdık. Şimdi Scala’daki halini incelemeye başlayalım.

Scala birden fazla boyutta for döngüleri yazacağımız zaman for kelimesinden sonraki parantezlerin yerini süslü parantezler alıyor. Her bir döngüyü ayrı bir satıra gelecek şekilde yazıyoruz.

Buradaki örnekte 10. satırda 1 to 20 ifadesini biliyoruz ama bu sefer bir ekleme var. “1 to 20 by 2” ifadesi 1’den 20’ye kadar Range oluşturuyor ama ikişer artırarak oluşturuyor. Yani sonuçta (1, 3, 5, …, 17, 19) şeklinde bir Range oluşuyor. Bunun Java örneğindeki i += 2 ifadesine karşılık geldiğini görebilirsiniz.

11. satırda da ilk döngümüzün içindeki ikinci döngümüzü tanımlıyoruz. Burada j‘ler, i‘nin o anki değerinden, (i * 2)‘ye kadar ilerleyecek ama sonrasında gelen j < 14 koşulunu sağladığı sürece. Burada gördüğünüz gibi, for döngüsünde döngüyü sadece belirli koşullarda ilerleyecek şekilde yazabiliyoruz. Bunun için de bir koşul yazmak için en mantıklı olan şeyi, yani if kelimesini kullanıyoruz. if’ten sonra parantez kullanma zorunluluğu yok. (match … case ifadelerindeki koşulları hatırlayın.) Bu döngü çalıştığında aşağıdaki sonucu alacağız.

Screenshot 2015-12-15 22.44.16

Gördüğünüz gibi i değerleri ikişer artıyor. j değerleri de 14’ten her zaman küçük. Bu koşul bozulduğu anda döngünün durduğunu görüyorsunuz. Yukarıda break olmamasından ve while kullanmaktan mümkün olduğunca kaçınmak gerektiğinden bahsetmiştim. Gördüğünüz gibi sorununuzu buna benzer for döngüleri ile büyük ihtimalle çözebilirsiniz. 🙂

Şimdi son bir örnekle Java’daki gelişmiş for döngülerine benzer bir döngü yazalım. Ama sırf yapabildiğimiz için bu döngü bir değer de üretsin. (if bloğundan değer üretmeyi hatırlayın.)


// Java
String[] isimler = new String[] {"Ali", "Veli", "Ahmet", "Hüseyin", "Akif"};
String[] secilenIsimler = new String[isimler.length];
int i = 0;
for (String isim : isimler) {
if (isim.startsWith("A") && isim.length > 3) {
System.out.println("Seçilen isim: " + isim);
secilenİsimler[i] = isim;
i++;
}
}
// Scala
val isimler: Array[String] = Array("Ali", "Veli", "Ahmet", "Hüseyin", "Akif")
val secilenIsimler: Array[String] = for (isim <- isimler if isim.startsWith("A") && isim.length > 3) yield {
println("Seçilen isim: " + isim)
isim
}

Buradaki örneğimiz tanımlanmış bazı isimlerden A harfi ile başlayan ve 3 karakterden uzun olan isimleri buluyor. Java’daki örnekte, 6. satırda gördüğünüz gibi bir koleksiyon üzerinde gelişmiş for döngüsü kullanıyoruz. Ayrı bir Array’de de sonucu saklıyoruz. Şimdi Scala’daki örneğe bakalım.

Scala’da bir koleksiyon üzerinde for döngüsü yapmak yukarıdaki örneklerle aynı. Bir değişken ismi veriyoruz, <- işaretini kullanıyoruz ve koleksiyonu yazıyoruz. 15. satırda bir Array tanımlanışı görüyorsunuz. Koleksiyonları anlatacağım yazımda daha detaylı bahsedeceğim için şu an bunun detaylarına girmiyorum. Şimdi 17. satırda başlayan döngüye bakalım.

17. satır bir val tanımlamasıyla başlıyor. Değer olarak da doğrudan döngünün kendisini yazdık. Buradaki döngümüz (tıpkı daha önce if bloklarında anlattığım gibi) çalıştırılıp bir değer üretiyor. Bir for döngüsünün değer üretmesi için gövdesi yerine yield kelimesini kullanıyoruz. Burada isimler isimli Array’imiz üzerinde isim diye adlandırdığımız bir değişkenle dönüyoruz. Koşullarımızı da doğrudan döngüye ekleyebildiğimizi görüyorsunuz. Bu sayede eğer o anki eleman koşula uymuyorsa atlanacak ve üretilen değere dahil edilmeyecek. yield kelimesinden sonra gelen blokta da hangi isim olduğu yazıyoruz ve ismi geri dönüyoruz. Burada bir Array[String] üzerinde döndüğümüz için döngüde tanımladığımız isim değişkeninin türü Stringyield ifadesininden de geriye isim, yani String türünden bir değer döndürdüğümüz için döngünün tamamı Array[String] değeri üretmiş oluyor. Bu değeri de secilenIsimler val’ına atıyoruz.

for döngüleriyle ilgili başka örnekler de yazıp, deneyerek alıştırma yapmanızı tavsiye ederim. Özellikle özel koşulları olan for döngüleri ve yield ile değer üreten döngüler, tam anlamıyla hakim olduğunuzda gerçekten güçlü araçlar. 🙂

Sonuç

Bu yazımda sizlere Scala’da döngü ifadelerinden bahsetmeye çalıştım. Farklı yönlerini görebilmeniz adına Java’daki halleriyle karşılaştırmalar da yaptım. İnşallah anlaşılır olmuştur.

Görüşmek üzere. Hoşça kalın!

Scala’da Değişkenler (var), Değerler (val) ve Metodlar (def)

Merhabalar! Bundan sonraki yazılarımda daha çok ve somut örnekler ve karşılaştırmalar üzerinden giderek temel birçok kavrama değineceğim. Böylece Scala ile daha çok ve anlamlı uygulamalar geliştirmeye başlayabileceğiz. Bu yazımda en programlamadaki en temel kavramlardan biri olan değişkenlerden, Scala’da daha sık kullanılan değişmez değerlerden ve metodlardan bahsedeceğim.

Haydi başlayalım!

1. Değerler (val) ve Değişkenler (var)

Uygulama geliştirirken bir değeri veya nesneyi saklamak ve isimlendirmek için değişkenler kullanırız. Hatta bazen bu isimlendirdiğimiz şeyin bir daha değiştirilmemesini de isteyebiliriz. Scala’da bu işler için 2 özel kelime var.

1.1. Değişken (var)

Değerini sonradan değiştirebileceğiniz bir değer veya nesne oluşturmak için var özel kelimesini (İngilizce değişken anlamına gelen variable‘ın kısa hali) kullanabilirsiniz. Aşağıdaki birkaç değişik örnek yazdım.


var sayi: Int = 6
var metin = "Sayı çift mi?"
var ciftMi: Boolean = _
println("Sayı: " + sayi)
println(metin + " " + ciftMi)
ciftMi = sayi % 2 == 0
println("Tekrar bak.")
println(metin + " " + ciftMi)

İlk satırda sayi adında Int türünde, değeri 6 olan bir değişken oluşturuyoruz. Burası açık.

İkinci satırda adı metin olan, türünü belirtmediğimiz bir değişken yaratıyoruz. Böylece Scala String olduğunu çıkarım yaparak bulacak.

Üçüncü satırda ise yarattığımızda değerini belirtmediğimiz ciftMi adında Boolean türünde bir değişken oluşturuyoruz. Bir değişkeni değerini vermeden yaratmak için Java’da ve diğer dillerde sadece adını ve türünü yazmak yeterliyken, Scala’da değerinin sonradan verileceğini belirtmemiz gerekiyor. Bunu da _ (alt tire) yer tutucu (placeholder) karakteri ile sağlıyoruz. Değerini vermeden değişken yaratacağımız zaman – Scala değeri bilmeden tür çıkarımı yapamayacağı için – türü belirtmemiz gerekiyor. Değerini belirtmeden değişken yarattığımızda aslında o değişkene belirttiğimiz türe göre değişecek varsayılan bir değer atanıyor. Bu varsayılan değer sayı türleri için 0, Boolean için false, bunlar dışındaki referans türleri için de null. O yüzden 6. satırda ciftMi değişkeninin değeri olarak ekrana false yazılacak. ciftMi değişkeninin değerinin sonradan değiştirilebildiğini görüyorsunuz.

var ile ilgili bir not; eğer Scala’yı önerildiği gibi, fonksiyonel programlamaya uygun kullanmak istiyorsanız hiç var kullanmamaya çalışın. İleride değişmezlik (immutability) hakkında yazacağım yazı(lar)da bu konuya tekrar değineceğim. 🙂

1.2. Değer (val)

Değerini sonradan değiştiremeyeceğimiz bir değer veya nesne oluşturmak için val özel kelimesini (İngilizce değer anlamına gelen value‘nun kısa hali) kullanabiliriz. val ile değerler yaratmak Java’da ve başka bazı dillerde değişken tanımının önüne final özel kelimesini getirmeye eşdeğerdir. Bir kere oluşturulur, değeri sabittir, yeniden atama yapılamaz. var için olana benzer bir örnek yapalım.


val sayi: Int = 6
val metin = "Sayı çift mi?"
// Bu hata verecek.
val ciftMi: Boolean = _
// Bu da hata verecek.
sayi = 5

Burada da aynı şekilde bir Int ve String oluşturuyoruz yalnız bu sefer bu değerlere yeniden atama yaparak sakladıkları değerleri değiştiremeyeceğiz.

4. satırda gördüğünüz gibi val ile oluşturulmuş bir değerin saklayacağı değeri belirtmeden geçemiyorsunuz çünkü o val bir kere oluşturulduktan sonra değerinin değiştirilmesi engellenecek, sonradan değer ataması yapılamayacak.

7. satırdaki işlem de hata verecek çünkü daha önceden tanımlanmış bir val’ın sakladığı değerin yerine başka bir değer atamaya çalışıyoruz.

var ile ilgili yazdığım notu tamamlayayım; değişmezliği sağlayabilmek için var değil val kullanmaya çalışın. 🙂

2. Metodlar (def)

Aslında daha önceki yazılarımdaki örneklerde metodları kullanmıştık. Scala’da metodlar def özel kelimesi ile tanımlanırlar. Hemen birkaç örnek görelim.


def buBirMetod {}
def buDa = {}
def hattaBuDa: Unit = {}
def veHattaBuDa(): Unit = {}
buBirMetod
veHattaBuDa()
def sayi = 5
def sayi2() = 6
def topla(s1: Int, s2: Int) = s1 + s2
def carp(s1: Int)(s2: Int) = s1 * s2
def karistir() = {
val sonuc1 = topla(sayi, sayi2())
val sonuc2 = carp(sayi)(sayi2())
topla(sonuc1, sonuc2)
}
val toplam = topla(2, 3)
val carpim = carp(3)(5)
karistir()

Yukarıdaki örnekte birçok değişik metod tanımlaması görüyorsunuz. İlk 4 metod tanımlaması da aslında bir işlem yapmayan, Unit dönüş türüne sahip, gövdesi boş metodlar. Ama tanımlanışlarında farklılıklar var.

İlk metod hiç parametre tanımlamıyor. Şimdiye kadar gördüklerimiz aksine dönüş türü de belirtmiyor. Gövdesinin boş olduğunu görüyorsunuz, yani bir iş yapmıyor, yani aslında dönüş türünün Unit olması gerekirdi. Scala’da Unit dönüş türüne sahip metodları tanımlarken = (eşittir) işaretini ve dönüş türünü birlikte atlayabiliyoruz.

İkinci metod da aslında ilk metod ile birebir aynı. Parametre almıyor ve dönüş türü Unit. Yalnız bu sefer = kullandığımız için Scala tür çıkarımı yapıyor. Gövde boş olduğu için de (aslında Unit döndüren bir şeylerle dolu da olabilirdi) metodun dönüş türünün Unit olduğuna karar veriyor.

Üçüncü metod da ikinci metod ile aynı. Bu sefer dönüş türünü kendimiz belirttik.

Dördüncü metodda diğer üç metoddan farklı bir nokta var. Bu metod aslında diğerleri gibi parametresiz bir metod değil. Parametre alacak şekilde ama parametresi olmadan tanımlanmış. Scala’da parametresiz tanımlanmış bir metodu parantezlerle, parametre alacak bir metodu da parantezleri olmadan çağırmaya kalkarsak hata alıyoruz. 6. ve 7. satırlarda bu metodları çağırma sırasındaki farkı görüyorsunuz.

9. satırdan itibaren tanımladığımız metodlar (tür çıkarımı ile) geriye Int döndüren metodlar.

sayi ve sayi2() metodları arasında buBirMetod ve veHattaBuDa() metodlarının arasındaki ilişkinin aynısı var. Sonraki satırlarda farklı şekillerde çağırıldıklarını görüyorsunuz.

topla metodu 2 tane Int parametresi olan bir metod. Belki de buradaki en anlaşılır metod. 🙂

carp metodunda ilginç bir farklılık var. Bu metodun 2 tane parametre grubu var. Scala’da metodların birden fazla parametre grupları olabiliyor. Ayrı parantezler halinde yazılıyorlar ve metodun imzasına dahil ediliyorlar. Buradaki metod carp(Int)(Int): Int şeklinde bir imzaya sahip. Metodun nasıl çağrıldığını 21. satırda görüyorsunuz.

karistir() metodu şimdiye kadar tanımladıklarımızı kullanıp bazı hesaplamalar yapan bir metod. Bu metod da veHattaBuDa() metodu gibi parametre alacak şekilde ama parametresi olmadan tanımlanmış. Gövdesinde birden fazla ifade olacağı için süslü parantezler {} kullanılıyor. Son olarak, gövdesindeki son ifadenin değerini geri döndürüyor (tür çıkarımı da buna göre yapılıyor).

Scala’da metodlar, Java’daki gibi sadece bir class içinde değil, başka yerlerde de tanımlanabiliyor, örneğin başka bir metodun içinde. 🙂 Bunun bir örneğini görelim.


def beni {
def ben {println("Bir ben vardır bende benden içeri.")}
println("Beni bende deme bende değilim,")
ben
}
beni
// Bu hata verecek
ben

Burada ben metodunun beni metodunun içinde tanımlandığını görüyorsunuz. Scala’da bu mümkün. Bir metodun içinde tanımlanan başka bir metod, sadece tanımlandığı metodun gövdesi içinde ulaşılabilir durumdadır. Yukarıdaki örnekte 10. satırda ben metodu bulunamadığı için hata alınacak.

Metodlarla ilgili değinmek istediğim son bir konu var. Scala’da parametreleri olan metodları çağırırken, bu parametreleri isimlerini de kullanarak gönderebilirsiniz. Yapmanız gereken parametrenin değerinin önüne adını yazmak ve = (eşittir) atama işaretini koymak. Bu özelliği kullanarak parametre listesini birebir takip etmeden bile metodunuzu çağırabilirsiniz. Bunun da örneklerini görelim.


def tanit(adi: String, soyadi: String, yasi: Int, erkekMi: Boolean): Unit = {
def cinsiyet(e: Boolean): String = {
if (e) {
"Erkek"
} else {
"Kadın"
}
}
println("Adı : " + adi)
println("Soyadı : " + soyadi)
println("Yaşı : " + yasi)
println("Cinsiyeti: " + cinsiyet(erkekMi))
}
tanit("Mehmet Akif", "Tütüncü", 24, true)
tanit(adi = "Mehmet Akif", soyadi = "Tütüncü", yasi = 24, erkekMi = true)
tanit("Mehmet Akif", soyadi = "Tütüncü", 24, erkekMi = true)
tanit(soyadi = "Tütüncü", erkekMi = true, adi = "Mehmet Akif", yasi = 24)

Bu örnekte tanit adında, 4 tane parametresi olan, Unit döndüren bir metod tanımlıyoruz. Burada cinsiyet metoduyla, yukarıda bahsettiğim metod içinde başka bir metod tanımlamanın bir örneğini daha görüyorsunuz. Gönderilen erkekMi parametresinin değerine göre kişinin cinsiyetine karar verecek küçük yardımcı bir metod. Bu metodun gövdesinde karar vermeye yarayan if özel kelimesi var. Bundan sonraki yazılarımda daha detaylı bahsedeceğim. Şimdi 16. satırdan itibaren metodun farklı şekillerde çağrılışlarını inceleyelim.

16. satırda şimdiye kadar bildiğimiz yöntemle, sırayla parametreleri vererek çağırıyoruz.

17. satırda birer birer bütün parametrelerin isimlerini de vererek çağırıyoruz. Gördüğünüz gibi bu yöntem kodun okunduğunda daha kolay anlaşılmasına yardımcı oluyor. Tabi bunun için metodu tanımlarken parametrelere anlamlı isimler vermek gerekiyor.

18. satırda parametrelerin hepsine değil, sadece bazılarına isimlerini de vererek değer gönderiyoruz. Bu yine bazı durumlarda kodun anlaşılabilirliğini artırmak için güzel bir yöntem. Özellikle türü Boolean olan parametrelerin değerlerini verirken isimleriyle çağırmanızı tavsiye ederim. Burada hala parametreleri gerçek sıralarıyla çağırdığımıza dikkat edin.

19. satırda işler biraz daha değişiyor. Artık parametreleri kendi istediğimiz sırada gönderiyoruz. Tüm parametreleri tanımladığımız için ve hepsini ismiyle gönderdiğimiz için Scala metod çağrılarını bu şekilde yapmamıza bile izin veriyor.

Ekleme: Metod Parametrelerinde Varsayılan Değerler

Yazıyı yazıp yayımladıktan sonra atladığımı fark ettiğim için eklemek istediğim, metodlar yazarken sıkça kullanılan bir konu daha var. Scala’da metodların parametrelerine varsayılan değerler belirleyebilirsiniz. Böylece metodu çağırırken varsayılan değeri olan bir parametreyi yazmadan da geçebilirsiniz. Böyle durumlarda metod tanımlanırken belirtilen varsayılan değer kullanılır. Bir örnek ile görelim.


def tanit(adi: String, soyadi: String, yasi: Int, erkekMi: Boolean, sadeceAdiKullan: Boolean = false): Unit = {
def cinsiyet(e: Boolean): String = {
if (e) {
"Erkek"
} else {
"Kadın"
}
}
println("Adı : " + adi)
if (!sadeceAdiKullan) {
println("Soyadı : " + soyadi)
println("Yaşı : " + yasi)
println("Cinsiyeti: " + cinsiyet(erkekMi))
}
}
// Bunlar önceki örnekteki gibi çalışacak.
tanit("Mehmet Akif", "Tütüncü", 24, true)
tanit("Mehmet Akif", "Tütüncü", 24, erkekMi = true)
// Bunlar sadece adı yazdıracak.
tanit("Mehmet Akif", "Tütüncü", 24, true, true)
tanit("Mehmet Akif", "Tütüncü", 24, true, sadeceAdiKullan = true)
tanit("Mehmet Akif", "Tütüncü", 24, erkekMi = true, sadeceAdiKullan = true)

Bir önceki örnekteki metoda sadeceAdiKullan adında bir Boolean parametre daha ekledim. Bu parametrenin varsayılan bir değeri var, false. Ve metodun işleyişi bu parametrenin değerine göre değişiyor. 20 ve 21. satırlarda gördüğünüz gibi sadeceAdiKullan parametresini hiç dahil etmeden de metodu çağırabiliyoruz. Bu durumda bu parametrenin değeri varsayılan değer olan belirtilen değer oluyor. Ama 24, 25 ve 26. satırlardaki kullanımda sadeceAdiKullan parametresini de işin içine katıyoruz ve istediğimiz değeri belirtiyoruz.

Bu eklemeyle beraber metod parametrelerini isimleriyle kullanma konusunda bir tavsiyede bulunayım. Metodun parametrelerini gönderirken okunurluğu artırmak adına parametreleri, özellike de türü Boolean olan parametreleri, isimlerini kullanarak gönderin. Yukarıdaki örnekte 21. ve 26. satırdaki kullanımlar buna örnekler. 🙂

Sonuç

Bu yazımda programlamadaki temel kavramlardan değişken, sabit değer ve metodları ve bunların Scala’daki kullanılışlarını anlatmaya çalıştım. İnşallah anlaşılır olmuştur.

Kaynak

Yunus Emre’nin Severim Ben Seni Candan İçeri şiiri: http://www.yunusemre.gov.tr/index.php/eserleri/siirleri/siirlerin-devami/severim-ben-seni-candan-iceri

Görüşmek üzere. Hoşça kalın!

 

Neden Scala?

Merhabalar! Bu yazımda Scala’nın onu tercih sebebiniz olabilecek birkaç avantajından bahsetmek istiyorum. Merhaba Scala! yazımda ve Kim? sayfamda biraz bahsettiğim gibi Linovi’de çalışıyorum ve Scala’yı öğrenmeye/kullanmaya burada başladım. Scala ile ilgili şirketimin tercihleri ve benim kişisel görüşlerimi göz önünde bulundurarak birkaç başlık halinde anlatacağım.

Java ile Yakın İlişki

Java en yaygın programlama dillerinden bir tanesi. Java ile yapılabilecekler gerçekten oldukça fazla. Çok çeşitli ortamlarda da çalışabiliyor. Haliyle Java ile yazılmış dünya kadar kütüphane, araç ve çözüm var. Ancak eğer siz bir şekilde Java ile geliştirme yapmıyorsanız, geliştirdiğiniz dilden başka bir dilde yazılmış bir kodu kullanmak ya ek çaba gerektirecektir ya da mümkün değildir. Scala ile geliştirme yapacak olursanız böyle bir sorunla karşılaşmazsınız. Scala da tıpkı Java gibi JVM üzerinde çalışır. Scala kodunuzla birlikte Java kodu yazabilir, Scala kodunuzda Java kütüphanelerini doğrudan kullanabilir ve Java’yı çalıştırabildiğiniz bir ortamda Scala’yı da çalıştırabilirsiniz. Gördüğünüz gibi, bir nedenden dolayı Java’yı değil başka bir dili tercih etmek durumundaysanız, Scala’nın Java ile bu yakın ilişkisi sizin için avantajlı olabilir. Şirketimin Scala tercihinde de Java ile olan bu ilişki önemli bir etken. Örneğin yoğun olarak kullandığımız Amazon’un AWS (Amazon Web Services) isimli bulut (cloud) hizmetleri için hazırlanmış arayüzler ve kütüphaneler Java ile yazılmış durumda ve biz Scala kodumuzla birlikte sorunsuzca kullanabiliyoruz.

Yüksek Performanslı, Eşzamanlı İşler

Scala ile Akka teknolojilerini kullanarak eşzamanlı (concurrent), dağıtık (distributed) ve yüksek performanslı sistemler geliştirebilirsiniz. Evet, Akka teknolojilerini Java’da ve başka dillerde de kullanabiliyorsunuz ama bu teknolojileri Scala ile de sorunsuzca kullanabilmek yine bir avantaj. Hatta Scala’nın (fonksiyonel programlama gibi) farklı yetenekleriyle de birleşince bu teknolojileri Scala ile kullanmak daha kolay ve etkili olabiliyor. Linovi’de Akka’nın aktörlerini Scala ile kullanıyoruz.

Fonksiyonel Programlama

Scala birden fazla programlama paradigmasını/modelini destekleyecek şekilde geliştirilmiş. Nesne yönelimli programlama modelini tıpkı Java’daki veya başka bir nesne yönelimli programlama destekleyen dildeki gibi kullanabiliyorsunuz. Hatta bunun üzerine iyileştirmeler de yapılmış. Bunlara ek olarak Scala ile nesne yönelimli programlamadan oldukça farklı olan fonksiyonel programlama modelini de kullanabiliyorsunuz. Scala bu iki temel programlama modellerini başarılı şekilde harmanlamış. Dilin size sunduğu birçok kütüphanede ve arayüzde fonksiyonel programlama özellikleri ve tekniklerinden yararlanılmış. Hatta – daha önce bahsetmiştim – Scala birçok yerde sizi fonksiyonel programlama yapmaya teşvik ediyor. İlerleyen yazılarımda Scala ile daha çok kodlama yaptıkça bunun detaylarına ineceğim.

Kısa ve Öz Sözdizimi

Bu yazıyı okuyorsanız muhtemelen Scala dışında bir dil kullanıyorsunuzdur. Hatta o dilin Java olma ihtimali de oldukça yüksek. 🙂 Java ile geliştirme yapmışsanız bilirsiniz ki bazen basit bir iş için bile çok fazla kod yazarız. Benzer şeyleri tekrar tekrar yazarız ve yaptığımız işler büyüdükçe bu durum biraz can sıkmaya başlar. Scala geliştirilirken, bu gibi can sıkıcı durumlardan kurtulmak için birçok noktada neyin gerçekten gerekli olduğu, neyin ise aslında gereksiz olduğu ve atılabileceği üzerinde düşünülmüş. Örnek olması için; bir İnsan sınıfı tanımlayan, 10 tane rastgele yaşlara sahip insan oluşturan, bunları listeleyen ve sonra yaşlarının toplamını gösteren bir kod yazdım. Aşağıda aynı kodun birbirine denk Java ve Scala ile yazılmış hallerini görebilirsiniz.

Java


class Insan {
private int yas;
public Insan(int yas) {
this.yas = yas;
}
public int yas() {
return yas;
}
@Override public String toString() {
return "Insan(" + yas + ")";
}
}
class NedenScala {
public static void main(String[] args) {
Random rastgele = new Random();
Insan[] insanlar = new Insan[10];
for (int i = 0; i < 10; i++) {
insanlar[i] = new Insan(rastgele.nextInt(30) + 5);
}
System.out.println("İnsanlar:");
for (Insan insan : insanlar) {
System.out.println(insan);
}
System.out.println("Yaşları toplamı:");
int toplam = 0;
for (Insan insan : insanlar) {
toplam += insan.yas();
}
System.out.println(toplam);
}
}

view raw

NedenScala.java

hosted with ❤ by GitHub

Scala


case class Insan(yas: Int)
object NedenScala {
def main(args: Array[String]) {
val insanlar = for (i <- 1 to 10) yield Insan(scala.util.Random.nextInt(30) + 5)
println("İnsanlar:")
insanlar foreach println
println("Yaşları toplamı:")
println(insanlar.foldLeft(0)(_ + _.yas))
}
}

Aradaki farkı görüyorsunuz. 🙂 Kodun Scala halinde ileride detaylıca bahsedeceğim (tür çıkarımı/tahmini [type inference], sadece döngü olmayan for’lar [for comprehension], koleksiyonlar [collections], fonksiyonel programlama [functional programming], parçalı fonksiyonlar [partial functions] gibi) birçok Scala özelliğini kullandım. Her ne kadar örnek olsun diye uydurduğum bir kod olsa da Java’da, da Scala’da da geliştirme yapmış biri olarak farkın gerçekten de bu boyutlara ulaştığını söyleyebilirim. Scala’yı tercih etmemdeki kişisel nedenlerden birisi de bu Scala’nın bu öz (concise) yapısı.

Play Framework ve Web Uygulamaları

Yukarıda Akka’dan bahsederken anlattığım gibi, Scala ile web uygulamaları geliştirmek için Play Framework‘ü kullanabilirsiniz. Yine Akka gibi Play Framework de Java ile çalışabilmesine rağmen Scala ile daha kolay, keyifli ve etkili geliştirmeye olanak sağlıyor. Ayrıca Play Framework geliştiricileri önce Scala, sonra Java için geliştirme yapıyorlar diye biliyorum. Yani Play Framework kullanacaksanız Scala’nın Java’ya göre desteklenme konusunda bir avantajı var. Ayrıca Scala’daki implicit kavramı ve fonksiyonel programlama özellikleri gibi gelişmiş yapılar, web uygulamalarınızı geliştirirken size gerçekten çok yardımcı olabiliyor ve uygulamalarınızı daha etkin biçimde geliştirebiliyorsunuz. Linovi’de yüksek performanslı ve kaliteli web uygulamaları geliştirmeyi hedeflediğimiz için Play Framework’ü tercih ediyoruz. Çünkü Play Framework hafif ve iyi bir performansla çalışıyor. İlerleyen zamanlarda Scala ile Play Framework üzerine yazılar yazacağım.

Sonuç

Bu yazımda Scala ile ilgili “Neden Scala öğreneyim/kullanayım?”, “Neden Scala’ya geçeyim?” gibi sorularınıza cevaplar vermeye çalıştım. İnşallah anlattıklarım faydalı olmuştur.

Tekrar görüşmek üzere, hoşça kalın!