Neden çoğu ana dil, 3 yollu Boole karşılaştırmaları için “x <y <z” sözdizimini desteklemiyor?


34

İki sayıyı (veya diğer iyi düzenlenmiş varlıkları) karşılaştırmak istersem, bunu yapardım x < y. Üçünü karşılaştırmak istersem, lise cebir öğrencisi denemeyi önerecektir x < y < z. İçimdeki programcı "hayır, bu geçerli değil, yapmanız gerekiyor x < y && y < z" ifadesiyle cevap verecektir .

Karşılaştığım çoğu dil bu sözdizimini desteklemiyor gibi görünüyor, ki bu matematikte ne kadar yaygın olduğu belli. Python önemli bir istisnadır. JavaScript bir istisnaya benziyor , ancak bu aslında operatörün öncelikli ve örtülü dönüşümlerinin talihsiz bir yan ürünü; node.js dosyasında 1 < 3 < 2değerlendirir true, çünkü gerçekten (1 < 3) < 2 === true < 2 === 1 < 2.

Öyleyse sorum şu: Programlama dillerinde neden x < y < zbeklenen anlambilim ile yaygın olarak bulunmuyor?


1
: Ben sanmıyorum zor oluyor - İşte onlar dezavantaj Python belgelerinde sağ sopa dilbilgisi dosyası, var docs.python.org/reference/grammar.html
Aaron Hall

Python'u bildiğim kadar diğer dilleri de bilmiyorum, ancak Python'un yorumunu basitleştirebilirim. Belki de cevaplamalıyım. Fakat gnasher729'un zarar verdiği sonucuna katılıyorum.
Aaron Hall,

@ErikEidt - Talep, matematiksel ifadeleri, lisede (veya daha erken) öğretildiğimiz şekilde yazabilmektir. Matematiksel olarak eğimli olan herkes $ a <b <c <d $ 'nın ne demek olduğunu bilir. Sırf bir özellik olması, onu kullanmanız gerektiği anlamına gelmez. Bundan hoşlanmayanlar, kullanımını yasaklayan her zaman kişisel veya proje kuralı yapabilir.
David Hammen

2
Sanırım, aşağı indiği şey, C # ekibinin (örnek olarak) LINQ'u keşfetmesinin ve gelecekte belki de insanları ve 4 tuşa basmayı kurtaracak bazı sözdizimsel şeker eklemekten daha farklı türleri ve kalıp eşleştirmelerini kaydetmesinin daha iyi olduğunu düşünüyorum. herhangi bir anlamlılık ekleyin ( s static bool IsInRange<T>(this T candidate, T lower, T upper) where T : IComparable<T>de gerçekten sizi rahatsız ediyorsa, onun gibi bir yardımcı karakter yazabilirsiniz &&)
sara

1
SQL oldukça "mainstream" ve "x 1 ile 10 arasında" yazabilirsiniz "
JoelFan

Yanıtlar:


30

Bunlar, zincirlendiklerinde normal ve doğal olarak aşağıdaki gibi soyut bir sözdizimi ağacı oluşturan ikili işleçlerdir:

ikili operatörler için normal soyut sözdizimi ağacı

Değerlendirildiğinde (bunu yapraklardan yaptığınız gibi), bu, bundan bir boole sonucu verir x < y, ardından yapmaya çalışırken bir tür hata alırsınız boolean < z. Bahsettiğiniz x < y < zşekilde çalışabilmek için , derleyicide şöyle bir sözdizimi ağacı üretmek için özel bir durum oluşturmanız gerekir:

özel durum sözdizimi ağacı

Bunu yapmak mümkün değil. Belli ki öyle, ancak bu kadar sık ​​rastlanmayan bir durum için ayrıştırıcıya biraz karmaşıklık ekliyor. Temelde, bazen ikili bir operatör gibi davranan ve bazen üçlü bir operatör gibi davranan, hata yönetimi ve bunun gerektirdiği tüm sonuçları içeren bir sembol yaratıyorsunuz. Bu durum, dil tasarımcılarının mümkünse kaçınmasını tercih ettiği için yanlış giden şeyler için çok fazla alan ekler.


