All posts by Soner Gönül

Codecademy “Learn C#” Online Programlama Eğitimi – [3. Kısım]

Codecademy üzerinden “Learn C#” adındaki programlama eğitiminin 3. kısmını bu Twitch yayını ile tamamladık. Bu yayında konuştuğumuz konu başlıkları şu şekilde;

➡️ C# içerisinde metod tanımlama ve çağırma

➡️ Parametreler ve argümanlar

➡️ Opsiyonel parametreler (optional parameters)

➡️ Adlandırılmış parametreler (named parameters)

➡️ “Method overloading” ve metod imzası kavramları

➡️ “return” ifadesi

➡️ “void” geri dönüş tipi

➡️ “out” parametre tipi

🔴 1. Kısım: https://www.youtube.com/watch?v=0X7bEBSxygg

🔴 2. Kısım: https://www.youtube.com/watch?v=ziJPCgzvQjE

👍 İlk ziyaretiniz mi? O zaman sizi şöyle alalım: https://bit.ly/sonergonul-youtube-subs

🔥 Codecademy: “Learn C#” online programlama kursu: https://www.codecademy.com/learn/learn-c-sharp

✅ Online Kurslar:

– Codecademy: https://www.codecademy.com/

– Khan Academy: https://www.khanacademy.org/

– MIT Open Course: https://ocw.mit.edu/courses/

– Stanford Online Course: https://online.stanford.edu/

– FreeCodeCamp: https://www.freecodecamp.org/

– Coursera: https://www.coursera.org/

Codecademy “Learn C#” Online Programlama Eğitimi – [2. Kısım]

Codecademy üzerinden “Learn C#” adındaki programlama eğitiminin 2. kısmını bu Twitch yayını ile tamamladık. Bu yayında konuştuğumuz konu başlıkları şu şekilde;

➡️ String ve Char tiplerine genel bakış

➡️ String Concatenation (+ operatörü kullanımı)

➡️ String Interpolation

➡️ String bilgileri (string.Length ve string.IndexOf)

➡️ String’in alt string’lerine ulaşma (string.Substring)

➡️ String’i büyük/küçük karakterlere çevirme (string.ToUpper ve string.ToLower)

➡️ Boolean veri tipi

➡️ Karşılaştırma operatörleri

