F# 9'daki yenilikler
(learn.microsoft.com)-.NET 9 ile gelen F# 9, null atanabilir başvuru tipleri ve geliştirilmiş derleyici tanılarıyla C#/.NET birlikte çalışabilirliğinde ortaya çıkan güvenlik sorunlarını azaltıyor
- Discriminated union
.Is*özellikleri,booldöndüren kısmi aktif desenler ve boş computation expression'lar sayesinde günlük F# söz dizimi daha sade hale geliyor - FSharp.Core, koleksiyonlar için rastgelelik işlevleri ve C# collection expression desteği ekleyerek F# değişmez koleksiyonlarını diğer .NET kodlarında da kullanmayı kolaylaştırıyor
- Derleyici; hatalı attribute kullanımı, 65.520'den fazla IL metodu ve private member görünürlüğü gibi sorunları daha erken aşamada ortaya çıkarıyor
- equality denetimleri, tamsayı aralıkları ve list·array comprehension optimizasyonlarıyla bazı döngüler 1,25×~8×, bazı dizi comprehension'ları ise en fazla 10× hızlanıyor
.NET 9 ile gelen F# 9
- F# 9, programları daha güvenli, daha dayanıklı ve daha yüksek performanslı hale getirmek için değişiklikler içeriyor
- .NET 9 ile kullanılabiliyor ve en güncel .NET SDK, .NET indirme sayfasından alınabiliyor
- Başlıca değişiklikler F# open source code repository üzerinde geliştirildi
Dil özelliklerindeki değişiklikler
-
Null atanabilir başvuru tipleri
- F#,
null'dan kaçınacak şekilde tasarlandı; ancak C# ile yazılmış .NET kütüphaneleriyle birlikte kullanıldığındanullgelebiliyor - F# 9,
string | nullgibi null'un geçerli olduğu başvuru tiplerini tür güvenli biçimde ifade ediyor stringiçinenullkoyarsanız veyastring | nulldeğerinde doğrudan.Length'e erişirseniz null olasılığı uyarısı oluşuyor- Pattern matching içinde
nulldurumu önce ele alınırsa sonraki bağlamalar null olmayan değer olarak değerlendiriliyor - Generic kodda
nulldöndürmek için'T : not structgibi bir başvuru tipi kısıtı gerekiyor - Ayrıntılar için Nullable Reference Types in F# 9 yazısına bakabilirsiniz
- F#,
-
Discriminated union
.Is*özellikleri- Discriminated union'lar, her durum için otomatik üretilen
.Is*özelliklerine sahip - Örneğin
ContacttipindeEmailvePhonedurumları varsaperson.contact.IsEmailile belirli bir durum kontrol edilebiliyor - Eskiden aynı kontrol için
matchifadesiyleEmail _ -> true | _ -> falsegibi kod yazmak gerekiyordu
- Discriminated union'lar, her durum için otomatik üretilen
-
Kısmi aktif desenlerde
booldönüşü- Kısmi aktif desenler (partial active pattern), eskiden eşleşme başarılıysa
Some (), başarısızsaNonedöndürmek zorundaydı - F# 9 ile artık
booldöndürmek de mümkün - Büyük/küçük harf duyarsız string eşleştirme örneğinde
String.Equals(..., StringComparison.OrdinalIgnoreCase)sonucunu doğrudan döndürebilirsiniz
- Kısmi aktif desenler (partial active pattern), eskiden eşleşme başarılıysa
-
Argüman olduğunda extension method önceliği
- Bazı .NET kütüphaneleri, tipin kendi özelliğiyle aynı ada sahip extension method'lar tanımlıyor
- F# 9, bu desene uyum sağlayarak argüman verildiğinde tür denetimi hatası yerine extension method'u çözümlüyor
- Örnekte,
FootipininXözelliğiyle aynı ada sahipX(f: Foo, i: int)extension method'uf.X(1)biçiminde çağrılarak özellik ayarı ve çağrı zinciri birlikte kullanılabiliyor
-
Boş computation expression
- F# 9, boş computation expressions desteği sunuyor
seq { }boş bir sequence oluşturuyor; HTML DSL benzeri kodlardap { }gibi boş bloklar da ifade edilebiliyor- Boş computation expression, builder'ın
Zerometodunun çağrılmasına karşılık geliyor - Önceki
builder { () }kullanımına göre daha doğal bir söz dizimi
Hash yönergeleri ve F# Interactive iyileştirmeleri
-
String olmayan hash yönerge argümanları
- Derleyici hash yönergeleri eskiden yalnızca tırnak içine alınmış string argümanları kabul ediyordu
- F# 9 ile artık herhangi bir tipte argüman alabiliyorlar
#nowarn "0070"yerine#nowarn 0070,#time "on"yerine#time onyazılabiliyor
-
F# Interactive'de genişletilmiş
#help- F# Interactive'teki
#helpyönergesi, nesne veya fonksiyon belgelerini REPL içinde gösteriyor - Argümanlar tırnaksız verilebiliyor
- Örneğin
#help List.map;;, açıklama, parametreler, dönüş değeri, örnekler, tam ad ve assembly bilgisini gösteriyor - Ayrıntılar için Enhancing #help in F# Interactive blog post yazısına bakabilirsiniz
- F# Interactive'teki
-
#nowarniçinFSöneki desteği- Eskiden
#nowarn "FS0057"yazıldığında uyarı numarası doğru olsa bileInvalid warning number 'FS0057'hatası oluşuyordu - F# 9 ile
FSöneki olsa da uyarı numarası kabul ediliyor #nowarn 57,#nowarn 0057,#nowarn FS0057ile string biçimleri"57","0057","FS0057"artık çalışıyor- Yine de proje içinde aynı stili korumak iyi olur
- Eskiden
Derleyici güvenliği ve tanı iyileştirmeleri
-
Hatalı
[<TailCall>]konumu uyarısı- F# 9,
[<TailCall>]attribute'u uygun olmayan bir konuma yerleştirildiğinde uyarı veriyor - Örnekler arasında özyinelemeli olmayan fonksiyonlar, let binding değerleri ve özyinelemeli let binding değerleri yer alıyor
- Bu tür attribute'lar kodun davranışını etkilemese de okuyan kişiyi yanıltabiliyor
- F# 9,
-
AttributeTargetsuygulamasının sıkılaştırılması- Derleyici; let değerlerinde, fonksiyonlarda, union case bildirimlerinde, örtük oluşturucularda, struct ve class'larda
AttributeTargetskurallarını doğru biçimde uyguluyor - Bu sayede Xunit testlerinde unit argümanının unutulması gibi fark edilmesi zor hatalar önlenebiliyor
- Eskiden
[<Fact>] let ``this test always fails`` = Assert.True(false)gerçek bir fonksiyon olmadığı için test çalıştırıcısı tarafından yok sayılıyor,dotnet testde başarılı görünüyordu - Artık
error FS0842: This attribute is not valid for use on this language elementhatası veriliyor
- Derleyici; let değerlerinde, fonksiyonlarda, union case bildirimlerinde, örtük oluşturucularda, struct ve class'larda
-
Parser recovery
- Parser recovery iyileştirmeleri sayesinde düzenleme sırasında sözdizimsel olarak tamamlanmamış kodlarda bile sözdizimi renklendirme gibi araç özellikleri çalışmaya devam ediyor
- Kapsanan durumlar arasında tamamlanmamış
asdesenleri, object expression'lar, enum case bildirimleri, record bildirimleri, karmaşık primary constructor desenleri, çözümlenmemiş uzun tanımlayıcılar, boş match dalları, eksik union case alanları ve alan tipleri bulunuyor
-
Tanı mesajları ve konum doğruluğu
- F# 9, yeni tanı mesajları ve daha doğru tanı konumları ekliyor
- Kapsamda object expression içindeki belirsiz override metodları, non-abstract class içindeki abstract member'lar, discriminated union case ile aynı ada sahip özellikler, active pattern argüman sayısı uyuşmazlığı, yinelenen alana sahip union'lar ve computation expression içinde
use!ileand!birlikte kullanımı yer alıyor - Üretilen IL içinde 65.520'den fazla metoda sahip sınıflar için yeni bir derleme zamanı hatası oluşuyor
- Bu tür sınıflar CLR tarafından yüklenemediğinden çalışma zamanı hatasına yol açabiliyor
-
Gerçek görünürlük seçeneği
- F#, private member'ları IL'e internal olarak yazdığı için,
InternalsVisibleToile F# projelerine erişebilen F# dışı projeler private member'lara uygunsuz şekilde erişebiliyordu - F# 9, bu davranışı düzeltmek için isteğe bağlı
--realsig+derleyici bayrağını sunuyor .fsprojiçinde<RealSig>true</RealSig>eklenerek kullanılabiliyor- Böylece çözümünüzün eski davranışa bağımlı olup olmadığını kontrol edebilirsiniz
- F#, private member'ları IL'e internal olarak yazdığı için,
FSharp.Core standart kütüphanesindeki değişiklikler
-
Koleksiyonlar için rastgelelik işlevleri
List,Array,Seqmodüllerine rastgele örnekleme ve karıştırma işlevleri eklendi- Veri bilimi, makine öğrenimi, oyun geliştirme gibi rastgelelik gerektiren yaygın senaryolarda F# kullanımını kolaylaştırıyor
- Tüm işlevlerin üç varyantı var
- Örtük ve thread-safe paylaşılan bir
Randomörneği kullanan varyant - Argüman olarak
Randomörneği alan varyant - 0.0 dahil, 1.0 hariç
floatdeğer döndürmesi gereken özel birrandomizerfonksiyonu alan varyant
- Örtük ve thread-safe paylaşılan bir
- Sunulan işlevler
Shuffle,Choice,Choices,Sample; her birinin de üç varyantı bulunuyor - Tüm işlev ve varyant listesi için RFC #1135 belgesine bakabilirsiniz
-
Rastgelelik işlevlerinin davranışı
Shuffle, aynı tipte ve aynı boyutta yeni bir koleksiyon döndürüyor; her öğe koleksiyon uzunluğuna göre eşit ağırlıkla karıştırılıyor- Diziler için öğeleri mevcut dizi içinde karıştıran bir
InPlacevaryantı da var Choice, koleksiyon boyutuna göre eşit ağırlıkla tek bir rastgele öğe döndürüyorChoices, giriş koleksiyonundan N öğeyi rastgele sırayla seçiyor; aynı öğe birden fazla kez seçilebiliyorSample, giriş koleksiyonundan N öğeyi rastgele sırayla seçiyor ancak aynı öğeyi iki kez seçmiyorSampleiçin N değeri koleksiyon uzunluğundan büyük olamıyor
-
CustomOperationAttributeiçin parametresiz oluşturucuCustomOperationAttribute'a parametresiz bir oluşturucu eklenerek computation expression builder'larında özel işlemler tanımlamak kolaylaştırıldı- Çoğu durumda açık ad, metod adıyla aynı olduğundan
[<CustomOperation("bar")>]yerine[<CustomOperation>]kullanılabiliyor
-
C# collection expression desteği
- C# içinde F# list ve set tipleri collection expression ile başlatılabiliyor
- Örneğin
SetModule.FromArray([1, 2, 3])yerineFSharpSet<int> mySet = [ 1, 2, 3 ];yazılabiliyor - F# değişmez koleksiyonları,
System.Collections.Immutablekoleksiyonlarında bulunmayan structural equality gerektiğinde kullanılabiliyor
Performans iyileştirmeleri
-
equality denetimi optimizasyonu
- equality denetimleri hızlandı ve bellek tahsisi azaldı
- Struct tipli dizilerde
Array.containsile olmayan bir değeri arama örneğinde eskiden 1.000 kez boxing yapılıyordu, artık yapılmıyor - 2-member struct için dizi işlevleri benchmark'ında
ArrayContainsNonexistingortalama süresi 5.190,95ns'den 766,005ns'ye düştü; tahsis miktarı da 24.000B'den 0'a indi ArrayTryFindNonexistingise 5.139,58ns'den 1.140,515ns'ye düştü; tahsis 24.024B'den 24B'ye geriledi- Ayrıntılar için F# Developer Stories: How we’ve finally fixed a 9-year-old performance issue yazısına bakabilirsiniz
-
Struct discriminated union alan paylaşımı
- Struct discriminated union'larda birden fazla durumda alan adı ve tipi aynıysa aynı bellek konumunu paylaşabiliyorlar
- Bu da struct'ın bellek kullanımını azaltıyor
- Örnekte, aynı
int64tabanlı alanı paylaşan struct discriminated union'ın boyutu 16 bayt - Önceki yaklaşımda her durum için ayrı alan adı kullanıldığında boyut 60 bayttı
- Eskiden aynı alan adına izin verilmediğinden binary compatibility sorunu oluşmuyor
-
Tamsayı aralığı optimizasyonu
- Derleyici,
start..finishvestart..step..finishifadelerinin daha fazla durumda optimize edilmiş kodunu üretiyor - Önceden yalnızca tip
int/int32olduğunda ve step sabit1veya-1ise optimizasyon uygulanıyordu - Diğer tamsayı tipleri ve diğer step değerleri verimsiz
IEnumerabletabanlı uygulamayı kullanıyordu - Artık bu durumların tamamı optimize ediliyor
for … in start..finish do …,[start..step..finish],[for n in start..finish -> f n]kalıplarında 1,25× ile 8× arasında hız artışı görülüyor
- Derleyici,
-
List·array comprehension optimizasyonu
- List ve array comprehension içinde
for x in xs -> …biçimi optimize edildi - Özellikle dizilerde iyileştirme daha belirgin
- Hız en fazla 10× artarken tahsis boyutu yarıya, hatta dörtte bire kadar düşebiliyor
- List ve array comprehension içinde
Visual Studio araç iyileştirmeleri
-
Live buffers artık varsayılan olarak açık
- Visual Studio'daki live buffers özelliği daha önce isteğe bağlıydı; yeterince test edildikten sonra varsayılan olarak etkinleştirildi
- IDE'yi çalıştıran arka plan derleyicisi kaydedilmemiş dosya buffer'larını kullanıyor
- Böylece değişiklikler dosyayı diske kaydetmeden uygulanabiliyor
- Önceden düzenlenmiş ama kaydedilmemiş dosyalardaki sembolleri yeniden adlandırırken beklenmedik davranışlar görülebiliyordu
-
Gereksiz parantezleri kaldırma code fix'i
- Gereksiz parantezler için Visual Studio'da kaldırma code fix'i sunuluyor
- Örneğin
let f (x) = x,let f x = xhaline;let _ = (2 * 2) + 3iselet _ = 2 * 2 + 3haline getirilebiliyor - Amaç, açıklık sağlayan değil yalnızca gürültü yaratan parantezleri azaltmak
-
F# projelerinde özel görselleştirme desteği
- Visual Studio debugger visualizer artık F# projelerinde de çalışıyor
-
Pipeline ortasında signature tooltip
- Önceden pipeline ortasındaki bir fonksiyonda karmaşık curry'lenmiş parametreler zaten uygulanmışsa signature help gösterilmiyordu
- Artık sonraki parametre için signature tooltip görüntüleniyor
1 yorum
Hacker News yorumları
F# ile üniversitede ilk tanıştığımdan beri en sevdiğim dil oldu
union türleri, null güvenliği, pattern matching, record’lar, daha güçlü type inference ve generic constraint’ler gibi özelliklerde C#’ın çok ilerisindeydi
C#’ın zamanla bu özellikleri eklemesi iyi oldu, ama birbirleriyle uyumsuz biçimlerde gelmesi üzücü
F#’a yapılan yatırım C#’a kıyasla çok daha küçük olduğu için inovasyon hızında geri kaldığı yönler de oldu; yine de hâlâ harika bir dil, .NET ekosistemiyle büyük ölçüde uyumlu ve C# ile aynı performansı çok daha az boilerplate ile sağlayabiliyor
Gerekli “yapıştırıcı kodu” içeren yardımcı bir C# projesi yazarak bunu epey kolayca halledebilirsiniz
Bunun dışında aklınızda özel olarak hangi sorunlar var merak ediyorum
F# 9, C#’a yakın zamanda eklenen
ref structgeneric argüman kullanımını da destekliyor; bildiğim kadarıyla F# içinde tanımlanacak özellikleri de getirme planı varŞimdiye kadar arayı kapatma işini etkileyici derecede iyi yaptı ve çok daha fazla takdiri hak ediyor
“Üretilen IL’de 65.520’den fazla metoda sahip sınıflar için yeni bir compile-time hatası geliyor. Böyle sınıflar CLR tarafından yüklenemediği için runtime hatası oluşuyor” kısmını hayal etmek bile zor
Her hâlükârda F# harika bir dil
Microsoft’un Excel’den sonra ortaya çıkardığı en iyi ikinci şey gibi geliyor ve .NET’i makul bir platform hâline getiriyor
JS veya TS’ye zaten aşina olan birine öğretmesi görece kolay ve üretkenliği de yüksek bir dil
oyun motorları, enterprise backend’ler, masaüstü uygulamaları gibi çok farklı bağlamlarda kullanılıyor
Microsoft’un başlarda birkaç hata yaparak büyümesini yavaşlattığını düşünüyorum, ama genel amaçlı bir dil olarak gerçekten iyi ve öğrenmesi de görece kolay
Birkaç yıl önce LINQPad adlı hafif bir IDE ile biraz kurcalamıştım, ama sonrasında artılarını/eksilerini veya gelişimini takip etmedim
https://www.linqpad.net/
Phosphor’da birkaç yıllık ölçekte, şirketi ve teknik yönü F# üzerine kurma gibi büyük bir karar aldık
Bir yılı aşkın denemeden sonra uygulamayı TypeScript ve Rust ile tamamen yeniden yazdık
Geliştirdiğimiz ürün son kullanıcı programlama aracı olduğu için geleneksel frontend/backend sınırları bulanıklaşıyor; .NET ekosistemi buna pek uymadı
Başta Fable ile F# kodunu JS, Rust, .NET vb. hedeflere derleyip farklı teknolojiler arasında type safety’yi korumayı ve gerekli birlikte çalışabilirliği sağlamayı planlamıştık
Gerçekte ise çeşitli kütüphaneler arası birlikte çalışabilirlik beklediğimizden çok daha zordu; birden fazla dependency ve binding’i yönetmek/güncel tutmak gerçekten acı vericiydi
F#’ın güzel ve verimli kod ürettiği varsayımının hâlâ doğru olduğunu düşünüyorum, ama ekosistemi ve tasarım biçimi gereği yalnızca geleneksel frontend/backend sınırları net olan uygulamalara iyi uyduğunu düşünüyorum
Böyle bir durumda F# yalnızca backend’de kullanılacak olur
Şu anda en çok heyecanlandığım teknolojiler içeride kullandığımız Effect ve Moonbit
Effect’in Schema kütüphanesi TS type system’deki birçok boşluğu dolduruyor; Moonbit ise MS/.NET bağımlılığı olmayan modern bir F# gibi görünüyor
Moonbit, OCaml için Fable denebilecek ReScript’in yaratıcısı tarafından tasarlandı; çok iyi tasarlanmış ve optimize edilmiş JS, WASM ve native çıktılara doğrudan derleniyor
Effect’i production’da kullanıyoruz, Moonbit’i henüz kullanmıyoruz; ama yapay zeka öncelikli bir dünya için tasarlanmış bir dil olarak potansiyeli oldukça büyük
Çekirdek iş mantığı ve doğrulayıcılar F# ile yazılmıştı; frontend uygulamasının kalanı TypeScript, backend ise C# ile yazılmıştı
Yani çekirdek mantık ve doğrulama F#’ta, tüm girdi/çıktı ise TS ve C#’taydı
Benzer bir üründü ve F# ile yazıldığını hatırlıyorum, ama son durumunu takip edemedim
Effect oldukça iyi ve keşke TypeScript dışında başka dillerde de olsa
MoonBit ise kendi tescilli programlama dili gibi görünüyor; iyi bilinen bir dil yerine ona geçmek konusunda tereddüt ederdim, bu konuda nasıl düşündüğünüzü merak ediyorum
.NET kullanan herhangi bir dili seçebildiğimiz bir kriptografi dersi vardı; F# ile yaptığım ödevler diğerlerininkinden çok daha okunaklıydı
Daha sık kullanmak isterdim, ama veri bilimi işleri neredeyse %100 Python
F# 9, .NET 9’un neredeyse tüm performans iyileştirmelerinden de yararlanıyor
Özellikle object escape analysis tarafındaki iyileştirmeler büyük
https://devblogs.microsoft.com/dotnet/performance-improvemen...
F# ile çalıştığım zamanları gerçekten özlüyorum
Üretkenliği yüksek bir dil olduğu için güncellemelerini takip etmek bile keyifli
Topluluk büyüklüğü ve Microsoft’un zaman zaman gösterdiği ilgisizlik düşünüldüğünde araç desteğinin oldukça iyi olduğunu düşünüyorum
En büyük sıkıntı kod test coverage doğruluğuydu
Son zamanlarda F#’a biraz dokundum; Python’dan gelen biri olarak REPL ile çeşitli şeyleri deneyebilmek gerçekten hoşuma gitti
Deneyimli F# geliştiricilerinin de böyle kullanıp kullanmadığını merak ediyorum
Bu kış küçük bir web backend projesi yaparak dili ve ekosistemi daha iyi tanımak istiyorum
HTTP tarafında Oxpecker’ın iyi olduğunu duydum; PostgreSQL istemcisi veya sürücüsü için öneri var mı merak ediyorum
ORM’leri sevmiyorum
https://lanayx.github.io/Oxpecker/
https://monazita.gitlab.io/monazita/ F# öğrenirken kişisel projelerim için yaptığım bir şey; temelde çalışıyor ama daha cilalanacak tarafları var ve PostgreSQL’e özel
https://github.com/jacentino/DbFun önceki projeden daha cilalı ve birden fazla veritabanını destekliyor
Oradan başlamak iyi olur
API’den emin değilsem gerçek kod tabanının içinde bile “Send to F# interactive”e basıp modül içinde çalıştırıyor ve deniyorum
Yeni kütüphaneleri denemek, hızlı benchmark yapmak veya PowerShell script’lerinin yerine kullanmak için de kullanıyorum
#!/usr/bin/env -S dotnet fsishebang’iyle F# script’lerini çalıştırılabilir hâle getirmek mümkün; bu yüzden dotnet-sdk’nın zaten kurulu olduğu .NET projelerinin etrafındaki script’lerde bash/Python alternatifi olarak sıkça kullanıyorumGenelde daha hızlı çalışıyor ve çoğu zaman en az onlar kadar kısa oluyor
Kişisel hissime göre F#’ın sözdizimi ve idiomları, küçük kod parçalarını birbirine eklemeye dayalı REPL programlamaya C#’tan daha uygun
C# genelde daha fazla nesne yönelimli yapı gerektiriyor
F#’ta sürüm yönetiminin nasıl olduğunu merak ediyorum
Güzel görünen pek çok yaşam kalitesi iyileştirmesi var; ancak anlamsal sürümleme açısından bakınca uyumluluğu bozan bir değişiklik olmadığı için ana sürüm değişikliği haklı görünmüyor, anlamsal sürümleme kullanmayan bir proje için de 8’den 9’a çıkaracak kadar büyük bir dil özelliği sıçraması gibi durmuyor
Başka bir yorumda yakın zamanda çıkan .NET 9’dan bahsedilmişti; bunun .NET sürüm numarasıyla aynı ritmi tutturmak için mi olduğunu merak ediyorum
.NET sürümüyle örtüşen noktada bilinçli olarak mı geçiş yaptılar, yoksa tesadüf mü bilmiyorum
Örneğin C# .NET 9’a denk gelecek şekilde C# 13’ü çıkardı
dotnet buildçalıştırılırken kullanılan derleme aracı sürümünü ifade ederBuna msbuild, derleyiciler, NuGet paketleri vb. dahildir
Örneğin F# ekibi 8 ile 9 arasında dil değişiklikleri çıkarabilirdi; ama çıkarmamış olsalar bile herhangi bir nedenle .NET 9 gerektiren bir derleyici değişikliği veya msbuild değişikliği çıkarabilirlerdi
Geliştiriciler, dağıtım ortamına en yeni .NET’in kurulmasını beklemek zorunda olmadıkları sürece genelde kodlarını en yeni runtime sürümüne yükseltebilirler
Günümüzde self-contained dağıtımlar oluşturmayı sağlayan MSBuild değişiklikleri sayesinde buna duyulan ihtiyaç da azaldı, ama bilmeye değer bir nokta
Yalnız C# 4 sürüm önde
Zaten anlamsal sürümlemenin abartıldığını düşünüyorum
Windows’ta GUI uygulamaları geliştirirken C# alternatifi olarak F#’ın durumunun nasıl olduğunu merak ediyorum
F#’ı bu amaçla kullanan şirketler olup olmadığını da merak ediyorum
https://github.com/fsprojects/Avalonia.FuncUI
https://fabulous.dev/ Avalonia/MAUI/Xamarin’i hedefliyor
https://github.com/kekyo/epoxy Avalonia ve WPF’yi destekliyor
Şirketlerde bu amaçla kullanılıp kullanılmadığını merak ediyorsan çevreme sorabilirim
F#’ı bizzat denemiş değilim ama göz attığımda şu kaynak çok iyi görünmüştü: https://fsharpforfunandprofit.com/
Deneyimli C# geliştiricileri için de, programlamayı nispeten yeni öğrenenler için de iyi
Günümüzde pek güncellenmediği için F# 9’un yeni özellikleriyle ilgili tartışma bulmak zor; ancak mevcut yazılar
applyvebindgibi kavramları anlamak için mükemmel