1
"sonra boolean <z boolean yapmaya çalışırken bir tür hata alıyorsunuz" - derleyici z karşılaştırması için y değerini yerinde değerlendirerek zincirlemeye izin vermiyorsa. “Bu, yanlış giden şeyler için dil tasarımcılarının mümkünse kaçınmasını tercih ettiği bir alan yaratıyor” Aslında Python bunu yaparken sorun vardır ve ayrıştırma için mantık tek fonksiyonu sınırlıdır: hg.python.org/cpython/file/tip/Python/ast.c#l1122 - gitmek şeyler için boşluk değil bir sürü yanlış. "bazen ikili bir operatör gibi davranır ve bazen etkili bir üçlü operatör gibi davranır," Python'da tüm karşılaştırma zinciri üçlüdür.
Aaron Hall

2
Yapılabilir olmadığını, sadece fazladan karmaşık bir iş olduğunu söylemedim. Diğer diller yazmak zorunda değilsiniz , herhangi sadece kendi karşılaştırma operatörlerini işlemek için ayrı bir kod. Diğer binary operatörler ile ücretsiz olarak alabilirsiniz. Sadece önceliklerini belirtmeniz gerekiyor.
Karl Bielefeldt

Evet, ama ... orada olan bir zaten Üçlü operatör birçok dille kullanılabilir?
JensG

1
@JensG Üçlü ifadesi, 3 argüman aldığı anlamına gelir. Bağlantınızın bağlamında, bu üçlü bir durum operatörüdür. Görünüşe göre 2 alır ama aslında 3 alır bir operatör için yazılmış bir terim "trinary" Bu cevap ile benim temel sorun çoğunlukla FUD olduğunu.
Aaron Hall

2
Bu kabul edilen cevabın en önemlilerinden biriyim. (@JesseTG: Lütfen bu cevabı kabul etmeyin.) Bu soru ne x<y<zanlama geldiğini ya da daha önemlisi karıştırır x<y<=z. Bu cevap x<y<ztriner operatörü olarak yorumlanır . Bu tam olarak tanımlanmış matematiksel ifadenin nasıl yorumlanmaması gerektiğidir. x<y<zbunun yerine kısaca (x<y)&&(y<z). Bireysel karşılaştırmalar hala ikilidir.
David Hammen

37

x < y < zProgramlama dillerinde neden yaygın olarak bulunmuyor?

Bu cevapta ben sonuç

  • Her ne kadar bu yapı bir dilin gramerinde uygulamak için önemsiz olsa da ve dil kullanıcıları için değer yaratıyorsa,
  • Bunun pek çok dilde bulunmamasının temel nedenleri, diğer özelliklere göre öneminden ve dillerin yönetim organlarından birinin isteksizliğinden kaynaklanmaktadır.
    • Potansiyel olarak kırılma değişiklikleri olan kullanıcıları üz
    • Özelliği uygulamak için hareket etmek (örneğin: tembellik).

Giriş

Bu konuda bir Pythonist'in bakış açısından konuşabilirim. Bu özelliği olan bir dilin kullanıcısıyım ve dilin uygulama ayrıntılarını incelemeyi seviyorum. Bunun ötesinde, C ve C ++ gibi dilleri değiştirme sürecine biraz aşina oldum (ISO standardı komite tarafından yönetiliyor ve yıllara göre uyarlanıyor.) Ve hem Ruby hem de Python'un kırılma değişiklikleri gerçekleştirmesini izledim.

Python'un dokümantasyonu ve uygulaması

Dokümanlar / gramerden, karşılaştırma operatörleriyle istediğiniz sayıda ifadeyi zincirleyebileceğimizi görüyoruz:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"

ve belgeler ayrıca şunları belirtir:

Karşılaştırmalar keyfi bir şekilde zincirlenebilir, örneğin, x <y <= z, x <y ve y <= z'ye eşittir, ancak y yalnızca bir kez değerlendirilir (ancak her iki durumda da z, x <y bulunduğunda hiç değerlendirilmez) yanlış olmak için).

Mantıksal Eşdeğerlik

Yani

result = (x < y <= z)

mantıksal olan eşdeğer değerlendirilmesi açısından x, yve zdışında, yiki kez değerlendirilir:

x_lessthan_y = (x < y)
if x_lessthan_y:       # z is evaluated contingent on x < y being True
    y_lessthan_z = (y <= z)
    result = y_lessthan_z
else:
    result = x_lessthan_y

Yine fark, y'nin yalnızca bir kez değerlendirildiğidir (x < y <= z).