➡️ Truth table (https://en.wikipedia.org/wiki/Truth_table)

➡️ Mantık operatörleri (&&, ||, !)

➡️ Koşul ifadeleri (if, if..else, else if, switch)

➡️ Ternary Operatörü (condition ? true : false)

🔴 Codecademy – “Learn C#” Online Programlama Eğitimi – 1. Kısım: https://www.youtube.com/watch?v=0X7bEBSxygg

🔴 İlk ziyaretiniz mi? O zaman sizi şöyle alalım: https://bit.ly/sonergonul-youtube-subs

🔴 Codecademy: “Learn C#” online programlama kursu: https://www.codecademy.com/learn/learn-c-sharp

✅ Online Kurslar:

– Codecademy: https://www.codecademy.com/

– Khan Academy: https://www.khanacademy.org/

– MIT Open Course: https://ocw.mit.edu/courses/

– Stanford Online Course: https://online.stanford.edu/

– FreeCodeCamp: https://www.freecodecamp.org/

– Coursera: https://www.coursera.org/

Codecademy “Learn C#” Online Programlama Eğitimi – [1. Kısım]

Codecademy üzerinden “Learn C#” adındaki programlama eğitiminin 1. kısmını bu Twitch yayını ile tamamladık. Bu yayında konuştuğumuz konu başlıkları şu şekilde;

➡️ Hello World! https://en.wikipedia.org/wiki/%22Hello,_World!%22_program

➡️ Konsoldan bilgi alma ve konsola bilgi yazmak (Console.ReadLine() ve Console.WriteLine())

➡️ Nümerik data tipleri (int, double, decimal, float)

➡️ Cast mantığı (implicit casting, explicit casting)

➡️ Data tipleri çevrimi (Convert.ToX metodları)

➡️ Aritmetik operatörleri kullanma, operatör önceliği

➡️ Modül operatörü

➡️ Arttırım ve azaltım operatörleri (++, –)

➡️ Math sınıfı içerisindeki bazı hazır metodları kullanma (Abs, Pow, Sqrt, Floor, Ceiling, Min, Max)

🔴 İlk ziyaretiniz mi? O zaman sizi şöyle alalım: https://bit.ly/sonergonul-youtube-subs

🔴 Codecademy: “Learn C#” online programlama kursu: https://www.codecademy.com/learn/learn-c-sharp

✅ Online Kurslar:

Codecademy: https://www.codecademy.com/

Khan Academy: https://www.khanacademy.org/

MIT Open Course: https://ocw.mit.edu/courses/

Stanford Online Course: https://online.stanford.edu/

FreeCodeCamp: https://www.freecodecamp.org/

Coursera: https://www.coursera.org/

Codecademy Kodlama ve Programlamaya Giriş Eğitimi – [2. KISIM]

Codecademy üzerinden “Learn How to Code” adındaki programlama eğitiminin ikinci kısmını hep birlikte bu Twitch yayını ile tamamladık. Bu yayında konuştuğumuz konu başlıkları şu şekilde;

➡️ Programlamada Control Flow’ları nelerdir? (Kontrol akışları, if else, exception)

➡️ Listeler nedir ve nasıl kullanılırlar? (Element eklemek, element silmek, index kavramı)

➡️ Programlamada döngüler nelerdir ve nasıl kullanılırlar? (for, while, foreach)

Codecademy Kodlama ve Programlamaya Giriş Eğitimi – [1. KISIM]: https://www.youtube.com/watch?v=PYUFso6r84s

İlk ziyaretiniz mi? O zaman sizi şöyle alalım: https://bit.ly/sonergonul-youtube-subs

Codecademy: “Learn How To Code” online programlama kursu: https://www.codecademy.com/learn/learn-how-to-code

✅ Online Kurslar:

– Codecademy: https://www.codecademy.com/

– Khan Academy: https://www.khanacademy.org/

– MIT Open Course: https://ocw.mit.edu/courses/

– Stanford Online Course: https://online.stanford.edu/

– FreeCodeCamp: https://www.freecodecamp.org/

– Coursera: https://www.coursera.org/

Codecademy Kodlama ve Programlamaya Giriş Eğitimi – [1. KISIM]

Codecademy üzerinden “Learn How to Code” adındaki programlama eğitiminin ilk kısmını hep birlikte bu Twitch yayını ile tamamladık. Bu yayında konuştuğumuz konu başlıkları şu şekilde;

➡️ Programlama, kodlama nedir?

➡️ Programlamada değişken kavramı nedir? Nerelerde kullanılır?

➡️ Programlamada kullanılan genel veri tipleri nelerdir?

➡️ Programlamada aritmetik operatörler nasıl çalışır?

➡️ Programlamada karşılaştırma operatörleri nasıl kullanılır?

➡️ Progralamada mantıksal operatörler nasıl kullanılır?

➡️ Programlama fonksiyonlar nasıl ve nerede kullanılır?

Kanalıma ilk ziyaretiniz mi? O zaman sizi şöyle alalım: https://bit.ly/sonergonul-youtube-subs

Codecademy: “Learn How To Code” online programlama kursu: https://www.codecademy.com/learn/learn-how-to-code

✅ Online Kurslar:

– Codecademy: https://www.codecademy.com/

– Khan Academy: https://www.khanacademy.org/

– MIT Open Course: https://ocw.mit.edu/courses/

– Stanford Online Course: https://online.stanford.edu/

– FreeCodeCamp: https://www.freecodecamp.org/

– Coursera: https://www.coursera.org/

Merhaba Youtube! Merhaba Twitch! Nasıl Bir Programlama Yayını Yapmak İstiyorum? [İlk Yayın]

Twitch üzerinden düzenli olarak yapmayı planladığım programlama yayınlarının akışını konuştuk bu videoda. Bu yayınlarda genel olarak kullanacağımız online kaynakları aşağıda listeledim, siz de istediğiniz sayfayı bookmark’larınıza ekleyip kullanabilirsiniz.

✅ Online Kurslar:

– Codecademy: https://www.codecademy.com/

– Khan Academy: https://www.khanacademy.org/

– MIT Open Course: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/

– Stanford Online Course: https://online.stanford.edu/courses-programs – FreeCodeCamp: https://www.freecodecamp.org/

– Coursera: https://www.coursera.org/

✅ Veri Yapıları ve Algoritmalar:

– GeeksForGeeks: https://www.geeksforgeeks.org/

– LeetCode: https://leetcode.com/

– VisualGo: https://visualgo.net/

– Data Structure Visualizations: https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

✅ Yazılım Kitapları:

– Code Complete 2

– Cracking the Coding Interview

✅ Competitive Programming:

– Codingame: https://www.codingame.com/home

– LeetCode: https://leetcode.com/

– SPOJ: https://www.spoj.com/

– Codewars: https://www.codewars.com/

– Kattis: https://open.kattis.com/

✅ Eğlence

– Satranç: https://www.chess.com/

– Ekşi Sözlük: https://eksisozluk.com/

– GeoGuessr: https://www.geoguessr.com/

– Human Benchmark: https://www.humanbenchmark.com/

10 Milyon

Sabah rutinlerimden biri Stack Overflow‘a bakmak ki yolunuz bu bloğa düştüyse muhtemelen oradan gelmişsinizdir. Genellikle c#, datetime, veya timezone gibi ilgimi çeken etiketlere sahip sorulardan cevaplayabileceğim olanlar var mı diye bakarım. Belirli bir yerden sonra bağımlılık haline geldi bu durum bende. Bunu birkaç senedir düzenli yaptığımdan dolayı da Türkiye’deki en fazla rep puanına’a sahip kullanıcılar arasına girdim. Tabi bu istatistik yurt dışında yaşayan Türk kullanıcılarını saymadığından (sadece lokasyon bazlı) pekte havalı bir istatistik sayılmaz.

Birkaç hafta önce profilim sayfama baktığımda şunu fark ettim;

Bunun ne olduğunu bilmeyenler için şöyle özetleyeyim; Stack Overflow birkaç sene önce profil sayfasına kullanıcıların yaklaşık olarak kaç defa görüntülendiğine dair bir istatistik ekledi. Bu sayede hem kullanıcılar, hem de o kullanıcının sayfasını ziyaret eden herkes bu kişinin bu istatistiğini görebiliyor hale geldi.

Benim profilimde de bu sayı yazıyor. 10 milyon.. wow. Bu çok fazla. Gerçekten bu site içerisinde yazdığım içerikler bu kadar (kabaca kişiye) görüntülenmiş olabilir mi? Sonuçta Stack Overflow’da bir post’u birden fazla görüntülediğinizde o post içerisindeki görüntülenme sayısı artmıyor. 10 milyon kişi mi faydalandı benim yazdıklarımdan? Veya aynı mantık ile bir kişi 10 milyon defa mı faydalandı? Veya 10.000 kişi 1000 defa?

Biraz araştırdım, örneğin yazdıkları post içerisinde bu istatistiğin şu şekilde hesaplandığı yazılıyor;

  • Questions
    • Non-deleted only
  • Answers – Views of the parent question for answers that are:
    • Non-deleted AND
    • Score > 0 AND
    • Also meets one or more of the following criteria:
      • In the top 3 answers OR
      • Is the Accepted Answer OR
      • Score at least 5 OR
      • Has at least 20% of the total vote count

Hmm,  “views of the parent question for answers that are..” kısmı biraz garip. Yani benim verdiğim cevapların görüntülenme sayısı, sorulan sorunun görüntülenme sayısına göre belirleniyor. Aslında biraz anlaşılabilir, çünkü Stack Overflow verilen cevapların görüntülenme sayısını tutmuyor. Sadece soruların görüntülenme sayısı istatistiği var. Bu yüzden o soruyu ziyaret eden kişi, sizin cevabınızı görüntülememiş olabilir.

Stack Exchange Data Explorer içerisinde bu istatistiğe en yakın olacak şekilde bir sorgu yazılmış Martin Smith adlı kullanıcı tarafından. Buradan baktığımda benim için en fazla view alan cevabım 444.000 küsür ile Converting dd/mm/yyyy formatted string to Datetime sorusunda. Evet bu rakam sorulan sorunun görüntülenme sayısı. Benim cevabım burada seçilmiş cevap değil. Peki seçilen cevap gerçekten bu kadar görüntülendi mi? Ya benim cevabım?  Benim cevabım en fazla oy alan cevap bile değil. Fakat yukarıda bahsettiğim “In the top 3 answers” kuralına uyduğu için hesaplamaya dahil edilmiş görünüyor.

Hatta Joel Spolsky, Bits & Pretzels için yaptığı “How to write the script for the future” isimli konuşmasında da (05:00’ten sonra) Jon Skeet‘in 250 milyon’dan fazla kişiye yardım ettiğini belirtiyor.

Neresinden bakarsak bakalım, “people reached” garip bir istatistik türü. Hiçbir şekilde o kişinin sizin cevabınızı okuduğunu ispatlayamıyorsunuz. O zaman bu sayı ne tam olarak? Fikrimce sizin bir şekilde “katkıda bulunduğunuz” içeriğe ait sorunun görüntülenme sayısı. Bu sayı sizin içeriğinize ait doğru rakamı veriyor olabilir veya olmayabilir.

Fakat bu istatistiğin kullanıcılar arasında bir etkisinin olduğunu düşünüyorum. En azından benim tarafımda şöyle bir etkisi oldu; “Neden bunu daha fazla yükseltmiyorum ki?”. Jeff Atwood – ki kendisi Stack Overflow kurucularından biridir Joel Spolsky ile birlikte – Because Reading is Fundamental isimli yazısında şöyle diyor;

If I have learned anything from the Internet, it is this: be very, very careful when you put a number next to someone’s name. Because people will do whatever it takes to make that number go up.

Tabi ki asıl amacım hiçbir zaman sadece buradaki sayıyı yükseltmek olmadı. Stack Overflow’da yazmakta, yazabilmekten her zaman keyif aldım bir programcı olarak. Bilmediğim bir şeyi sormak, bildiğim bir konu hakkında bir şeyler yazmak, bilmesem bile ilgimi çeken bir konu ise o soruya cevap verilene kadar çözümü için araştırma yapmak bir programcılar için elzem bir durum olmalıdır düşüncesindeyim. Fakat burada Jeff’e katılmamak elde değil. İnternet ortamında hangi web sitesinde olursanız olun, klasik bir rep puan sayısı olsun, veya o sitedeki ilerlemenizi gösteren bir progress bar olsun, bu durum kişinin siteye karşı gösterdiği ilgilide otomatik olarak bir arttırım sağlıyor. 

Uzun lafın kısası, 10 milyon olmadı da diyelim ki 5 milyon oldu o da olumlu..

DateTime.Parse(string) kullanmayı bırakamaz mıyız?

gandalf-parse

Scott Hanselman’ın What Great .NET Developers Ought To Know (More .NET Interview Questions) isimli yazısında da bahsedilği gibi, başta Stack Overflow olmak üzere birçok online sitede aşağıdaki şekilde kod örneklerine rastlıyorum:

DateTime dt = DateTime.Parse(myString);

Buna bir son verilmesi lazım. Bu kullanımda bir problem var. DateTime.Parse(string) metodu default olarak CurrentCulture ayalarını kullanmaktadır. Ve bu ayarlara istinaden direkt olarak bir string’i göndermek belirsiz durumlar oluşturmaya zemin hazırlar. Bu şu demek gibi;

Sana bir string gönderiyorum. CurrentCulture ayarlarına istinaden geçerli formatları sırasıyla dene, eğer biri uyuyorsa bu şekilde parse et. Eğer bu string için bu culture ayarlarında uygun bir format yoksa, bir FormatException fırlat.

Örnek olarak “01/02/2015” string’ini örnek alalım. Bu string hangi formatta? 1 Şubat 2015 mi? 2 Ocak 2015 mi? Cevap vermek imkansız zira bu sorunun cevabı dünyanın neresinde yaşadığınıza ve/veya hangi culture ayarlarını kullandığınıza göre değişir. Şehir/bölge olarak eşleştirilen Türkiye (“tr-TR”) ve Hindistan (“hi-IN”) için kullanılan culture ayarlarına ve bölgesel algıya göre bu string “1 Şubat 2015” olarak parse edilir fakat Amerika Birleşik Devletleri (“en-US”) için kullanılan culture ayarına göre “2 Ocak 2015” şeklinde parse edilir.

Bu DateTime.Parse(string) metodunun .NET Framework 4 versiyonu MSDN sayfasında (gördüğüm kadarıyla bu açıklama .NET Framework 4.5 ve 4.6 versiyonunda mevcut değil) da ifade edilir:

Because the Parse(String) method tries to parse the string representation of a date and time using the formatting rules of the current culture, trying to parse a particular string across different cultures can either fail or return different results. If a specific date and time format will be parsed across different locales, use the “DateTime.Parse(String, IFormatProvider)” method or one of the overloads of the ParseExact method and provide a format specifier.

Burada gördüğünüz gibi, spesifik bir format ile DateTime.ParseExact metodunu kullanmak çok daha kontrollü ve kesin bir sonuç döndürür. Tabi bu durumu gelen verinin formatını kesin olarak doğru bildiğimiz zamanlar kullanmalıyız. Eğer güvenmediğimiz veya bilmediğimiz bir yerden bu veriyi alıyorsak DateTime.TryParse veya DateTime.TryParseExact metodları daha uygun olur.

Açıklamada farklı sonuçlar oluşabileceği veya “fail” yani exception alabileceğimiz söyleniyor. Tabi ki bu çok normal. Zira “01/02:2015A22-22” gibi standart olmayan bir string gönderirsek, hangi culture ayarlarını kullanırsak kullanalım bir exception alırız ve bu exception’ı kod tarafıdan handle etmek zorunda kalırız. Standart olmayan veri dışında kullandığımız culture’ın DateTimeFormatInfo.Calendar özelliğinde var olan takvimin desteklediği sınırları aştığı durumlarda veya bu takvim üzerinde var olmayan bir tarihi parse etmeye çalıştığımızda da bu exception’ı alırız.

.NET Framework 4.5 versiyonunda çalıştırdığım şu kodu örnek alalım:

foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    DateTime dt;
    if (!DateTime.TryParse("1500/12/29", culture, DateTimeStyles.None, out dt))
    {
        Console.WriteLine(culture.Name);
    }
}

