Gremlinler İçin Bir Dil: Raku
(buttondown.email)- Raku, Python, J, Frink ve Excel'in matematiksel iş akışlarındaki boşlukları doldurabilecek bir hesap makinesi dili adayı olarak değerlendirildi; kısa denemeler bile onun çok güçlü ama tuhaf bir dil olduğu izlenimini verdi
- Unicode sembolleri, alfasayısal infix operatörler, liste çarpımı·zip·reduce·birikimli toplama,
~~eşleştiricisi ve...dizileri gibi özelliklerle operatör merkezli ifade gücü oldukça geniş - Kullanıcılar yalnızca infix operatörleri değil, circumfix/postcircumfix operatörleri de tanımlayabiliyor; ayrıca birleşme kuralları soldan/sağdan birleşmenin ötesinde zincir ve liste birleşmesini de kapsıyor
- Çoklu dağıtım, yalnızca tür imzalarına göre değil
whereçalışma zamanı koşullarıyla da dallanıyor; fonksiyon imzaları ve içlerindeki parametreler de birinci sınıf değerler olarak ele alınabiliyor - Büyük kod tabanlarının bakımında yükü ağır görünüyor; ancak tek seferlik betikler, hesaplamalar ve kişisel araçlar gibi küçük ölçekli programlama için çekici; dokümantasyon, Windows REPL'i, derleme hızı ve sigil hataları başlıca engeller
Raku'ya bakma nedeni ve ilk izlenim
- Raku, geçmişte Perl 6 olarak bilinen dil
- Yazar, dinamik dillere dair şikâyetlerini yazdıktan sonra bazı kullanıcılar Raku'yu önerdi ve matematik işleri için bir hesap makinesi dili olmaya uygun olup olmadığını görmek üzere incelemeye başladı
- Daha önce Python, J, Frink ve Excel'i birlikte kullanıyordu, ancak her birinin ciddi eksileri vardı
- Birkaç gün denedikten sonra oluşan izlenim, “başka gremlinlerden bolca geri bildirim toplayarak bir dil tasarlamış gerçekten zeki gremlinler”e yakındı
Alışılmadık operatör sistemi
- Raku, Unicode operatörlerini aktif biçimde kullanıyor
- Bir kümenin eleman içerip içermediği
∈ile kontrol ediliyor ∉,∋,∌de mevcut
- Bir kümenin eleman içerip içermediği
- Alfasayısal infix operatörlere de izin veriliyor
- String tekrar operatörü
x - Fonksiyon bileşimi
o
- String tekrar operatörü
- Liste kombinasyonları da kısa sembollerle ifade ediliyor
X, listelerin Kartezyen çarpımını oluşturuyorXf, Kartezyen çarpımdaki her öğeyefuyguluyorZfise aynı işi zip düzeninde yapıyor
- Bir infix operatör
fiçin[f]listeyi reduce eder,[\\f]ise birikimli sonucu üretir[+] <1 2 3 4 5>sonucu15[\\+] <1 2 3 4 5>sonucu(1 3 6 10 15)
~~ eşleştiricisi ve ... dizileri
~~, farklı karşılaştırma türlerini tek sözdiziminde ele alan bir eşleştirici olarak kullanılıyor"abc" ~~ "abc"string eşleşmesini kontrol eder"abc" ~~ Str, bunun string türünde olup olmadığını kontrol eder"abc" ~~ {.chars == 3}, uzunluğun 3 olup olmadığını test eder"abc" ~~ /^b/,abcifadesininbile başlayıp başlamadığını kontrol eder
..., önceki değerlerdeki örüntüyü yakalayıp bir dizi oluşturur0,1,2...10,0'dan10'a kadar 1'er artar0,2,4...10, çift sayılar dizisi olur1,2,4...10,1 2 4 8gibi artış örüntüsünü izler
Kullanıcı tanımlı operatörler
- Raku, bazı dillerde olduğu gibi yalnızca infix operatör tanımlamakla kalmıyor; circumfix ve postcircumfix operatörler de oluşturulabiliyor
- Örneğin
sub circumfix:<[∀ zz>($inner){sum($inner)}gibi sarmalayan bir operatör tanımlanarak içteki değerler toplanabiliyor - Vektör iç çarpımı gibi görünen bir postcircumfix operatör de tanımlanabiliyor
sub postcircumfix:<| ⟩>(@left, @inside){[+] (@left Z* @inside)}<1 2 3>|<4 5 6>⟩sonucu32
- Operatör birleşme kuralları da çeşitli biçimlerde belirlenebiliyor
- Olağan soldan birleşen ve sağdan birleşen infix operatörler tanımlanabiliyor
x < y < zifadesininx < y && y < zgibi yorumlandığı zincir birleşmesi belirtilebiliyora op b op cifadesininop(a, b, c)olduğu liste birleşmesi de destekleniyor
Çoklu dağıtım ve çalışma zamanı koşul dallanması
- Raku, çoklu dağıtım destekliyor; farklı tür imzalarına sahip birden fazla fonksiyon tanımı arasından uygun olanı seçiyor
- Örnek
ffonksiyonu, argüman kombinasyonuna göre farklı davranıyor- Skaler ve dizi alırsa skaler değeri dizinin her öğesine ekliyor
- Dizi ve skaler alan sürüm de destekleniyor
- İki dizi alırsa her öğeyi
Z+ile topluyor
- Daha ilginç olan nokta, değerlerin çalışma zamanı koşul belirteçleri ile de dağıtılabilmesi
multi my_abs(Int $x where {$x > 0}) {$x}multi my_abs(Int $x) {-$x}
- Bir fonksiyonun imzası birinci sınıf bir değer ve imzanın içindeki parametreler de öyle
Küçük özelliklerin yarattığı geniş yüzey alanı
MAINfonksiyonu tanımlanırsa parametreleri otomatik olarak CLI bayraklarına dönüşüyor- Nesnelerde önceden sağlanan yöntem sayısı çok fazla
- List object, tüm permütasyonları, tüm k-kombinasyonlarını ve tüm kayan pencereleri alma yöntemleri sunuyor
- Junctions, aynı anda birden çok karşılaştırma yapmak için kullanılan sıra dışı bir değer biçimi
1|2,any(1, 2)biçimine genişler ve1 < 1|2doğru olur1&2,all(1, 2)biçimine genişler ve1 !< 1&2doğru olur
- Herhangi bir infix operatörün başına
!getirilerek olumsuzlama operatörü yapılabiliyor - Raku, hem
$kebab-caseisimleri hem de infix çıkarma işlemini aynı anda barındıran bir dil gibi görünüyor; bunu ayıran şeyin sigil sistemi olduğu tahmin ediliyor - regex syntax, Perl 5 ile geriye dönük uyumlu değil
- Diller 30 yıl boyunca PCRE “standart”ını izlemiş olsa da Perl 6 bunu terk etmiş
Henüz bakılmayan alanlar ve küçük ölçekteki cazibesi
- İncelenenler, hesap makinesi kullanımı odağındaki özelliklerin yalnızca bir kısmı
- Nesne sistemi, paketler ve grammars henüz öğrenilmemiş
- Fonksiyon gövdesindeki
samewith'in aynı fonksiyonu yeni argümanlarla yeniden çağırması gibi, ele alınmayan pek çok özellik daha var - Bir Raku legacy kod tabanının bakımını yapmak gerekse bunun çok zor olacağı düşünülüyor; ama In The Small programlama için güçlü görünüyor
- Tek seferlik betikler
- Hesaplamalar
- Kişisel araçlar
- Başta istenen türden işler
Şikâyetler ve beklentiler
- Dokümantasyon çok yetersiz ve sembollere bağımlılık nedeniyle arama yapmak zor
- Dokümantasyonu zayıf başka dilleri öğrenmiş olmak bile burada yeterli olmayabilir; Raku çok daha büyük ve karmaşık olduğu için motivasyonu düşürebilir
- Windows'ta REPL'e Unicode girildiğinde çökme yaşanıyor
- Derleyici de oldukça yavaş; küçük dosyalar bile 0.5 saniyeden uzun sürüyor ve tekrar eden işler can sıkıcı hale geliyor
- Sigil sistemi rahatsız edici
$xyerine@xyazılması gereken bir durumda hata ayıklamak için 30 dakika harcandığı bir örnek var
- Genel olarak Raku beğeniliyor ve başarılı olması isteniyor; ancak zamanla özellikle derleme süresi ve dokümantasyonun iyileşmesi umuluyor
1 yorum
Hacker News yorumları
Programlama dillerini iki boyutlu bir alana yerleştirsek eksenler ne kadar şaşırttığı ve şaşırttığında bunun keyifli mi/korkunç mu olduğu olabilir.
Normal dillerin genelde “pek şaşırtmayan ama ara sıra şaşırttığında da keyif veren” sol alt köşede olması sessizce beklenir; Raku ise nadiren dolu olan sol üst köşeyi açıkça hedefliyor gibi. Tavrı daha çok “Tuhaf, değil mi? Harika değil mi?” şeklinde.
document.write = function ...gibi JavaScript yazmıştım ve gereken işi yaptığı için keyifliydi ama aynı zamanda epey korkunçtu.Perl’de de çok sayıda “keyifli sürpriz” vardı; bence Raku esas olarak Perl’ün korkunç sürprizlerini ortadan kaldırmaya yönelik tasarlanmıştı.
∈ile küme üyeliğini kontrol etme kısmında ne demek istendiğini anlıyorum.0,2,4...10(0 2 4 6 8 10)oluyor ama1,2,4...10’un(1 2 4 8)olması “OEIS’te bir sonraki sayıyı mı arıyor?” dedirtiyor.Raku bir dil olarak ilginç, ama bazı idiomlar kafama pek oturmuyor.
AppleScript’in doğal dil gibi görünmeye çalışırken tuhaf hissettirmesine benzer biçimde;
my,say,sub,gathergibi doğal dilimsi öğeler,@gibi semboller, modül bildirimleri ve dışarıdan bakınca Bizans işi görünen sözdizimi kararları bir arada. 99 bottles örneği mantıksal olarak takip edilebiliyor ama sezgisel olarak keşfetmesi zor. Çok fazla sembol var ve bağlama göre aşırı yüklenmiş gibi hissettiriyor; doğal dil parser’ı gibi Raku’nun ideal olabileceği işlerde bile bizzat kullanmak istemem.https://examples.raku.org/categories/module-management/Fletc...
@sigil’i oldukça tanıdık görünür.Raku’da en sevdiğim özellik, tamsayı bölmesinin ve ondalık literallerin ikisinin de rasyonel sayı tipi olan
Ratdöndürmesi.Herkes kayan noktanın pek iyi olmadığını bilir ama ondan gerçekten uzaklaşmaya çalışan dil sayısı çok az; Raku’da kayan nokta literali olması için bilimsel gösterim kullanmanız gerekir.
Bunların rasyonel sayıları ve karmaşık rasyonel sayıları da içeren bir sayı hiyerarşisi var; keyfi duyarlıklı sayıları da doğal olarak destekliyorlar. Birleştirilebilirlik harika.
Rattemsili çok büyürse otomatik olarak kayan noktaya dönüşüyor.1/10birRat, ama1/100000000000000000000birNumoluyor. YükseltilmeyenFatRatda var ama varsayılan değil.Bu yüzden bunu “belirsiz kayan noktayı açıkça istememişken bile kullanma biçiminden uzaklaştı” diye değil, en başta hiç öyle bir durumda olmamıştı diye görmek daha doğru.
(/ 1.0 3.0)0.3333333333333333,(/ 1 3)1/3,(- (+ 0.1 0.2) 0.3)ise5.551115123125783e-17olur.Decimal()çağrısından çok daha fazlafloat()çağrısı var.Parayla doğrudan uğraşmadığım sürece neredeyse her zaman kayan nokta istediğim tercihtir.
Raku belgelerinin “gerçekten berbat” olduğunu düşünmedim; aksine resmi belge sitesi hem kavramsal belgeleri hem de API belgelerini içeren tek durak kaynak olarak etkileyiciydi.
https://docs.raku.org/
Kavramsal belgeler için başlangıç noktası olarak bu sayfa çok iyi: https://docs.raku.org/language
Var olan içeriğin çoğu iyi yazılmış ve yararlı örnek kodlar içeriyor, ama bazen hiç belgelenmemiş ya da yalnızca basit durumları ele alan kısımlarla karşılaşıyorum. Özellikle modül sistemi en sorunlu olanıydı; modül/paket ayrımını yalnızca Modules sayfasını okuyarak anlamak zor. İçe aktarılan ad alanı ile bildirilen ad alanı farklı olabiliyor, ama derleyicinin bulabilmesi için dizin yapısının ad alanıyla eşleşmesi gerekiyor; bu yararlı ve tuhaf biçimde mantıklı, ama deneyerek öğrenmek zorunda kaldım.
Raku’nun havalı Unicode operatörlerinin hepsinin ASCII alternatif gösterimi var.
Örneğin
∈,∉,∋,∌için alternatif gösterimler(elem),!(elem),(cont),!(cont)şeklinde.https://docs.raku.org/language/unicode_ascii#Other_acceptabl...
Dili iyi tanımadan ortaya çıkan tipik eleştirilerin hâlâ tekrarlandığı görülüyor. Eskiden Perl için “line noise” denirdi, şimdi de Raku’nun Unicode operatörlerini çekinmeden kullandığı söyleniyor
Ama bunlar isteğe bağlı; kodun ekranda küçük ve ifade gücü yüksek görünmesi için bizzat denedim. Dikkatli ve yaratıcı Unicode kullanımı için gayet uygun. Sigil’lerden hoşlanmama tepkisi de yaygın, ama Perl’in İsviçre çakısı motorlu testere gibi ifade gücünü sevdiğim için Raku/Perl 6 kullanıyordum; Raku, Perl’i Perl yapan şeylerin karesini almış gibi. Daha düzenli, ifade gücü yüksek ve eski güzel Perl’in üzerine devasa bir özellik yığını eklenmiş. Belgeleri de iyi, ama sürekli elden geçirilmesi gerekiyor; Perl belgeleriyle karşılaştırınca çıta çok yüksek
Birkaç karakter tasarruf etmek için bunu yapmak karmaşık ve pek anlamlı görünmüyor
Sözdizim şekeriyle dolu bir programlama dilinin nasıl görüneceğini bazen merak ederdim; artık biliyorum
“Berbat ama tuhaf biçimde çekici, gözümü alamıyorum, daha fazlasını göster” gibi bir his
GitHub açıklamasında “slaps roof of [programming language]* this bad boy can fit so much [syntax sugar] into it.” yazıyor. En son Advent of Code’u da o dili kullanarak kazandı: https://github.com/betaveros/noulith
Raku’nun aslında Perl 6 olarak başladığını ve tasarım felsefesinin büyük bölümünün Perl tarzı düşünceden çıktığını hatırlamakta fayda var
Yazarın string tekrarı için kullanılan
xoperatörüne hemen tepki vermesine bakılırsa Perl ve Raku tarihini pek bilmiyor gibi görünüyor; oysa bu Perl’de onlarca yıldır böyleydiBoşuna Perl 6 denmedi; neredeyse aynı Perl ekibi geliştirdi. Perl 5’i epey kullanmış biri için Perl6/Raku’nun mirası açıkça görülür. Raku’nun nesne modelinin tamamı da CPAN’deki Perl 5 modülü Moose.pm’in biraz daha güçlü bir sürümüne yakın
Dürüst olmak gerekirse Perl 5/PCRE regex sözdizimi berbat
Var olmasının nedeni de eski regex sözdiziminde
(?ifadesinin sözdizimi hatası olması ve bu yüzden herhangi bir anlam için yeniden tanımlanabilmesinden ibaret. Raku, regex’in neyi ifade etmesi gerektiğini artık bildiğimiz bir zamanda, baştan aklı başında bir regex dili tasarlama girişimi. Alternatif, önümüzdeki 30 yıl daha(?:this|(?>or that))gibi şeylere hapsolmakPerl’e dokunmayalı uzun zaman oldu ama regex’i hâlâ sık kullanıyorum
Belirli bir anlamda kesinlikle gremlin. Tuhaf ve karmaşık ama üretkenliği artıran araçları seviyorum
Yine de “büyük programlar vs küçük programlar” karşılaştırmasına katılmıyorum. Daha az bilge biri bunu büyük işler için kötü bir dil olduğu anlamına yorabilir, ama gerçekte diğer diller kadar iyi, hatta daha iyi bile olabilir. Sorun, diğer gremlin dillerinde olduğu gibi, iyi kullanmak için bilgelik gerekmesi. Örneğin
$xile@x’i karıştıran biri, benzer dilleri yeterince kullanmışsa neredeyse hiç çıkmaz. Sigil’ler kodu okurken değişkenin basit tipini, Raku’da ise arayüzünü hemen gösterdiği için işleri aslında kolaylaştırır; aynı değişken ad alanını farklı sigil’lerle yararlı biçimde kullanabilirsiniz. Garip görünür, gereksiz karakterler gibi durur ve anlamını bilmek gerekir, ama hayatı kolaylaştırabilir: https://www.perl.com/article/on-sigils/Sorun, ne yaptığını pek bilmeyen kişilerde ortaya çıkar. Böyle insanlar için bu gremlin dili yaşayan bir kâbus olabilir; bowling bariyerleri, kolluklar, Kevlar eldivenler, baret, GPS gibi çok sayıda korumaya ihtiyaç duyarlar. Bu, gremlin diliyle gökdelen inşa edilemez demek değil; kazaya yatkın gremlin olmayanlar inşa edemez, bilge gremlinler ise edebilir
Araçlar, ekibin ihtiyaç duyduğu işi daha iyi ya da daha hızlı yapmasına yardımcı olmak için vardır. Junior’ları elemek ya da kendi egonu beslemek için gereksiz derecede karmaşık araçlar kullanıyorsan, o araç organizasyonun geri kalanı için yardımcı olmaktan çok silaha yakındır