(Not: Parantezler tamamen gereksiz ve gereksizdir, ancak bunları diğer dillerden gelenlerin yararına kullandım ve yukarıdaki kod oldukça yasal Python'dur.)

Ayrıştırılmış Soyut Sözdizimi Ağacını İnceleme

Python'un zincirleme karşılaştırma işleçlerini nasıl ayrıştırdığını inceleyebiliriz:

>>> import ast
>>> node_obj = ast.parse('"foo" < "bar" <= "baz"')
>>> ast.dump(node_obj)
"Module(body=[Expr(value=Compare(left=Str(s='foo'), ops=[Lt(), LtE()],
 comparators=[Str(s='bar'), Str(s='baz')]))])"

Böylece Python veya başka bir dilin ayrıştırılması için bunun gerçekten zor olmadığını görebiliyoruz.

>>> ast.dump(node_obj, annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE()], [Str('bar'), Str('baz')]))])"
>>> ast.dump(ast.parse("'foo' < 'bar' <= 'baz' >= 'quux'"), annotate_fields=False)
"Module([Expr(Compare(Str('foo'), [Lt(), LtE(), GtE()], [Str('bar'), Str('baz'), Str('quux')]))])"

Ve şu anda kabul edilen cevabın aksine, üçlü işlem, ilk ifadeyi alan, belirli karşılaştırmaların yinelemeli ve gerektiği gibi değerlendirmek için ifade düğümlerinin yinelenebilen genel bir karşılaştırma işlemidir. Basit.

Python Üzerine Sonuç

Kişisel olarak anlam semantiklerini oldukça şık buluyorum ve tanıdığım çoğu Python uzmanı, zarar vermeyi düşünmek yerine, özelliğin kullanımını teşvik edecektir - anlambilim, tanınmış belgelerde (yukarıda belirtildiği gibi) oldukça açık bir şekilde belirtilmiştir.

Kodun yazıldığından çok daha fazla okunduğunu unutmayın. Kodun okunabilirliğini artıran değişiklikler, Korku, Belirsizlik ve Şüphe'nin jenerik hayaletlerini artırarak indirgenmemelidir .

Öyleyse neden programlama dillerinde x <y <z yaygın olarak bulunmuyor?

Özelliğin göreceli önemine ve dil valilerinin izin verdiği değişimin göreceli momentum / ataletine odaklanan nedenlerin bir birleşimi olduğunu düşünüyorum.

Diğer daha önemli dil özellikleri için de benzer sorular sorulabilir.

Neden Java veya C # ile birden fazla devralma mevcut değil? Her iki soruya da iyi bir cevap yok . Belki de Bob Martin’in iddia ettiği gibi geliştiriciler çok tembeldi ve verilen sebepler sadece bahaneler. Ve çoklu kalıtım, bilgisayar bilimlerinde oldukça büyük bir konudur. Operatör zincirlemesinden kesinlikle daha önemlidir.

Basit geçici çözümler var

Karşılaştırma operatörü zincirleme zarif, ancak hiçbir şekilde çoklu kalıtım kadar önemli değildir. Ve Java ve C # 'nin bir geçici çözüm olarak arayüzleri olduğu gibi, çoklu dil karşılaştırmaları için her dilin yaptığı gibi - kolayca ve basit bir şekilde çalışan Boolean "ve" s ile yapılan karşılaştırmaları zincirlemelisiniz.

Çoğu dil komite tarafından yönetilir