Bu kod parçası normalde konsola harhangi bir şey yazdırmaz (eğer bu formatı desteklemeyen custom bir culture oluşturmadıysanız). Bu demek oluyor ki bu string formatı bir şekilde lokal makinanızdaki tüm culture ayarları tarafında parse edilebilir. Şimdi de string değerini “1500/12/30” olarak değiştirelim.

foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    DateTime dt;
    if (!DateTime.TryParse("1500/12/30", culture, DateTimeStyles.None, out dt))
    {
        Console.WriteLine(culture.Name);
    }
}

Bu kod 6 adet sonuç üretiyor. TwoLetterISOLanguageName bakımından benzer olanları saymazsak bunlar “prs-AF” ve “yo-NG” değerleri. Peki bunların ortak özellikleri ne? Bu iki CultureInfo değeri DateTimeFormatInfo.Calendar olarak HijriCalendar kullanmakta. Ve bu takvimde 12. ay olan Zulhijjah (diğer adıyla Dhu al-Hijjah) sadece artık yıllarda 30 gün vardır. Diğer yıllarda 29 gün sürer bu ay. Bu arada HijriCalendar içerisinde Miladi takvime göre farklı bir artık yıl hesaplama kuralı vardır. Bu nedenle aslında bu takvimde var olmayan bir tarihi parse etmeye çalıştığımızdan exception almış oluruz. Son olarak string değerini “1500/12/31” olarak değiştirelim.

foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
    DateTime dt;
    if (!DateTime.TryParse("1500/12/31", culture, DateTimeStyles.None, out dt))
    {
        Console.WriteLine(culture.Name);
    }
}

Üstteki kod parçasında kullandığımız ”30” değeri için aldığımız sonuçlara ilave olarak “ar-SA” culture’ını da burada alırız. Neden? Çünkü bu culture değeri DateTimeFormatInfo.Calendar olarak UmAlQuraCalendar kullanmakta ve bu takvimin desteklediği maksimum tarih değeri “1500/12/30”. Bunu .NET Framework kodunu browser üzerinden gözlemleyebileceğiniz reference source içerisinde görebilirsiniz. Bu nedenle bu takvimin desteklediği tarih aralığı dışında bir tarih parse etmeye çalıştığımızdan exception almış oluruz. Aslında yukarıdakine benzer bir durum fakat yine de bahsetmek istedim.

    ////////////////////////////////////////////////////////////////////////////
    //
    //  Notes about UmAlQuraCalendar
    //
    ////////////////////////////////////////////////////////////////////////////
     /*
     **  Calendar support range:
     **      Calendar    Minimum     Maximum
     **      ==========  ==========  ==========
     **      Gregorian   1900/04/30   2077/11/17
     **      UmAlQura    1318/01/01   1500/12/30
     */

