İsteğe bağlı noktalı virgüller


10

Çoğu zaman, genel amaçlı bir zorunlu dilde - deyim sınırlayıcılar olarak noktalı virgüller gereklidir veya tamamen izin verilmez (örn. C ve Python).

Bununla birlikte, JavaScript gibi bazı diller, ifadelerinizi diğer sınırlayıcılar (bir satırsonu gibi) lehine noktalı virgülle sınırlamayı seçmenize izin verir.

Bunun arkasındaki tasarım kararları nelerdir? Aynı satırda birden çok ifade yazarken noktalı virgüllerin gerekli olduğunu anlıyorum, ancak bunları zorunlu kılmak için başka bir neden var mı (C'yi takip eden hariç)?


1
Deyim sonlandırıcılar (perl, c) ve deyim sınırlayıcıları (javascript, pascal) hakkında düşünmeniz gerekir.

5
Python'da, noktalı virgüller aynı satırdaki birden çok ifadeyi ayırmak için kullanılabilir. Ve "boş" bir ifadeye izin verildiğinden, noktalı virgüllerin çoğu ifadenin sonunda kullanılabilir.
Greg Hewgill

1
I understand that semicolons are essential when writing multiple statements on the same line- Dile bağlıdır. Benim favorimde böyle bir sınırlayıcı yok, bir sonraki ifade tüm işlev argümanları tükendiğinde başlar.
Izkata

1
@MichaelT: Sınıflandırmalarınızın doğru olduğunu düşünmüyorum: Perl tartışmalı olarak her iki gruba ait ve JavaScript aslında "deyim sonlandırıcılar" kampında (uygulamaların }dosya öncesi veya sonunda noktalı virgül çıkarması gerekiyor ).
ruakh

Evet, kesinlikle dile bağlı. Kişisel tahminim, noktalı virgüllerin, çoğu dil tasarımcının takip ettiği yaygın olarak kabul edilen bir tür sözleşme olduğu yönündedir. En azından daha doğal bir dil bakış açısından bir anlam ifade ediyor. Bloklar için {ve} ile aynı şekilde: bu arada birçok dil tarafından kullanılıyor, ancak hepsi değil ve aslında bunu yapmak zorunda değilsiniz. Bunun arkasında evrensel bir neden yok.
JensG

Yanıtlar:


24

Onları zorunlu hale getirmek (veya tamamen reddetmek) köşe vakalarının sayısını azaltır, potansiyel bir hata kaynağını ortadan kaldırır ve derleyici / yorumlayıcı tasarımını basitleştirir.

Onları isteğe bağlı hale getirmeyi seçen dil tasarımcıları, daha fazla sözdizimsel esneklik karşılığında belirsizlikle yaşamayı seçti.


7
@RobertHarvey Heretic! Bunu yapmanın açık ve tek bir yolu olmalı ve sadece bir tane olmalıdır. Bu arada, perl'de yapmanın sadece bir yolu var.

1
BTW - bazı diller genel olarak gramerlerde oldukça fazla yedekliliğe sahiptir, bu nedenle noktalı virgülün isteğe bağlı hale getirilmesi uygulamada sadece bazen belirsizdir. Bununla birlikte, noktalı virgülün düşmesi için yanlışlık fazlalığı olduğunu düşünüyorum - bunun yerine argümanları ve parantezleri bıraktığınız Haskell'i çok seviyorum. Tamam, noktalı virgülü Haskell'e de bırakabilirsiniz, ancak Javascript ile aynı şey değildir.
Steve314

2
IIRC problemi, resmi modele uymadıkları ancak ayrıştırıcı jeneratörlerinin iyi hata mesajları üretmemesidir. Yani elle yazılmış ayrıştırıcı çok daha yararlı hata mesajı alabilirken, yaygın hatalar hakkında sınırlı bilgiye sahipler. Gcc, örneğin C dilbilgisi için bizon kullanmak için kullanılır. Benzer şekilde sorun, 'kenar vakaların' resmi kenar vakalar değil yumuşak olanlardır - yani ayrıştırıcı için AST açıktır ve insan için AST 'açıktır' ama AST'nin neye benzediğini kabul etmezler.
Maciej Piechotka