Çoğu dil, komite tarafından gelişmektedir (Python'daki gibi makul bir Benevolent For Life Diktatörüne sahip olmak yerine). Ve bu konunun ilgili komitelerinden çıkarmak için yeterli destek görmediğini düşünüyorum.

Bu özelliği sunmayan diller değişebilir mi?

Bir dil x < y < zbeklenen matematiksel anlambilim olmadan izin verirse , bu kırıcı bir değişiklik olur. İlk etapta izin vermediyse, eklemek neredeyse önemsiz olurdu.

Değişiklikleri kırmak

Değişen değişiklikler içeren dillerle ilgili: Değişen davranış değişiklikleriyle dilleri güncelleriz - ancak kullanıcılar bundan hoşlanmaz, özellikle de kırılabilecek özellikler kullanıcıları. Bir kullanıcı önceki davranışına güveniyorsa, x < y < zmuhtemelen yüksek sesle protesto ederdi. Ve çoğu dil komite tarafından yönetildiğinden, böyle bir değişikliği desteklemek için çok fazla siyasi irade alacağımızdan şüpheliyim.


Doğrusu, o zihinsel eşlemek için bir geliştirici için önemsiz zincir karşılaştırma böyle `x <y <z` gibi işlemler ancak olduğuna dilleri tarafından sağlanan semantik ile hiçbir meseleyi x < y < ziçin (x < y) && (y < z). Sirkleri seçmek, zincirleme karşılaştırmanın zihinsel modeli genel matematiktir. Klasik karşılaştırma genel olarak matematik değil, Boole mantığıdır. x < yikili bir cevap üretir {0}. y < zikili bir cevap üretir {1}. {0} && {1}açıklayıcı cevap üretir. Mantık, saf olarak zincirlenmemiş bir biçimde oluşur.
K. Alan Bates

Daha iyi iletişim kurmak için, cevabı, tüm içeriği doğrudan özetleyen tek bir cümleyle öneriyorum. Uzun bir cümle, ben de mermilerden ayırdım.
Aaron Hall

2
Birkaç dilin bu özelliği uygulamasının kilit nedeni, Guido'dan önce kimsenin düşünmemiş olması. C'den miras kalan diller bunu şimdi "doğru" (matematiksel olarak doğru) alamıyor çünkü C geliştiricileri 40 yıl önce "yanlış" (matematiksel olarak yanlış). Orada, bu dillerin nasıl yorumlandığının karşı yönelimli yapısına bağlı olarak birçok kod var x<y<z. Bir dilin bir zamanlar böyle bir şeyi alma şansı vardır ve bu şansın dilin başlangıcında olmasıdır.
David Hammen

1
@ K.AlanBates 2 puan kazanıyorsunuz: 1) operatör zincirlemesi özensiz ve 2) sözdizimsel şekerin değeri yok. İlki: Operatör zincirinin% 100 deterministik olduğunu kanıtladım, değil mi? Belki bazı programcılar yapıyı anlama yeteneklerini genişletmek için zihinsel olarak tembeldir? İkinci noktaya: Bana okunabilirliğe karşı doğrudan tartışıyormuşsunuz gibi geliyor? Sözdizimsel şeker genellikle okunabilirliği arttırdığında iyi bir şey olarak düşünülmüyor mu? Bu şekilde düşünmek normal ise, neden bir programcı bu şekilde iletişim kurmak istemez? Kod okunmak için yazılmalıdır, hayır?
Aaron Hall

2
I have watched both Ruby and Python implement breaking changes.Meraklıları için
user2023861

13

Bilgisayar dilleri mümkün olan en küçük birimleri tanımlamaya ve bunları birleştirmenize izin verir. Mümkün olan en küçük birim, boolean bir sonuç veren "x <y" gibi bir şey olacaktır.

Üçlü bir operatör isteyebilirsiniz. Bir örnek, x <y <z olacaktır. Şimdi hangi operatör kombinasyonlarına izin veriyoruz? Açıkçası x> y> z veya x> = y> = z veya x> y> = z veya belki x == y == z girilmelidir. Peki ya x <y> z? x! = y! = z? Sonuncusu ne anlama geliyor, x! = Y ve y! = Z veya üçünün de farklı olduğu nedir?

Şimdi argüman promosyonları: C veya C ++ 'da argümanlar ortak bir türe yükseltilir. Öyleyse, x <y <z'nin anlamı x'in çift olduğu ancak y ve z'nin uzun uzun int olduğu? Üçü de ikiye katlanacak mı? Ya da y bir kez iki katı, diğer zaman ise o kadar uzun mu alınır? C ++ 'da operatörlerden biri veya her ikisi aşırı yüklenirse ne olur?

Ve son olarak, herhangi bir sayıda operata izin veriyor musunuz? Bir <b> c <d> e <f> g gibi?

Her şey çok karmaşıklaşıyor. Şimdi umursamadığım şey, sözdizimi hatası üreten x <y <z. Çünkü faydası, x <y <z'nin gerçekte ne yaptığını bulamayan yeni başlayanlara verilen zararla karşılaştırıldığında küçüktür.


4
Yani, kısacası, iyi tasarlanması sadece zor bir özellik.
Jon Purdy