Bunların dışında DateTime.Parse(string) kullanımında, CurrentCulture konusunda kesin bir bilgi sahibi olunmasına kesin gözüyle bakamadığımızdan, “AM/PM” belirteçleri, tarih ayıracı, zaman ayıracı, gün isimleri, ay isimleri, kısaltılmış gün isimleri, kısaltılmış ay isimleri vb. özellikler culture bazlı farklılıklar gösterir. Örneğin; “Pazartesi” içeren bir string’i nasıl “en-US” culture’ı ile parse edemiyorsak, “Monday” içeren bir string’i de “tr-TR” culture’ı ile parse edemeyiz.

CurrentCulture ayarı konusunda kesin bilgimiz olsaydı bu herşeyi çözer miydi? Pek değil aslında. .NET Framework üzerindeki major ve minor değişiklikler veya işletim sistemi versiyonu değişikliklerinde bile CultureInfo özellikleri değişebiliyor. Bu konuda en önemli değişikliklerden biri it-IT culture’ı için .NET 3.5 versiyonundan 4.0 versiyonuna geçişte yaşandı. .NET 3.5 ve önceki versiyonlarda bu culture TimeSeparator olarak “.” kullanmasına rağmen .NET 4.0 versiyonu ile birlikte “:” kullanımına geçti. Date and time notation in Italy sayfasına göre de doğru olan “:” gibi görünüyor. Benzer durumlar Windows 10’a ilk geçiş sürecinde de yaşandı. Reddit’te benzer bir thread dahi mevcut. Ek olarak Culture data shouldn’t be considered stable (except for Invariant) yazısını da okuyabilirsiniz. Bu durum özet olarak CultureInfo sayfasında “Dynamic culture data” kısmında şu şekilde açıklanmış:

Except for the invariant culture, culture data is dynamic. This is true even for the predefined cultures. For example, countries or regions adopt new currencies, change their spellings of words, or change their preferred calendar, and culture definitions change to track this. Custom cultures are subject to change without notice, and any specific culture might be overridden by a custom replacement culture. Also, as discussed below, an individual user can override cultural preferences. Applications should always obtain culture data at run time.

When saving data, your application should use the invariant culture, a binary format, or a specific culture-independent format. Data saved according to the current values associated with a particular culture, other than the invariant culture, might become unreadable or might change in meaning if that culture changes.

Metinsel (string) bir veriyi Ticks bazlı bir veri yapısına (DateTime) parse etmenin karmaşıklığı yanı sıra, biz programcılar, kullandığımız culture ayarlarının bu gibi belirsiz değişimlere maruz kalabileceğini (InvariantCulture için bile olsa) unutmamalıyız. Bu nedenle nacizane fikrimce en iyi yaklaşım kendi static formatımızı oluşturmak veya değişimi düşük bir ihtimal olsa da InvariantCulture kullanmaktır. Yazdığımız bütün programların kendilerine özgü gereksinimleri olacaktır, bu yüzden bunları seçerken dikkkatli olmalıyız.

F# Programını Çalıştırmak

