Sıra Dışı Raku Özellikleri
(buttondown.com)- Raku, yüksek olgunlukta tek bir tasarımdan çok, birden fazla fikri doğrudan denediği bir dil özellikleri laboratuvarına daha yakın; başka dillerin benimseyebileceği deneyleri tek yerde görmeyi sağlıyor
- Junctions, olası değerler kümesine işlemleri yaydıktan sonra
all,any,onegibi Boole nicelik belirleyicileriyle katlayarak karmaşık koşulları kısa ifade ediyor - Whatevers içindeki
*, sonsuz aralıklar, anonim fonksiyonlar ve liste uzunluğuna dayalı indeksleme için kullanılıyor; kısa ama alışılmadık bir kod tarzı oluşturuyor - Raku regex’leri, PCRE uyumluluğundan vazgeçmek karşılığında birleştirilebilir gramerler, değer ayırıcıları, okunabilir lookahead ve varsayılan olarak boşlukları yok sayma gibi kolaylıklar sunuyor
- Hyperoperators, Pair Syntax, Slangs, RakuAST ve Rakudo Star’a bakıldığında Raku’nun sözdizimi deneylerinden dağıtım biçimine kadar geniş bir alanda denemeler yapan bir dil olduğu görülüyor
Raku’nun neden bir dil özellikleri laboratuvarı gibi göründüğü
- Raku’yu bir yıldan uzun süre fiilen kullandıktan sonra, Raku “dil özellikleri için bir laboratuvar”a daha yakın bir dil gibi görünüyor
- Beş farklı eşzamanlılık modeli ve aynı işi yapmanın birden çok yolu, “ne olacağını görmek için” yapılan deney niteliğini ortaya koyuyor
- Birçok özelliğin tuhaf biçimde etkileşime girmesinin ve çok sayıda edge case barındırmasının nedeni de, 100 deneyi çalıştırmaktan çok onları cilalayıp birlikte çalışır hâle getirmenin çok daha zor olması
- Burada ele alınan özellikler, başka programlama dillerinde de bir gün görülebilecek Raku tarzı deneyler
Junctions: olası değerlerin üst üste bindirilmesi ve Boole nicelik belirleyicileri
- Junctions, olası değerlerin üst üste bindirilmesini temsil eder; bir junction’a işlem uygulandığında aynı işlem içerideki tüm değerlere uygulanır
2|10,any(2, 10)olur2&10 + 3,all(5, 13)olur(1&2) + (10^20),all(one(11, 21), one(12, 22))gibi birleşir
- Junctions’ın temel kullanım amacı
all,anygibi Boole formüllerini ifade etmektir- Bir junction’ı destructure etmenin bir yolu yoktur
- Pratikte kullanmak için önce Boole değerine katlamak gerekir
so, junction’ı Boole değerine zorla dönüştürürso (1&2) + (10^20) < 15,Truedönerso (1&2) + (10^20) > 0,Falsedöner
- Raku’daki
list.all, argüman alan bir metot değil, listeyi junction’a çeviren argümansız bir metottur<1 2 3>.all,all(1, 2, 3)oluris-prime($x)uygulandığında her değere uygulanarakall(False, True, True)gibi olur
- Junctions birleştirilerek
uniquebenzeri davranışlar da oluşturulabilir- “Her eleman tam olarak bir elemanla eşit mi?” ifadesi
{.all == .one}ile anlatılabilir <1 2 3 7>doğru,<1 2 3 7 2>ise yanlış olur
- “Her eleman tam olarak bir elemanla eşit mi?” ifadesi
Whatevers: * ile oluşturulan sonsuz aralıklar ve anonim fonksiyonlar
- Whatevers içindeki
*, Raku’da birden çok rol üstlenen whatever sembolüdür - Aralıklarda veya dizilerde
*, sınır olmadığını ifade eder1..*,1..Infanlamına gelir(2,4,8...*)[17],262144döner
*içeren ifadeler anonim fonksiyona yükseltilir- Bu davranışa whatever-priming denir
- Sonuç
WhateverCodeolur ve tipi dışında diğer fonksiyonlardan ayırt edilmez (* + 10)(2),12döner(^10).map(* % 2),0 1 0 1 ...desenini oluşturur
- Bir ifadede iki
*varsa her biri ayrı bir konumsal argüman olur(2, 30, 4, 50).map(* + *),(32, 54)döndürür- Bu davranış zorlu Fibonacci tanımları için faydalıdır, ancak her
*ın aynı değer olduğu yaklaşımdan daha iyi olduğundan emin değilim
- Raku metotlarının önemli bir kısmı fonksiyon alabildiği için priming yaygın kullanılır
l[*-1]negatif indeks gibi görünür, ama aslında[]liste uzunluğunu fonksiyona geçirip hesaplanan indeksi sorgular- Listenin uzunluğu 10 ise
l[*-1],l[10-1], yani son eleman olur l.head(2)ilk iki elemanı,l.head(*-2)ise son iki eleman hariç tümünü ifade eder
[]içine başka fonksiyonlar geçirilirse ring buffer gibi yapılar da kolayca uygulanabilir@x[95 % *]--, liste uzunluğunu kullanarak konumu hesaplar
Regex: PCRE uyumluluğunu bırakıp birleştirilebilir gramerlere geçmek
- Raku, POSIX regex veya PCRE’den farklı yeni bir regex sözdizimi kullanır
- POSIX regex, çok sayıda ters eğik çizgi ve noktalama işareti içeren bir yapıdır
- PCRE, POSIX ile geriye dönük uyumludur ve daha karmaşık ters eğik çizgi/noktalama yapısını devralır
- Perl 6, geriye dönük uyumluluğu kırarak yeni bir regex sözdizimi getirdi
- En belirgin iyileştirme birleştirilebilirlik tarafındadır
- Birçok dilde regex string’leri yan yana eklenerek birleştirilir
- Raku,
/< foo >+/gibi başka bir regex’i içeri yerleştirerekfooregex’ini bir veya daha fazla kez eşleştirir ve bunun üst regex’e sızmamasını sağlar
- Karmaşık regex’ler daha küçük ve okunabilir parçalara bölünebilir
- Bu yaklaşım, Raku’nun parsing gramerlerini yerleşik dil özelliği olarak desteklemesinin temelini oluşturur
- Geriye dönük uyumluluğu kırarken çeşitli kolaylık özellikleri de eklendi
\d+ % ',',1,1,2,1,1,4ile eşleşir; ancak1,veya12ile eşleşmez- lookahead ve non-capturing group anlaşılması zor sembol kombinasyonları değildir
r1 && r2, yalnızca hemr1hemr2koşulunu karşılayan string’lerle eşleşir:ile backtracking durdurulabilir- Boşluklar varsayılan olarak yok sayılır; eşleşme deseninde açıkça etkinleştirilmeleri gerekir
- Raku’nun regex notasyonu, gerçek işleme yeteneklerinden bağımsız olarak başka dillerde de ortaya çıkabilecek bir özellik olarak görülebilir
Hyperoperators: iç içe listelere kadar inen genelleştirilmiş mapping
- Hyperoperators temel biçimi olan
l>>.method,mape benzer ama alt listelerin içine özyinelemeli olarak iner[1, [2, 3], 4]>>.succ,[2 [3 4] 5]olur
- Raku’da
f(list, *args)biçimindeki fonksiyon çağrısı,list.&f(* args)biçiminde metot formuna dönüştürülebilir- Bu yüzden
>>.genelleştirilmiş bir mapping operatörü gibi çalışır - Whatever ile birlikte
[1, [2, 3], 4]>>.&(*+1)şeklinde kullanılabilir
- Bu yüzden
- İkili hyperoperator olan
l1 << op >> l2,opu iki listeye eleman bazında uygular- Daha kısa liste, uzun liste bitene kadar tekrarlanır
[1, 2, 3, 4, 5] <<+>> [10, 20],[11 22 13 24 15]olur<< op<<veya>>op>>biçimleri yalnızca sol ya da sağ liste bitene kadar tekrarlar
- Tekil değerler ve iç içe listelerle de çalışır
[1, 2, 3, 4, 5] <<+>> 10,[11 12 13 14 15]olur[1, [2, 3], 4, 5] <<+>> [10, 20],[11 [22 23] 14 25]olur
- İki hash için hyperoperator, birleşim, kesişim ve hash farkına
opuygulayan ayrı davranışlara da sahiptir - Hyperoperator adını, tüm işlemleri paralel değerlendirmesinden alır
- Açık döngüler de
hyperönekiyle paralelleştirilebilir
- Açık döngüler de
Pair Syntax: hash’in temel birimi ve kısa bayrak aktarımı
- Pair, Raku hash’lerini oluşturan temel birimdir
- Hash,
key => valueçiftlerinden oluşan bir koleksiyondur - Pair temel tiptir; hash ise pair koleksiyonudur
- Hash,
- Raku’da pair’leri kısa belirtmek için çok sayıda colon syntax vardır
my $x = 3; :$x,x => 3olur:a<$x>,a => "$x"olur:a($x),a => 3olur:3a,a => 3olur
- En önemli kısaltma
:keyve:!keybiçimleridir- Bunlar sırasıyla
key => True,key => Falseolarak eşlenir - Metotlara bayrak eklemenin kısa bir yolu olarak kullanılır
- Bunlar sırasıyla
matchmetodu, bayrak gibi birden fazla colon pair alır:continue(:$c),:pos(:$p),:global(:$g),:overlap(:$ov)gibi biçimler kullanır- İmzadaki
:f(:$foo),$fooparametresini tanımlarken:ftakma adını da oluşturur - Çağıran taraf aynı bayrağı
:fveya:fooile ayarlayabilir
- Colon pair argümanları sıra ve konum açısından esnektir
"abab".match(/../, :g), global eşleştirme yapar"abab".match(/../, :g, :ov), örtüşmeli eşleştirme yapar"abab".match(:g:ov, /../)gibi sıra değiştirilebilir ve bitişik yazılabilir"abab".match(:g, /../):ov:2ndgibi fonksiyon çağrısından sonra anahtar sözcük argümanları konabilir
- Bu sözdizimi, metot seçeneklerini
match(global=True, overlap=True)yazmaktan çok daha kısa belirtmeyi sağlar
Slangs, RakuAST, Rakudo Star
- Slangs, Raku sözdizimini değiştiren bir özelliktir
- Döngü sözdizimini düzenlemek, tanımlayıcıları değiştirmek, actor eklemek, DNA dizileri eklemek gibi amaçlarla kullanılabilir
- Örnek olarak Slang::Otherwise, Slang::Piersing, OO::Actors, BioInfo veriliyor
- RakuAST, Raku ifadelerini Raku içinde AST olarak parse eden bir özelliktir
Q/my $x; $x++/.AST, değişken bildirimi ve postfix artırma işleminiRakuAST::StatementListbiçiminde gösterirQ/my $x; put $x/.AST.DEPARSE("NL")gibi, Raku kodunu başka bir dil tarzı notasyonla çıktılama örneği vardır
- Raku’da Rakudo Star kurulum dağıtımı vardır
- Bu dağıtım, seçili üçüncü taraf modülleri önceden kurulu olarak sunar
- Büyük bir standart kütüphanenin bakım yükü ile kullanıcının ekosistemde uygun paketi kendi bulma yükü arasında bir uzlaşmaya yakındır
1 yorum
Hacker News yorumları
Daha önce burada bahsettiğim birleştirilebilir düzenli ifadeler özelliğine benzer bir şeyi JavaScript için bağımsız olarak uygulamıştım; aradan yıllar geçmesine rağmen başka projelere en sık taşıdığım kütüphanelerden biri hâlâ bu
Dilin içinde birinci sınıf bir parser varmış hissine biraz daha yaklaşıyor; örnek olarak bunu kullanıp medya türü ayrıştırmayı düzenli ifadelerle gerçekleştiren bir uygulama var: https://runkit.com/tolmasky/media-type-parsing-with-template...
npm’de
templated-regular-expression, GitHub: https://github.com/tolmasky/templated-regular-expressionElbette programlama dillerinde gerçek parser’lar olmalı ve düzenli ifadeler parser olarak kullanılmamalı; ama zaten düzenli ifade kullanacaksanız, onu küçük parçalara bölebilmek gerçekten çok iyi
Raku’nun düzenli ifadeleri grammar ile birleşince çok daha güçlü oluyor ve iyi yazıldıklarında herhangi bir “gerçek parser”dan daha anlaşılır olabiliyor. Raku’yu sıradan bir parser ile ayrıştırmak için, ayrıştırma sırasında parser’a öğe ekleyip çıkarabilmeniz gerekir; Raku’nun parser’ı bunu, mevcut grammar’yi subclass edip geçerli sözcüksel kapsam içinde öğeler ekleyip çıkararak ve kapsam bitince önceki grammar’ye dönerek halleder
Raku’da düzenli ifade, kod yazmak için kullanılan başka bir sözdizimidir; temel sözdizimi ve davranıştan yalnızca biraz farklıdır, ayrıca parametreleri ve değişkenleri olabilir. Düzenli ifade sözdiziminin uygun olmadığı bir iş varsa, normal Raku sözdizimini araya sokup gereken işi yaptıktan sonra tekrar düzenli ifade sözdizimine dönebilirsiniz
Örneğin bir veya daha fazla
A’nın ardından aynı sayıdaBve aynı sayıdaCeşlemek de mümkündür; çoğu düzenli ifade sözdiziminde aynı sayıdaAveBeşlemek için arada özyineleme gerekir, ama bunu yapıncaC’yi de aynı şekilde ele almak zorlaşır ve okunması çok daha güçleşir. Raku’nun yaklaşımı geri izleme ya da özyineleme gerektirmez, bu yüzden oldukça hızlı çalışabilirGrammar ile paketlediğinizde eksiksiz bir parse tree elde edersiniz; grammar olmadan da yapılabilir ama grammar kullanmak daha kolaydır. Gerçek parser örneği olarak sık sık JSON::TINY::Grammar önerilir: https://github.com/moritz/json/blob/master/lib/JSON/Tiny/Gra...
Açıkçası “gerçek parser” tasarımının önemli bir kısmı, ilk bilgisayarların kısıtlı RAM’inden kaynaklanan bir yan ürün gibi görünüyor. Ayrı bir tokenization aşaması, kaynak kodun kapladığı RAM’i azaltıp sonraki anlamsal analiz ve derleme için bellek bırakmaya yönelikti; bunun sonraki aşamaları o kadar da çok basitleştirdiğini düşünmüyorum. Yukarıdaki JSON::Tiny modülü, grammar ayrıştırma yaparken action class aracılığıyla yerel Raku veri yapıları oluşturduğu için, ayrıştırırken aynı anda derleme yapmış oluyor
Raku’yu prodüksiyonda kullanıyorum. Metin işleme için en iyi dil ve parser oluşturma deneyimi inanılmaz iyi
Bunun LLM metin pipeline’ları oluşturmak için en üst düzey dil olmaması şaşırtıcı
Vay. Bir gün Raku codebase’i bakımını yapmak zorunda kalmadan sektörden ayrılmak istiyorum
Giriş seviyesi Raku kitaplarına bakınca birçok yerde Python’a C ailesi sözdizimi eklenmiş gibi hissettiriyor. Süslü parantez merkezli bir sözdizimi var ama kullanım kolaylığı, yerleşik veri yapıları ve nesne yönelimli özelliklerin hepsi üst seviye
Başka üst seviye betik dillerini biliyorsanız, benzer bir betiğin Raku kodunu oldukça kolay okuyabileceğinizi düşünüyorum. Gündelik kodda gerçekten tuhaf özelliklerin çoğunu çoğu kişinin kullanacağını sanmıyorum; Raku daha esnek ama normal kod genellikle anlaşılması zor görünmüyor
Raku’da keyword argument’ları kısaltılmış biçimde tanımlayabilme, örneğin
:global(:$g)ya daTruedeğeri varsayarakmatch(/foo/, :g)gibi global düzenli ifade eşleşmesi çağırabilme yeteneğinde de bunu görüyorsunuz. Perl’de de bunlardan çok var; hepsi daha hızlı ve eğlenceli kullanmak için, ama yeni başlayanlar için daha az okunabilirSanırım bu artık bir nesil farkı olacak. Daha yaşlı programcı kuşağının tamamı, mevcut kuşak için sıradan olan çalışma ortamında yerini kaybetmiş gibi hissedebilir
Bazı özellikler yarı tanıdık geliyor. Hyper, recursion-schemes tarafındaki bir şeyin daha doğaçlama yapılmış bir sürümü gibi geliyor; burada gösterilen
*da Scala’daki_ile bir ölçüde benzer_lambda’larda kullanmak için çok hoşuma gidiyor; keşke tüm diller benzer bir şeyi benimsese> (2, 30, 4, 50).map(* + *) returns (32, 45)aslındareturns (32, 54)olmalı değil mi? İkinci terim 4+50 olurduBelki de bazı ülkelerde İngilizcedeki fifty-four yerine vierenvijftig gibi “four and fifty” şeklinde söylenmesinden kaynaklanan bir ön ek çevirisi sonucudur
(32 54)döndürüyor. Yazarın eli kaymış gibiO hâlde Perl artık APL ailesi dillerine giden bir giriş uyuşturucusu mu?
Örneğin reduce meta operatörü
[ ], infix+ile birlikte kullanılarak “hepsini topla” yapılabilir:[+] 1, 2, 3Raku’da hız hâlâ büyük bir sorun. Regex ile günlük dosyalarını ayrıştırmak Perl’ün güçlü yanı, ama en güncel Raku bile başlangıç süresi hariç Python 3.13’ten 6,5 kat daha uzun sürüyor
(2,4,8...*)[17]ifadesinin262144olması gerçekten şaşırtıcıydıWhateverhariç tutulursa, Perl6/Raku sonrasındaki yenilik daha çok tembel değerlendirme tarafında gibi görünüyor(1,3,9...*)[4,5]sonucu(81 243)olur,(1,3,9...*)[(1..3)]sonucu ise(3 9 27)olurİç içe de kullanılabildiği için
(1,2,4...*)[(1,2,4...*)[1,2,3]]gibi ifadeler de mümkünRaku özellikleri arasından ilginç olanlar seçilip ele alınmış gibi
Bana göre en önemli Raku özellikleri komut satırı arayüzü ve grammar
Komut satırı arayüzü desteği yaygın bir özellik; örneğin
docoptimplementasyonları ve benimseme örnekleri var. Ancak Raku’da bu özellik yerleşik ve kullanımı rahatBuna karşılık grammar, bir programlama dilinin grameri birinci sınıf bileşen olarak sunması ve nesne yönelimli programlamayla gramer oluşturup birleştirmeye imkân vermesi bakımından nadir bir özellik
Bu projeyi birkaç yıldır takip ediyorum ve ilginç buluyorum; yine de Perl 6’nın bu aynanın içinden yolculukta fazlasıyla yolunu kaybetmiş gibi görünmesi gerçekten üzücü