2
Bu, iyi bilinen bir dilin neden bu özelliği içerdiğini açıklamak için bir neden değildir. Nitekim, iyi tanımlanmış bir dilde bir dilde dahil etmek oldukça kolaydır. Her operatörün ikili olması yerine, benzer tipte operatörler tarafından birbirine bağlanmış bir liste olarak görüntülenmesi meselesidir. Aynı şey x + y + z, herhangi bir anlamsal farklılık anlamına gelmeyen tek farkla, toplamlar için de yapılabilir . Demek ki, hiçbir zaman iyi bilinen bir dil bunu yapmaya özen göstermedi.
cmaster

1
Python'da, derlenmiş dillerin kendi yollarını optimize ettiğini hayal ettiğim bir optimizasyon (biraz x < y < zeşdeğer ((x < y) and (y < z))fakat ysadece bir kez değerlendirilmiş ) olduğunu düşünüyorum. “Çünkü faydası, x <y <z'nin gerçekte ne yaptığını bulamayan yeni başlayanlara verilen zararla karşılaştırıldığında küçük.” İnanılmaz derecede faydalı olduğunu düşünüyorum. Muhtemelen bunun için -1 olacak ...
Aaron Hall

Eğer birinin amacı, programcıların en aptallarına kafa karıştırıcı olabilecek her şeyi ortadan kaldıran bir dil tasarlamaksa, böyle bir dil zaten var: COBOL. Python'u kendim yazmayı tercih ettiğim yer a < b > c < d > e < f > golan "bariz" anlamı ile kullanmayı tercih ederim (a < b) and (b > c) and (c < d) and (d > e) and (e < f) and (f > g). Sırf bunun yazabileceğin anlamına gelmez. Bu tür canavarlıkları ortadan kaldırmak, kod incelemesinin amacıdır. Öte yandan, 0 < x < 8python ile yazmak , x'in 0 ile 8 arasında olduğu, özel olduğu anlamına gelir.
David Hammen

@DavidHammen, ironik, COBOL gerçekten bir <b <c izin veriyor
JoelFan

10

Birçok programlama dilinde, x < yiki operand'ı kabul eden ve tek bir boolean sonucu değerlendiren ikili bir ifadedir . Bu nedenle, eğer birden çok ifadeyi zincirlerseniz true < zve false < zmantıklı olmazsa ve bu ifadeler başarılı bir şekilde değerlendirilirse, yanlış sonuç vermeleri muhtemeldir.

İki parametre alan ve tek bir boolean sonuç üreten bir işlev çağrısıx < y olarak düşünmek çok daha kolaydır . Aslında, bu kadar dil onu kaputun altında uygular. Beste, kolay bir şekilde derlenebilir ve sadece çalışır.

x < y < zSenaryo çok daha karmaşıktır. Şimdi derleyici, aslında, moda zorundadır üç fonksiyonları: x < y, y < zve bu iki değerin sonucu bütün bir tartışmalı kapsamında bir araya anded belirsiz dil grameri .

Neden diğer yoldan yaptılar? Belirgin dilbilgisi olduğu için uygulaması çok daha kolay ve düzeltilmesi çok daha kolay.


2
Dili tasarlıyorsanız, doğru sonucu verme şansına sahipsiniz .
JesseTG

2
Elbette soruyu cevaplıyor. Eğer soru gerçekten nedense , cevabı "dil tasarımcılarının seçtiği budur." Bundan daha iyi bir cevap bulabilirseniz, bunun için gidin. Gnasher'ın cevabının ilk paragrafında esasen aynı şeyi söylediğini unutmayın .
Robert Harvey,

3
Yine saçları ayırıyorsun. Programcılar bunu yapma eğilimindedir. "Çöpü çıkarmak istiyor musun?" "Yok hayır." "Çöpü dışarı çıkarır mısın?" "Evet."
Robert Harvey

2
Ayrıca son paragrafa da itiraz ediyorum. Python zincir karşılaştırmalarını desteklemektedir ve ayrıştırıcısı LL (1). O değil mutlaka ya semantiğini tanımlamak ve uygulamak zor: Python sadece diyor e1 op1 e2 op2 e3 op3 ...eşdeğerdir e1 op e2 and e2 op2 e3 and ...her ifade sadece bir kez değerlendirilir olduğunu hariç. (BTW bu basit kuralın, a == b is Trueartık gibi ifadelerin artık amaçlanan etkiye sahip olmadığı kafa karıştırıcı yan etkiye sahiptir .)