2
@Maciej Piechotka - Hasarların parens'in isteğe bağlı olduğunu ima etmek istememiştim. Bir dil tasarımı kararı olarak gereksiz bir şeyi bırakmaktan bahsediyorum. Mesele şu ki, Haskell'deki bir işlev çağrısı için parens veya virgül kullanmıyorsunuz. Sen edebilirsiniz bağımsız değişken olarak bir demet, ama bu argümanlar geçmek için, bir demet için hala sözdizimi var. Haskell (ve ML ve diğerleri), diğer dillerde (Algol'den beri?) Ortak bir konvansiyon olduğu için işlev argümanları için parenleri ve virgülleri "düşürdü", ancak Haskell bunu yapmıyor.
Steve314

1
@Maciej Piechotka - Tabii ki hiçbir zaman gerçekten evrensel bir konvansiyon değildi - sadece Algol-aile dilleri diğer diller kendilerini buna göre tanımladıkları anlamına gelmiyor, bu yüzden "düştü" iddiam bu anlamda yanlış - ama hepsiyle Bugünlerde C-ailesi dilleri biraz böyle hissediyor.
Steve314

15

JavaScript bize bunun çok kötü bir fikir olduğunu gösterdi. Örneğin:

return
0;

C'de bu 0 değerini döndürür. JavaScript'te bu undefined, return ifadesinden sonra noktalı virgül eklendiği için döndürülür ve otomatik noktalı virgül eklemenin ayrıntılarını bilmediğiniz sürece kodunuzun neden kırıldığı hemen belli olmaz.


1
@delnan: Python, C gibi görünecek şekilde tasarlanmamıştır. Girintiye dayalı olduğu ve bu nedenle yüksek derecede satır odaklı olduğu iyi bilinir ve noktalı virgül gerektirmez. JavaScript teknik olarak bunları gerektirir; sözdizimsel olarak geçerli bir ifadeye benzeyen şeyi tamamen farklı semantiklere sahip iki ayrı ifadeye dönüştüren bir eksik bulduğunda bir ekleme yapar.
Mason Wheeler

7
Kötü bir fikir değil, sadece otomatik noktalı virgül ekleme hakkında bilgi edinmek için rahatsız etmeden JavaScript kullanmaya çalışan insanlar için kafa karıştırıcı . Belki de "bu çok kötü bir fikir" demek yerine "noktalı virgülleri isteğe bağlı yapmak, dışarı çıkmayan ve tüm ayrıntıları öğrenmeyen programcılar için tuzaklar getirir" diyebilirsiniz.
TehShrike

4
@delnan: Bu şaşırtıcı oluyor nedeni JavaScript genellikle olmasıdır gelmez , bir satırın sonunda noktalı virgül eklemek bir başka-geçersiz programı düzeltmek için hariç. After return, program onsuz geçerli olsa bile JavaScript'in noktalı virgül ekleyeceği birkaç durumdan biridir. (Ama elbette, bu Mason Wheeler'ın
amacını baltalıyor

6
@TehShrike: Noktalı virgülleri isteğe bağlı yapmak, tüm programcılar için tuzaklar getirir , çünkü ne demek istediğinizi sormak yerine yazım hatalarını keyfi olarak yorumlar . Herkes arada bir yazım hatası yapar.
Jan Hudec

1
javascript, isteğe bağlı noktalı virgüllerin uygulanmasının hatalı olduğunu göstermiştir. İsteğe bağlı noktalı virgüllerin kendileri için kötü olduğunu göstermez.
CodesInChaos

4

Noktalı virgülleri zorunlu kılmak için dilbilginizi ve ayrıştırıcıyı basitleştirir. Temel olarak, lexer'ın yeni satırlar da dahil olmak üzere tüm boşlukları boşaltmasına izin verir ve ayrıştırıcı bunun için endişelenmek zorunda değildir.

Öte yandan, ayrıştırıcıya yine de boşluk hakkında bilgi vermek istediğinizde noktalı virgülleri isteğe bağlı yapmak o kadar da zor değildir. Onları genellikle bir whitespacejetonla birlikte toplayabilirsiniz ve ayrıştırıcınız iyi işleyebilir.

Örneğin, noktalı virgülleri aşağıdaki C ifadeleri dizisine eklemeyi deneyin.

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

Artık yapamayacağınız bazı garip şeyler olsa da while(1);, çoğunlukla, ifadelerin belirli bir sınırlayıcı olmadan nerede biteceğini belirlemek için modern ayrıştırma teknikleriyle nispeten kolaydır. Hala garip şeylere izin vermek isteseniz bile, newline_or_semicolonterminal olmayan bir şey yapmak o kadar zor değil .


C ilk olarak 1970'lerin başında geliştirildiğinde, derleyicileri basitleştirmek için ifade sonlandırıcılara ihtiyaç duyuldu. 90'lı yılların ortalarında, Javascript geliştirildiğinde, daha az endişe duyuyordu.
Sean McSomething

3

Noktalı virgüller bir dilbilgisinde 2 nedenden dolayı yararlıdır. İlk olarak, uzun ifadeleri, iğrenç devam karakterleri olmadan birden çok satıra bölmenize izin verir (Senin hakkında konuşuyorum, Fortran ve Basic). İkincisi, sözdizim bir yazım hatası nedeniyle gerçekten kıvrık hale geldiğinde ayrıştırıcının ayrıştırmak için bir yol bulmasına izin verelim. Karl Bielefeldt örneğinden çalmak,

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

ekstra bir açık paren yazdığınızı hayal edin:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

şimdi hata nerede? Noktalı virgülleriniz varsa, ayrıştırıcının ilk noktalı virgülden vazgeçmesi daha kolaydır. Hatta noktalı virgülden sonra ayrıştırmaya devam edebilirdi.

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

Artık ayrıştırıcıda bir hata bildirmek ve oluştuğu satır / sütunu bulmak daha kolaydır.


1
Fortran ve Basic en azından iyi seçilmiş hat devam işaretlerini (sırasıyla & ve _) seçti. Sırf "" OMG, ne düşünüyorlardı "için hiçbir şey
FoxPro'yu yenemez

2

Noktalı virgüller, sorunuzda belirttiğiniz gibi her zaman ya da hiç değildir. Örneğin, Lua'nın dilbilgisi dikkatlice serbest form olacak şekilde tasarlanmıştır (yeni satırlar dahil tüm boşluklar yok sayılabilir), aynı zamanda noktalı virgül kullanmaya gerek kalmadan. Örneğin, aşağıdaki programlar eşdeğerdir:

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2

0

Tüm tasarım ve inşaat bir yana, birçok programcının farklı geçmişlerden geldiğine ve bazılarının noktalı virgül kullanmayı öğrendiğine ve bazılarının kullanmadığına inanıyorum. Ortaya çıkan birçok yeni dil noktalı virgül gerektirmez, ancak yine de var olmasına izin verir. Bence bu yeni dillerde alışkanlıklarını başladığı zamandan vazgeçmeden daha fazla programcıya nasıl kod yazacağını öğrenmenin bir yolu olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.