F# programlarını Visual Studio içerisinde çalıştırmanın iki yolu var; F# projesi oluşturmak – tıpkı C# projesi oluşturmak gibi – veya F# interactive penceresini kullanmak. F# dili, Visual Studio 2013 içerisinde aşağıdaki proje tiplerini destekliyor;

– Console Application, klasik konsol uygulama projesi template’i.

– Library, sınıf kütüphanesi template’i.

– Tutorial, F# örnekleri içeren bir konsol uygulaması. Buradaki örnek uygulamalara kesinlikle göz atmanızı tavsiye ederim.

– Portable Library, Silverlight, Windows Phone ve Windows 8.x ortamlarında çalıştırılabilen sınıf kütüphaneleri.

Adım adım bir konsol uygulaması oluşturalım hemen.

fsharp1.pngfsharp2.png

F# Interactive Kullanımı

Basit programlar için F# dili F# Interactive (FSI) adında bir seçenek sunar. Bu özelliği küçük kod parçacıklarını test etmek için kullanabilirsiniz. Hangi geliştirme profilini kullandığınıza bağlı olarak Visual Studio içerisinde bu özelliği View veya View –> Other Windows seçekelerini kullanarak bulabilirsiniz.

fsharp3.png

fsharp4.png

FSI penceresi input olarak kod yazmanıza imkan veriyor. Bu yüzden kodunuzu direkt olarak çalıştırabilirsiniz. Farklı olarak statement’lar için tek noktalı virgül (;) yerine iki noktalı virgül (;;) kullanmalısınız. Intellisense özelliğini desteklememesi kötü bir yanı tabi ki.

F# source file ve F# script’i arasındaki en temel fark build action kısmı. F# source file, compile olabilen ve .fs uzantılı bir dosya ve build action kısmı Compile atanmış. F# script’i ise .fsx uzantılı ve build action kısmı None atanmıştır. Fakat hangi dosyayı seçerseniz seçin, seçtiğiniz kodu F# Interactive üzerinde sağ tıklayıp ya da ALT+ENTER klavye kombinasyonu ile çalıştırabilirsiniz.

Gelin 1’den 50’ye kadar olan tek sayıların toplamını bulalım;

let mutable toplam = 0
for i = 0 to 50 do     if i%2 <> 0 then toplam <- toplam + i
printf "1'den 50'ye olan tek sayıların toplamı: %A" toplam

F# Interactive’de sonuç şu şekilde görünür;

1’den 50’ye olan tek sayıların toplamı: 625
val mutable toplam : int = 625

FSIAnyCPU

Bu özellik Visual Studio 2012 ile eklendi. FSI var olan 64-bit işletim sisteminde 64-bit işlemci ile çalışacaktır. Bunun dışında F# Interactive 32-bit işlemci ile çalışır. Bu FSIAnyCPU özelliği Visual Studio’nun Tool-> Options-> F# Tools –> F# Interactive kısmından aktif edebilirsiniz.

FSIAnyCPU işlemcisinin hangisi ile çalıştığına sizeof ve System.IntPtr ile de bakabilirsiniz. 32-bit işlemcilerde 4, 64-bit işlemcilerde 8 değerini geri döndürecektir.

> sizeof<System.IntPtr>;;
val it : int = 4

F# Interactive Directive’leri

F# Interactive içerisinde bulunan directive’leri şu sayfadan görebilirsiniz. Ayrıca F# Interactive içerisinde #help;; komutu ile mevcut direvtive’leri listeleyebilirsiniz.

F# Interactive directives:

#r “file.dll”;;              Reference (dynamically load) the given DLL
#I “path”;;                Add the given search path for referenced DLLs
#load “file.fs” …;;    Load the given file(s) as if compiled and referenced
#time [“on”|”off”];;   Toggle timing on/off
#help;;                      Display help
#quit;;                       Exit

 

F# Derleyici Directive’leri

F# Interactive küçük programlarınızı çalıştırmak için güzel bir özellik. Fakat çalıştırılabilir binary dosyalarınız için iyi bir seçim olmuyor. Bunun için Visaul Studio’ya ihtiyaç duyuyoruz. Şimdi de F# Derleyici Directive’lerine bir göz atalım;

#if koşullu derleme için kullanılır. Syntax’ı şu şekilde if <sembol>. Eğer sembol derleyici’de tanımlıysa, if directive’inden sonraki kod bloğu derlenir.

#else koşullu derleme için kullanılır. Eğer sembol tanımlanmadıysa, else bloğundan sonraki kod bloğu derlenir.

#endif koşullu derleme için kullanılır ve koşullu derlemenin bitimini gösterir.

#line orijinal kod satır numarasını ve dosya ismini gösterir.

#nowarning bir veya daha fazla uyarıyı etkisezliştmeyere yarar. F# genel olarak C#’tan daha fazla uyarı üretir.

F# ile Temel Veri Tipleri

F# bir .NET ailesi dili. Bu yüzden, temel veri tipleri ve referans’ları C# ile çok benziyor.