2
@RobertHarvey re:answerBu, ana soru hakkındaki yorumum için aklımın hemen gittiği yerdi. x < y < zDil anlambilimine herhangi bir değer katmak için destek bulmuyorum. (x < y) && (y < z)daha geniş bir şekilde desteklenir, daha belirgin, daha etkileyici, bileşenlerine daha kolay sindirilir, daha karmaşık, daha mantıklı, daha kolay yeniden yapılandırılabilir.
K. Alan Bates

6

Çoğu ana dil (en azından kısmen) nesne yönelimlidir. Temel olarak, OO'nun temel prensibi, nesnelerin diğer nesnelere (veya kendilerine) mesaj göndermesi ve bu mesajın alıcısının , bu mesaja nasıl cevap vereceği üzerinde tam kontrol sahibi olmasıdır.

Şimdi, nasıl bir şey uygulayacağımızı görelim

a < b < c

Kesinlikle soldan sağa (soldan ilişkili) değerlendirebiliriz:

a.__lt__(b).__lt__(c)

Ama şimdi bunun __lt__sonucudur a.__lt__(b), ki bu bir Boolean. Bu hiç mantıklı değil.

Doğru ilişkisel deneyelim:

a.__lt__(b.__lt__(c))

Hayır, bu da mantıklı değil. Şimdi, biz var a < (something that's a Boolean).

Tamam, peki ya sentaktik şeker gibi davranıyorsun. Bir n <karşılaştırma zinciri yapalım, bir n-1 ary mesajı gönderelim. Bu bizim mesaj göndermek, anlamına gelebilir __lt__için a, geçen bve cbağımsız değişkenleri olarak:

a.__lt__(b, c)

Tamam, bu işe yarıyor, ama burada tuhaf bir asimetri var: adaha az olup olmadığına karar veriyor b. Ama bbu daha az olup olmadığına karar vermek almaz ckarar olduğunu bunun yerine, aynı zamanda yapılan a.

Peki ya bunu bir mesajın gönderileceği gibi yorumlamaya ne dersiniz this?

this.__lt__(a, b, c)

En sonunda! Bu işe yarayabilir. Bununla birlikte, nesnelerin sıralanmasının artık nesnenin bir özelliği olmadığı anlamına gelir (örneğin , ne mülkünün ne de özelliğinden aaz olup olmadığı ) bunun yerine bağlamın (yani ) bir özelliğidir .babthis

Bir garip bakış açısına göre garip görünüyor. Ancak, örneğin Haskell'de bu normaldir. Orada birden çok farklı uygulamaları olabilir Ord, örneğin typeclass, ve olsun veya olmasın aen az bir bkapsamda olması umulur typeclass örneği bağlıdır.

Ama aslında, hiç de garip değil ! Hem Java ( Comparator) hem de .NET ( IComparer), örneğin sıralama algoritmalarına kendi sipariş ilişkinizi enjekte etmenizi sağlayan arayüzlere sahiptir. Bu nedenle, siparişin bir türe göre sabit bir şey olmadığını, bunun yerine içeriğe bağlı olduğunu kabul ederler.

Bildiğim kadarıyla, şu anda böyle bir çeviri yapan dil yok. Bir öncelik Ancak, var: Her iki Ioke ve Seph onların tasarımcı "trinary operatörleri" dediği var - olan operatörler sözdizimsel ikili, ancak semantik üçlü. Özellikle,

a = b

olduğu değil mesajı göndererek olarak yorumlanır =için ageçen bargüman olarak değil, olduğu gibi mesaj göndererek ="Mevcut Ground" (benzer ama aynı değil bir konsepte this) geçen ave bargümanlar olarak. Yani, a = byorumlanır

=(a, b)

ve yok

a =(b)

Bu kolayca n-ary operatörleri için genelleştirilebilir.

Bunun gerçekten OO dillerine özgü olduğuna dikkat edin. OO'da, daima bir mesaj gönderisini yorumlamaktan nihayet sorumlu olan tek bir nesneye sahibiz ve gördüğümüz gibi, a < b < changi nesnenin olması gerektiği gibi bir şey için hemen belli değil .

Bu olsa da işlemsel veya işlevsel diller için geçerli değildir. Örneğin, Scheme , Common Lisp ve Clojure'da , <işlev n-ary'dır ve rastgele sayıda argümanla çağrılabilir.

Özellikle, <does not mean "az", daha doğrusu bu işlevler biraz farklı yorumlanır:

(<  a b c d) ; the sequence a, b, c, d is monotonically increasing
(>  a b c d) ; the sequence a, b, c, d is monotonically decreasing
(<= a b c d) ; the sequence a, b, c, d is monotonically non-decreasing
(>= a b c d) ; the sequence a, b, c, d is monotonically non-increasing

3

Sadece dil tasarımcılarının bunu düşünmediği veya iyi bir fikir olduğunu düşünmediği için. Python, basit bir (neredeyse) LL (1) gramer ile tanımladığınız gibi yapar.


1
Bu hala hemen hemen her ana dilde normal bir gramerle ayrıştırılacak; @RobertHarvey'in vermiş olduğu nedenden dolayı doğru anlaşılmayacak.
Mason Wheeler

@MasonWheeler Hayır, mutlaka değil. Kurallar, karşılaştırmaların diğer operatörlerle değiştirilebilir olması için yazılırsa (örneğin, aynı önceliğe sahip oldukları için), doğru davranışı alamazsınız. Python'un tüm karşılaştırmaları bir düzeye koyması, diziyi bir birleşim halinde ele almasına izin veren şeydir.
Neil G,

1
Pek sayılmaz. 1 < 2 < 3Java ya da C # 'ya koyun ve operatör önceliğiyle ilgili bir sorununuz yok; geçersiz türlerle ilgili bir sorununuz var. Mesele şu ki, tam olarak sizin yazdığınız gibi ayrıştırılacak, ancak bireysel karşılaştırmalar dizisinden zincirleme bir karşılaştırmaya çevirmek için derleyicide özel bir durum mantığına ihtiyacınız var.
Mason Wheeler

2
@MasonWheeler Demek istediğim, dilin çalışması için tasarlanması gerektiğidir. Bunun bir kısmı gramerin doğru olması. (Kurallar, karşılaştırmaların diğer operatörler ile birbiriyle değiştirilebilecek şekilde yazılması durumunda, aynı önceliğe sahip olduklarından, doğru davranışı alamayacağınızı söyleyin.) Bunun bir diğer kısmı, AST'yi bir C ++ olarak yorumlamaktır. yapmaz. Cevabımın asıl amacı bir dil tasarımcının kararı olduğu.
Neil G,

@MasonWheeler Sanırım aynı fikirdeyiz. Sadece bunun için dilbilgisini elde etmenin zor olmadığını vurguladım. Sadece bu şekilde çalışmasını istediğine karar vermek meselesi.
Neil G,

2

Aşağıdaki C ++ programı, en yüksek seviyeye ayarlanmış uyarılar da dahil olmak üzere, nary clang dan bir dikizlemekle derlenir -Weverything:

#include <iostream>
int main () { std::cout << (1 < 3 < 2) << '\n'; }

Diğer taraftan gnu derleyici paketi bu konuda beni uyarıyor comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses].

