- Veri yapılarında öğeleri virgülle ayırırken sondaki ayırıcıya izin verilirse, öğe ekleme·silme·yeniden sıralama aynı tür metin değişikliğiyle işlenir
- JSON, son üyenin ardından gelen virgülü yasakladığı için en sona anahtar eklerken veya silerken mevcut satırı da değiştirmeyi gerektiren bir özel durum ortaya çıkar
- Haskell kayıtları, TLA+ değişken bildirimleri ve Prolog kuralları da ayırıcı konumu ya da bitiş simgesi nedeniyle ilk satır ve son satır değişikliklerini farklı şekilde ele alır
- Python ve Go sondaki virgüle izin verir ama baştaki virgüle izin vermez; Alloy ise hem baştaki hem sondaki virgüle izin verir
- Sondaki ayırıcılar kontrol yapılarında ayrıştırma belirsizliği yaratabilir; Python’daki tek öğeli tuple örneğinde olduğu gibi veri sözdiziminde de anlam ayrımı için kullanılabilir
JSON’da son virgül sorunu
- JSON nesnelerinde üyeler arasında virgüle izin verilir, ancak son üyeden sonra gelen virgül sözdizimi açısından geçerli değildir
{
"a": 1,
"b": 2,
"c": 3
}
- Aynı nesnede
"c": 3, gibi son üyeden sonra virgül eklenirse bu geçersiz JSON olur
{
"a": 1,
"b": 2,
"c": 3,
}
- Sondaki virgüle izin verilseydi,
"a" önüne "x" eklerken ve "c" sonrasına "y" eklerken yalnızca aynı tür satır eklemeleri gerekirdi
{
+ "x": 0,
"a": 1,
"b": 2,
"c": 3,
+ "y": 4,
}
- Mevcut JSON sözdiziminde son konuma anahtar eklerken mevcut son satır
"c": 3 satırına da virgül eklemek gerektiğinden değişiklik daha karmaşık hale gelir
{
+ "x": 0,
"a": 1,
"b": 2,
- "c": 3
+ "c": 3,
+ "y": 4
}
- Öğe kaldırılırken de yalnızca ilgili satırı silmek yetmez; son satırda sonda kalan bir virgül kalmadığından emin olmak gerekir
- Nesne değerinin kendisi çok satırlı bir dizi ya da nesneyse, “sondaki virgül yok” kuralı nedeniyle dönüşüm daha da karmaşıklaşır
Diğer dillerde benzer örnekler
-
Haskell kayıtları
- Haskell, kayıt tiplerinde virgülü her satırın başına koyan “kısmi madde işareti” stilini kullanabilir
data Drone = Drone
{ xPos :: Int
, yPos :: Int
, zPos :: Int
}
- Bu yaklaşım son satırı değiştirmeyi kolaylaştırır, ancak ilk satırı değiştirmeyi daha zor hale getirir
-
TLA+
- TLA+’ta değişken listeleri ve dizilerde sondaki virgül olmayan biçim geçerlidir
VARIABLES a, b, c
vars ==
- Aynı sözdiziminde son öğeden sonra virgül eklenirse geçersiz olur
VARIABLES a, b, c,
vars ==
- TLA+ belirtimleri yazarken en üst düzey değişkenlere sürekli yenileri eklendiği için bu kısıt rahatsız edicidir
- PlusCal DSL’de aynı sorun yoktur ve değişken bildirimleri noktalı virgülle sıralanabilir
(*--algorithm foo {
variables a; b; c;
-
Prolog
- Prolog gibi mantık dilleri yalnızca sondaki ayırıcıya izin vermemekle kalmaz, ayrıca ayrı bir bitiş simgesi de kullanır
foo(A, B, C) :-
A = 1, % comma
B = 2, % comma
C = 3. % period!
- Son noktayı ayrı bir satıra koyma yöntemi bunu süslü parantez gibi göstermeyi sağlayabilir, ancak bu standart sözdizimi değildir ve yine de sondaki ayırıcı elde edilmez
foo(A, B, C) :-
A = 1,
B = 2,
C = 3
.
Daha iyi yaklaşım
-
Sondaki ayırıcıya izin veren diller
- Go, map literal’larında son öğeden sonra virgüle izin verir
valid := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
- Python da dictionary’lerde son öğeden sonra virgüle izin verir
valid = {
"a": 1,
"b": 2,
"c": 3,
}
- Python ve Go’da virgül sona gelebilir ama başa gelemez; bu yüzden tam bir madde işareti stili oluşturulamaz
invalid = {
, "a": 1
, "b": 2
, "c": 3
}
-
Baştaki ayırıcı ve Alloy
- TLA+, öne alınmış birleşim ve öne alınmış mantıksal veya işlemlerine izin verir ama
(a &&) gibi sona eklenen biçime izin vermez
// Not TLA+ but the same semantics
|| && a == 1
&& b == 2
|| && a == 3
&& b == 4
- Alloy, hem baştaki virgüle hem sondaki virgüle izin verir
sig Valid {
, a: 1
, b: 2
}
sig AlsoValid {
a: 1,
b: 2,
}
- Alloy boş ayırıcılara da izin verir; bu yüzden yalnızca birden fazla virgül içeren satırlar da geçerli sayılır
sig StillValid {
,, a: 1,,
,,,,,,,,,
,, b: 2,,
}
- Bu tür biçime bazı kişiler “stuttering” adını veriyor
Karşı argüman: ayrıştırma belirsizliği
-
Prolog’un kontrol ayırıcıları
- Sondaki ayırıcıya karşı argümanlardan biri, ayrıştırmanın belirsiz hale gelebilmesidir
- Prolog’da bir kural noktayla biterse
foo ve barın ayrı tanımlar olduğu açıktır
foo(A, B) :-
A = 1,
B = 2.
bar(c).
- Kural bitiş simgesi virgülle değiştirilirse
bar(c) ifadesi foo tanımının bir parçası olarak yorumlanabilir
foo(A, B) :-
A = 1,
B = 2,
bar(c),
- Bu durumda
foo, ancak bar(c) de doğruysa doğru kabul edilecek şekilde yorumlanabilir
-
Ruby’de metot çağrıları
- Ruby’de satır sonundan sonra da metot zinciri devam edebilir; aşağıdaki kod 5 yazdırır
puts 3.
succ().
succ()
- Metot çağrılarından sonra sondaki ayırıcıya izin verilirse
quux()’un en üst düzey bir fonksiyon mu yoksa foo’nun bir metodu mu olduğu belirsizleşir
foo.
bar().
baz().
quux()
- Prolog ve Ruby örnekleri veri ayırıcılarıyla değil, kontrol ayırıcılarıyla ilgili belirsizliklerdir
Veri sözdiziminde istisna: Python tuple’ı
- Python, parantezleri hem ifadeleri gruplamak hem de tuple tanımlamak için kullanır
(2+3) bir ifadenin değerlendirilmesi olarak işlenir ve int olur
>>> x = (2+3)
>>> type(x)
(2+3,) ise sondaki virgül nedeniyle tek öğeli bir tuple olarak işlenir
>>> x = (2+3,)
>>> type(x)
- Python’daki bu örnekte sondaki veri ayırıcısı, ifade ile tek öğeli tuple arasında ayrım yapma işlevi görür
1 yorum
Lobste.rs görüşleri
JSON sözdizimi, bir nesnenin iki üyesi arasına virgül konulabileceğini ama üyeden sonra sonda gelen virgül konulamayacağını söyler. Buna “tasarım hatası” denebileceğini düşünmüyorum. Çünkü bu bir seçenek değildi JSON, 2000~2001 civarında ECMAScript 3'ün bir alt kümesi olarak oluşturuldu ve bilgilendirici RFC 4627 ise 2006'da yazıldı. JSON'un amacı ve başarısının anahtarı, JavaScript'in bir alt kümesi olması sayesinde tarayıcıda doğrudan
evalile çalışabilmesiydi; tarayıcıların yerel JSON API'si ise ancak 2009'da eklendi ES5'te sonda gelen virgülün tanımlanması da Aralık 2009'da oldu; yani sonda gelen virgüllü JSON, daha en baştan amacına uyan bir şey olarak var olamazdıProlog'da en sık yaşadığım rahatsızlıklardan biri bu. Yüklemler üzerinde çalışırken sona
,true.eklemek işe yarıyor; böylece yukarıdaki satırları yeniden düzenlerken veya yorum satırı yaparken en sondaki noktayı dert etmene gerek kalmıyorwhere true / and ... / and ...biçiminde WHERE koşulunu kullanıyor. Buradaki eğik çizgiler satır sonunu ifade ediyor Bu sayede herhangi bir koşulu özel durum gibi ele almadan kolayca düzenleyebiliyoruzZig, sonda gelen virgülü destekliyor ve bunu yapılandırılamayan formatter'ı kontrol etmek için kullanabiliyor
.{1, 2, 3,}şu hale dönüşüyorAyrıca dikey biçimlendirilmiş literal'de sonda gelen virgülü kaldırmak, yatay hizalama istediğin anlamına geliyor:
.{ 1, 2, 3 }Bu şu durumlarda da çalışıyor: kapsayıcı tür tanımıstruct { a: u32, b: u32, }, fonksiyon imzasıfn foo(a: u32, b: u32,) void {}, fonksiyon çağrısıfoo(1, 2,);Tüm bu durumlarda otomatik biçimlendirmeyi sonda gelen virgülle kontrol edebiliyorsun Bu özelliği o kadar sevdim ki kendi HTML dil sunucuma/otomatik formatter'ıma da ekledim Before:After:
https://github.com/kristoff-it/superhtml
%100 katılıyorum. Sonda gelen ayırıcılar olmayan yeni diller bende kişisel olarak hafif bir eksi puan alıyor. Dilin sözdiziminden nefret edecek kadar değil ama küçük bir yara gibi, rahatsız edici bir şey
foo(1,2,3,4,)?bar(,1,2,3,4)?foo()değişken sayıda parametreye izin veriyorsa son argümannilmi oluyor?bar()için ilk parametrenilmi oluyor?Clojure ve EDN'de virgül boşluk sayılır. Genelde aynı satırdaki map literal içinde anahtar-değer çiftleri arasında geleneksel olarak kullanılır ama tamamen isteğe bağlıdır
Bence burada gerilim yaratan başlıca neden, aynı satırda birden çok öğe olduğunda bir şekilde ayırıcıya ihtiyaç duyulması
Böyle durumlarda satır bazlı diff ile argüman ekleyip çıkarmak her zaman tuhaf görünür. Tek bir argümanı yorum satırı yapmak bile biraz dikkat ve emek ister. Bunun karşılığında bir satıra birden fazla öğe sığdırmanın kısalığını kabul etmiş olursun Ama satır başına tek bir öğe koymaya başladığında, ideal olarak daha temiz diff'ler ve basit satır yorumlarıyla kolayca devre dışı bırakma yöntemi istersin Açık cevap, satır sonunu standart ayırıcı olarak ele almaktır
Birçok dil
;için bunu yapıyor. Bir satıra birden çok ifade koymamayı teşvik eden bir stile sahipsen;neredeyse hiç görünmez. Virgül için de aynısını yapan bir dil bilmiyorum ama hobi dili projelerinde denemek istediğim olmuştu Elbette Lisp, alt ifadeler ve alt öğeler her zaman tamamen ayrıldığı için hiç ayırıcı olmadan bu sorunu pas geçiyorLisp'i, daha doğrusu S-ifadelerini sevmemin nedenlerinden biri de bu. Düşünmem gereken bir ayrıntı daha eksiliyor