F# bir strongly typed dildir. Bu nedenle tür dönüşümlerinde oluşan bir hata compile time’da meydana gelir. Bu sayede bu tür hatalar, yazılım geliştirmenin erken evrelerinde kontrol edilip müdahele edilebilir.

C# ile F# arasındaki farklardan biri de; F# örnekleri açıkça tip belirtilmesine ihtiyaç duymaz, bu yüzden genellikle atanan değerden tipi anlayabilir. C# geliştiricileri için bu durum var keyword’ünü anımsatır. Fakat let ile var anahtar sözcükleri arasında bazı temel farklılıklar da mevcuttur.

Aşağıdaki tablo Literals (F#) sayfasının bir kopyası gibi olacak ama yine de C# ve F# gösterimini göstermek istedim;

Veri Tipi C# Gösterimi F# Gösterimi
string string s = “abc” let s = “abc”
char char c = ‘c’ let c = ‘c’
int int i = 5 let i = 5 veya
let i = 5l
Uint uint i = 5U let i = 5u veya
let i = 5ul
decimal decimal d = 5m let d = 5m veya
let d = 5M
short short s = 5 let s = 5s
long long l = 5L let l = 5L
ushort ushort u = 5 let u = 5us
ulong ulong u = 5UL let u = 5UL
byte byte b = 64 let b = 64y
let b = ‘b’B
sbyte sbyte sb = 64 let sb = 64uy
boolean bool b = true let b = true
double double d = 0.3
double d = 0.3d
double d = 3e-1
let d = 3.0 veya
let d = 3e-1 veya
let d = 3.
float float f = 0.3f
float f = 0.3F
let f = 0.3F

 

İlginç bir F# özelliği de, “B” suffix’i ile bir ASCII string’i gösteren byte dizisi oluşturabiliyorsunuz. Direkt olarak Encoding.ASCII.GetBytes fonksiyonunu çağırmak yerine bu suffix kullanılabilir. .NET Framework içerisinde string yapısı Unicode tabanlıdır. Bu yüzden bu yapı biraz garip gelebilir size. Aşağıdaki örnekte, AsciiString bir byte[] tipindedir.

let asciiString = "xyz"B // F# gösterimi
 
byte[] asciiBytes = Encoding.ASCII.GetBytes("xyz"); // C# gösterimi

C#’ın aksine, float tipi F# içerisinde 64 bit’tir (double precision floating-point) ki C#’ta double tipine eşdeğerdir. C# içerisinde float 32 bit (single precision floating-point) memory kaplar ki bu da F#’ta float32 tipine eşdeğerdir.

F# derleyicisi “implicit type conversion”’a izin vermez. Bir C# geliştiricisi için int tipi bir değer float tipinde bir değere herhangi bir işlem yapmadan çevirebilir. Burada bu değer 13’ten 13.0’a dönüşür. Bu F# içerisinde yasak olduğundan integer 13’ü bir float 13’e dönüştürmek için “explicit conversion” yapmanız gerekir.

String tipine bakacak olursa F# 2.0 versiyonunda aynı şu andaki C# string literal’de olduğu gibi iki farklı string var görünüyor; normal string ve verbatim string. Bir de F# 3.0 versiyonu ile triple-quoted string eklenmiş.

let a = "Son karakter bir tab \t"
let b = @"Son karakter bir tab \t"

Bunların F# interactive penceresinde çıktıları şu şekilde olur;

val a : string = "Son karakter bir tab    "
val b : string = “Son karakter bir tab\t"

Bunun dışında C#’tan bildiğiniz gibi escape sequence karakterleri (örneğin; ve \) göstermek isterseniz onları escape etmeniz gerekir. Örneğin;

let a = "Bu gecerli bir \"string\""
let b = @"Bu gecerli bir ""string"""

F# 3.0 ile gelen triple-quoted string bu acıyı hafifletmiş gibi. 3 tane çift tırnak’ın (”””) arasındaki herşey verbatim olarak algılanıyor. Bu yüzden çift tırnak ya da backslash gibi karakterleri escape etmenize gerek yok. Burada da şöyle bir kural var; string tek bir çift tırnak ile başlayabilir ama tek bir çift tırnak ile bitemez. Ayrıca XML tarafında da faydalı olduğu söyleniyor bu üçlü çift tırnak yapısının ama o konuda pek bilgim yok.

let a = """Bu gecerli bir "string" """
let b = """" Bu gecerli bir string """
let c = """ Bu gecersiz bir string """" // Geçersiz string

F# değişken isimlendirmede de bazı kolaylıklar sağlıyor. Bildiğiniz gibi okunabilir bir değişken ismi her zaman yazılımcılar için iyi bir pratiktir. F#’ta alfabetik olmayan değişken isimleri yazmak için çift ters tırnak kullanabilirsiniz.

//Boşluk içeren değişken ismi
let ``benim değişkenim`` = 4
 
//Keyword ile değişken ismi
let ``if`` = 5
 
//Tek tırnaklı değişken ismi
let a' = 6
 
// # içeren değişken ismi
let ``F#`` = "F#"

Akış Kontrolleri

F#’ta imperative stili programlar yazmanız için akış kontrollerini bilmeniz gerekir. For loop, while loop ve if expression bunlardan bazıları. C#’ta { ve } scope ayrımları için kullanırken F#’ta boşluk kullanılır. Visual Studio otomatik olarak tab’ı boşluk’a çevirir.

F#’ta iki çeşit for döngüsü bulunuyor: for…to/downto ve for…in.

for…to/downto döngüsü bir başlangıç değerinden bir bitiş değerine tekrarlanır. C#’taki for döngüsüne çok benzerdir.

for…in döngüsü ise bir pattern ile eşleşen enumerable collection içinde tekrarlanır. Örneğin; Range expression, List, diziler.. C#’taki foreach döngüsüne çok benzer. C#’ta 1’den 100’e kadar olan sayılar üzerinde şu şekilde dönebilirsiniz;

for (int i = 0; i < 100; i++)
{
}

F#’ta şu şekillerde gösterebiliriz;

for i = 0 to 100 do ...
 
for i in [0...100] do ...

Veya 100’den geriye olarak;

for i = 100 downto 0 do ...

Peki for…to/downto döngüsü ile ikişer ikişer nasıl ilerleyebiliriz? Bildiğim kadarıyla bu döngü bunu desteklemiyor. Mecburen for…in ile bir sequence veya list kullanmamız gerekiyor.

F#’ta while loop C#’taki ile aynı şekilde işlev görür. C#’ta şu şekilde;

int i = 0;
while (i <= 10)
{
    i++;
}

F#’ta ise şu şekilde gösterilir;

let mutable i = 0
while i <= 10 do    
i <- i + 1

F#’ta statement’lar sonunda noktalı virgül (;) kullanımı zorunlu değildir. Fakat bir satırda birden fazla statement yazmanız gerektiği bir durumda noktalı virgül kullanmak zorunda kalırsınız.

Gördüğünüz üzere yukarıdaki F# örneğinde mutable anahtar sözcüğünü kullandık. Bunun anlami i bir mutable değişkendir ve <- operatörü ile değeri değiştirebilir. Bu bizi F#’ta farklı bir kavrama götürür. Bunun anlamı; F#’ta mutable keyword’ü ile tanımlanmayan bir değişken immutable object’tir. Onun değerini değiştiremezsiniz. Bu yüzden C#’ta int i = 0 statement’ı F#’ta let mutable i = 0 statement’ına eşdeğerdir. Bu küçük bir değişiklik olarak görünse de, aslında çok temel bir değişikliktir. C#’ta değişkenler varsayılan olarak mutable iken F# değişkenler default olarak immutable’dır. Bu kavramı F# ile Fonksiyonel Programlama yazısında anlatmıştım.

Yukarıda söylediğim gibi F#’ta if bir expression’dır. Bunun anlamı geriye bir değer döndürür. Her if/else kolu aynı tipte değer döndürmelidir. Eğer if kolu herhangi bir değer döndürmüyorsa else kısmı opsiyoneldir. Eğer if bir değer döndürüyorsa else kullanılmak zorundadır. Bu yapısıyla C#’taki ?: operatorüne benzer. If yapısı içerisinde başka bir koşul yerleştirmek için C#’taki if…else if yapısına istinaden F#’’ elif kullanır.

if a<b then "küçük"
elif a>b then "büyük"
else "eşit"

C# eşleşme statement kullanımında switch yapısını kullanırken F# match expression’ını kullanır.

C# gösterimi;

int i = 1;
switch (i)
{
	case 1 :
		Console.WriteLine (1);
		break;
	case 2 :
		Console.WriteLine (2);
		break;
	default:
		Console.WriteLine ("Sayı değil");
		break;
}

F# gösterimi;

let mutable i = 1;
match i with    
	| 1 -> printfn "1"    
	| 2 -> printfn "2"    
	| _ -> printfn "Sayı değil"

C# içerisinde kullandığımız Console.WriteLine() ile konsola yazdırdığımız çıktıları F# ile de kullanabiliriz. Kendisi bir .NET dili olduğu için sorun olmayacaktır. Ama F# bize daha güçlü bir yapı olan printfn yapısını sunuyor. Örneğin;

C#

Console.WriteLine("Toplam: {0}", toplam);

F#

printfn "Toplam: %A" toplam

F# dilinde printfn, Console.WriteLine() methoduna göre daha katıdır. C#’ta {numara} her türlü değişkeni alır ve bu değişkenin tipi hakkında endişelenmeniz gerekmez. F# spesifik bir tipteki değişken için spesifik formatlara ihtiyaç duyar. Bu şekilde F# bununla ilgili hata oluşma olasılığını azaltır. Tüm formatları şu sayfada görebilirsiniz.