Öyleyse benim sorum şudur: x <y <z programlama dillerinde, beklenen anlambilimiyle neden yaygın olarak bulunmuyor?

Cevap basit: Geriye dönük uyumluluk. Doğada eşdeğerini kullanan 1<3<2ve sonucun gerçek olmasını bekleyen çok sayıda kod vardır .

Bir dil tasarımcısının bu "doğru" olma şansından başka bir şansı yoktur ve bu, dilin ilk tasarlandığı zamanın noktasıdır. Başlangıçta "yanlış" olması, diğer programcıların bu "yanlış" davranıştan hızlıca faydalanacakları anlamına gelir. İkinci kez "doğru" olarak almak, bu mevcut kod tabanını kıracak.


+1 çünkü bu program matematikte açıkça yanlış olan bir ifadenin sonucu olarak '1' değerini veriyor. Buna rağmen, bu dil özelliği eklendiyse anlaşılmaz değişken isimlerine sahip gerçek dünyadan bir örnek, hata ayıklama kabusu olur.
Seth Battin

@SethBattin - Bu Python'da bir hata ayıklama kabusu değil. Python'daki tek sorun if x == y is True : ..., benim görüşüme göre: Bu tür bir kodu yazan insanlar, (şimdi yaşıyor olsaydı) Torquemada'nın kendisinin soluk hale getireceği, çok özel, olağanüstü bir işkenceye maruz kalmayı hak ediyorlar.
David Hammen
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.