Neden diller mantıksal bir işleç olarak ima içermiyor?


60

Garip bir soru olabilir, ancak neden birçok dilde mantıksal bir operatör olarak ima edilmediği (Java, C, C ++, Python Haskell - en sonuncusu kullanıcı eklemek için operatörleri tanımlamasına rağmen). Mantıksal çıkarımın (özellikle iddialarda veya iddiaya benzer ifadelerde) yazmaktan sonra daha net veya daha olumsuz buluyorum:

encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}

28
Çünkü C'ye girmedi; eğer konulsaydı o zaman C ++, Java ve C # olurdu.
m3th0dman

4
Fakat C buna sahip değil, çünkü meclis dilinin ortak bir parçası değil. Oysa bildiğim tüm komut kümeleri olarak dahil ettim ya da etmeyin, ima eden hiçbir şey olmadığını biliyorum - kısa bir süre önce belirsiz olan bazı belirsiz talimatlar setini bana söyleyecek kadar şüphesiz ...
Jack Aidley

4
Belki gereksiz olduğu için kabul edildi, çünkü (1) "^", "v", "~", (2) 'den daha az ilkeldir; .
Giorgio

4
Mantıksal yapıları ele alan dillerin buna sahip olma olasılığı daha yüksektir. Bunlar arasında Başlıca prolog var

9
assert# 1'in 2'den daha net olduğunu düşünmene şaşırdım . Bir süredir 1 numaraya baktım ve davranışının sezgisel olarak nasıl değerlendirilebileceğini hala göremiyorum. (özellikle ekstra !=mantık saygısız)
Chris Burt-Brown

Yanıtlar:


61

Hiç şüphesiz, bazen yararlı olabilir. Böyle bir operatöre karşı birkaç nokta öne çıkıyor:

  • Karakterleri -ve >izolasyon ve kombine hem değerlidir. Birçok dil onları zaten başka şeyler ifade etmek için kullanıyor. (Ve çoğu, sözdizimleri için unicode karakter kümelerini kullanamaz.)
  • Uygulama, mantık düşünen insanlar için bile programcılar gibi çok sezgiseldir. Dört doğruluk tablosu girişinden üçünün gerçeği truebirçok insanı şaşırttı.
  • Diğer tüm mantıksal operatörler simetriktir ve bu da ->diklik için bir istisna yapar.
  • Aynı zamanda, kolay bir geçici çözüm vardır: işleçleri !ve ||.
  • İması mantıksal daha az sıklıkla büyük ölçüde kullanılır and/ ' or.

Muhtemelen bu nedenle operatör bugün nadirdir. Yeni dinamik diller her şey için Unicode kullandığından ve operatörün aşırı yüklenmesi tekrar daha moda hale geldiğinden, kesinlikle daha yaygın hale gelebilir.


22
İlk noktanız, operatöre sahip olmaktan ziyade, operatörün sembolü olarak '->' kullanılmasına karşı çıkıyor. Diğerleri iyi noktalar.
AShelly

14
"Aynı zamanda, kolay bir geçici çözüm var: kullanın! Ve &&.": Aslında, "->" (veya "=>" ifadesini simüle etmenin en basit yolu, Math'da daha yaygın olduğu gibi) kullanmaktır. !ve ||, !ve ve &&: A -> Beşdeğer !A || Bolana eşittir !(A && !B).
Giorgio

22
“Dört doğruluk tablosu girişinden üçünün gerçek olması, birçok insanı şaşırttı” Wat. Ben sık sık kullanılan aynı özelliklere sahip başka bir operatör biliyorum ...
l0b0

9
@ l0b0, CS eğitimi alan bir programcıyım, ancak uzun zaman önceydi. "İma etmenin" gerçek bir değer veren iki işleci olan resmi bir işlem olduğunu unutmuştum, bu yüzden ilk başta bu sorunun mahiyetinde aklım karıştı. Her gün yapılan konuşmada, ilk işlenenin zaten doğru olduğu biliniyorsa, yalnızca “imaları” kullanıyorum (“X doğru, yani Y doğru olmalı”). Bir dakika sonra, formal "ima" nin nasıl çalıştığını hatırladım, ama gerçek şu ki - bir zamanlar resmi mantık inceleyen biri için bile, niyet bana açık değildi. Ve daha önce hiç çalışmasaydım, nihayetinde bile mantıklı gelmezdi.
Ben Lee,

5
(a) C -> operatör olarak kullanılır. Kimse bundan şikayet etmiyor. Yine de => kullanırdım. (b) Kime karşı sezgisel? Uygulama tanımı sadece bir tanımdır. (c) çıkarma, değişmeli değildir. Kimse bundan şikayet etmiyor. (d) Sanırım demek istiyorsun! ve || Öncelik nedeniyle (ve) de sıklıkla ihtiyaç duyulur. Aynı argüman && veya ||; istediğini al. (e) Belki de bunun nedeni çoğu dilde olmamasıdır. Birçok kullanım alanı || kesin ve (en azından benim için) sezgisel olarak ima ile ikame edilebilir.
Theodore Norvell

54

Cevabın matematik temellerinde olduğuna inanıyorum . Uygulama genellikle, boole cebirlerinin türetilmiş, temel olmayan bir işlemi olarak kabul edilir ve tanımlanır. Programlama dilleri bu sözleşmeyi izler.

Bu, George Boole'un Düşünce Yasalarını İncelemesi'nden (1854) II. Bölümün Teklifi :

Dilin tüm işlemleri, bir muhakeme aracı olarak, aşağıdaki unsurlardan oluşan bir işaretler sistemi ile yapılabilir:

1 inci. X, y ve c gibi değişmez semboller, kavramları anlayışımızın özneleri olarak gösterir.

2. +, -, × gibi operasyon işaretleri, aynı unsurları içeren yeni kavramlar oluşturacak şekilde şeylerin kavramlarının bir araya getirildiği veya çözümlendiği operasyonlar için geçerlidir.

3 üncü. Kimlik işareti, =.

Ve bu Mantık sembolleri, kullanımlarında, Cebir bilimindeki ilgili sembollerin yasalarına kısmen katılıyor ve kısmen onlardan farklı olan, belirli yasalara tabidir.

Boole'nin işareti +, bugün hem boole ya da kümeler birliği olarak tanıdığımız aynı "akıl işlemini" temsil ediyor. Benzer şekilde, - ve × işaretleri, bir ihmal, bir kümenin tamamlayıcısı, bir 'tamam' ve kümelerin kesişimine karşılık gelir.


+1 - katı cevap. Boole cebri ve mantıktaki basitleştirmeler, bir çok programlama metodolojisine olanak tanımaktadır. Bir "imalar ..." kullanmak potansiyel olarak "umursamıyorum" koşullarına müdahale edecektir.

3
1. Bu tanımlamaya bağlıdır. a || b = !(!a && !b)(Veya mantıkta türetilmiş operatör olarak tanıştım) veya gibi tanımlamak mümkündür . 2. Yapılmasının nedeni, genellikle indüksiyonu basitleştirmek, inandığımı kanıtlıyor (türetilmiş operatörlerin sadece kısa yollar olduğunu biliyoruz, bu yüzden onlar için ayrı bir davaya ihtiyacımız yok). @ GlenH7: Hangi "umursamıyor" koşulları? a --> baynıdır !a || b.
Maciej Piechotka

3
Ayrıca - xor ( !=) nxor ( ==) ... gibi diğer türetilmiş operatörlerimiz var ...
Maciej

5
Aslında her şeyi NAND !(a && b)veya NOR'dan türetebilirsiniz !(a || b). Örneğin, NOT a == a NAND a, a AND b == NOT(a NAND b), a OR b == (NOT a) NAND (NOT b). Ancak yalnızca bir NAND operatörü sağlamak sizi, ezoterik diller alanına koyar (ki bu, yanıtlayıcının kullanıcı adı ;-) verildiğinde şaşırtıcı derecede iyi uyuyor).
Stefan Majewsky

1
@Stefan: Her şeyi bir IMPL'den de türetebilirsiniz.
Mason Wheeler

37

GÜNCELLEME: Bu soru Kasım 2015'teki blogumun konusuydu . İlginç soru için teşekkürler!


Visual Basic 6 (ve VBScript) Impve Eqvoperatörleri vardı . Kimse onları kullanmadı. Her ikisi de VB.NET'te çıkarıldı; bildiğim kadarıyla kimse şikayet etmedi.

Bir yıl boyunca Visual Basic derleyici ekibinde (stajyer olarak) çalıştım ve VB'nin bile bu operatörlere sahip olduğunu asla farketmedim. VBScript derleyicisini yazan adam olmasaydım ve bu yüzden onların uygulamalarını test etmek zorunda kalsaydım, muhtemelen onları farketmezdim. Derleyici ekibindeki adam bu özelliği bilmiyorsa ve kullanmıyorsa, bu özelliklerin popülaritesi ve kullanışlılığı hakkında bir şeyler söyler.

C benzeri dillerden bahsettiniz. C veya C ++ veya Java ile konuşamıyorum, ancak C # ile konuşabiliyorum. C # için kullanıcı tarafından önerilen özelliklerin bir listesi var. Bildiğim kadarıyla, hiçbir kullanıcı C # ekibine böyle bir operatör önermedi ve birçok kez bu listeyi gözden geçirdim.

Bir dilde var olan ve kullanılmayan ve bir başkasında asla talep edilmeyen özellikler, modern programlama dilleri haline getirme olasılığı düşük olan adaylardır. İnsanlar özelliklerini yapmak için bütçede yeterli zaman ve çaba ve para olmadığı Özellikle zaman yok istiyorum.


IMP, operatör olarak GWBASIC günlerine geri döndü. 1979'dan hatırlıyorum.
zarchasmpgmr

1
IMPL'nin kod sözleşmelerinde çok faydalı olduğunu okudum. (Hangi VB'de yoktu.)
Mason Wheeler

3
VBScript programcıları muhtemelen böyle bir operatörü kullanma olasılığı en az olan gruptu. Şu anda PowerShell'in bir ima işlem operatörü olmasını diliyorum, böylece bazı [switch]filtre parametrelerini daha kolay ve okunaklı bir şekilde uygulayabiliyorum .
brianary

IMP'yi DEC BASIC'ten hatırlıyorum. Ben hatırlamıyorum EQV. Sık sık istediğim operatör, "sağ değil" olacaktır, bu da, sağ operatörün, olumsuzlamadan önce tanıtımını yapacaktır. Böylece, 0xABCD12345678ul ~& 0x00200000u0x12145678ul yerine 0xABCD12145678ul elde edilir.
supercat,

19

Sadece tahmin edebilirim ama bunun bir nedeni, oldukça basit ve okunabilir geçici çözümler olabilir. Örnek olarak düşünelim:

if (mode != ECB) assert (iv != null);

assert (mode != ECB --> iv != null);  // <-- that's only one character shorter

Bir ifadeye ihtiyacınız varsa, çoğu dilde mevcut olan satır içi if operatörü (genellikle üçlü operatör adı verilir) kullanılabilir. Verilen, bu kadar şık değildir A --> B, ancak kullanım durumlarının sayısı başka bir operatör eklemek (ve sürdürmek!) Haklı göstermeyebilir:

assert (mode != ECB ? iv != null : true);

2
İddia olarak - iyi bir sebep var. Birincisi (birçok uygulamada) "onaylama hatası: iv! = Null" mesajı, ikincisi "onaylama hatası: mode! = ECB -> iv! = Null" mesajı çıkar.
Maciej Piechotka

2
+1, bu soruyu aynı soruyu sormak üzereydim ("uygulama" ile ilgili fazla bilgi sahibi olmadığımdan asla gündeme gelmez). Bu ififade hemen hemen herkes için çok daha açık.
Izkata

12

Eyfel Uygulaması Var

Aslında daha da fazlası var. Çok sayıda yarı sıkı operatöre sahiptir.

Programcıların bu tür şeyleri kullanmamasının nedeni, asla ne olduklarını, nasıl kullanacaklarını ve ne zaman kullanacaklarını ve onlarla nasıl tasarlanacaklarını tam olarak bilmek konusunda eğitilmemeleridir. Asla eğitilmedikleri için, derleyici yazarlarından asla istemezler, bu yüzden derleyici bu tür mekanizmaları derleyiciye koymaktan rahatsız olmaz. Computer Science öğrencileri ve Gölge ağacı programcıları daha kapsamlı bir eğitim almaya başladıklarında, derleyiciler yetişmeye başlayacaktır.

Böyle Boole işleçleriyle bir diliniz olduğunda ve onlarla nasıl tasarım yapıp bunları nasıl kullandığınızı bildiğiniz, sonra onları kullandığınız anlaşılıyor.

Eyfel'de, "ima edilen" anahtar kelimenin kullanımı, sözleşme iddialarının Boole ağır yapısı nedeniyle Sözleşme-Tasarım nedeniyle oldukça belirgindir. Sadece "ima edilen" işleçle düzgün ve verimli bir şekilde yazılabilecek bazı sözleşmeler var. Bu daha sonra anlaşmasız dillerin, ima etme kullanımını incelemeye, eğitmeye ve uygulamaya neden olmadan da daha fazla olduğu yorumuna yalvarır.

Buna ek olarak, çoğu programcının "matematik ve mantık açısından zayıf" olduğunun da bize hikayenin geri kalanını anlattığını ekleyin. Eğitiminizde matematik ve mantık ağırlıklı olsanız bile, bir kişi uygulama gibi yapıları uygulamayan bir dil seçtiğinde, o zaman bu tür şeylerin gereksiz ya da kullanışlı olmadığını düşünmeye meyillidir. Bunlardan biri nadiren dili sorgular ve şöyle bir yankı odasına girer: "Peki derleyici insanlar ihtiyacı görmez" ve "Eh, programcılar ihtiyacı görmez" - sonsuz ve kısır döngü.

Bunun yerine, derleyici insanların, yıkanmış programcı kitlelerinin ne düşündüklerinden veya ne istediklerinden bağımsız olarak teori tarafından desteklenmeleri, teori tarafından önerilen veya ima edilen bir dil notasyonu yazmaları gerekir (örn. Nesne Yönelimli Teori). Oradan, profesörlerin, öğretmenlerin ve diğer profesyonellerin "teoriyle mercek kuramı" DEĞİL, ham teoriye dayalı genç beyinleri ustaca eğitmeleri gerekir. Bu gerçekleştiğinde, insanlar aniden uyanacak ve neyin eksik olduğunu ve onlara neyin çarpıldığını anlayacaklardır.

Şu anda, orada Nesne Yönelimli olarak maskelenen çok fazla teori var, ancak sadece [O'nun içinden] bir camdan karanlıkta OO'su]. Biri OO'daki çoğu "teori" kitabını okuyamaz çünkü teorinin ne olduğunu bir dilin lensinden yorumlamak isterler. Tamamen yanlış ve yanlış. Hesap makinesinde matematik temelli hesaplamayı veya slayt kuralımı öğretmek gibi olur. HAYIR - kişi gerçekliğin kendisine bir şey öğretmesine izin verir ve daha sonra ne gözlemlediğini tarif etmek için bir not kullanır - buna "bilim" denir. OO'nun dilden diline dayalı X adlı diğer püre de gerçeği zar zor temsil edecek kadar çarpık.

Bu yüzden dilden uzaklaşın, ham teoriye bakın ve tekrar başlayın. Bir dilin sınırlamaları, kısıtlamaları ve boya işlerinin size teorinin ne olduğunu söylemesine izin vermeyin. Basitçe, teorinin gerçekliğinin kendi göstergesini dikte etmesine izin ver ve sonra oradan bir dili formüle et.

Oradan, ima etmenin ve "ima etmenin" sadece yararlı değil, aynı zamanda şık ve çok havalı olduğunu da anlamaya başlayacaksınız!

İyi günler!


7

Python, bir çeşit gizli şekilde uygulama operatörüne sahiptir.

Eşit değerin altında olan operatör, boolean değerleri kabul etmek için aşırı yüklenmiştir. Sonuç olarak, kişi bunu bir uygulama operatörü olarak kullanabilir.

Örnekle Kanıt (Python Kodu):

print (False <= False) # This will print True.
print (False <= True)  # This will print True.
print (True <= False)  # This will print False.
print (True <= True)   # This will print True.

Uygulama operatörünün doğruluk tablosunu hatırlayın:

LEFT RIGHT RESULT
F    F     T
F    T     T
T    F     F
T    T     T

2
Bu harika, fakat maalesef yanlış katılık özellikleri vardır: f() implies g()değerlendirmek gerekir g()eğer f()olduğunu False, ancak <=değerlendiriyor g()bu durumda.
Jon Purdy

2
@Jon Purdy - Açıkçası, kısa devre değerlendirmesi ikili operatörlerin isteğe bağlı bir özelliğidir. Bu yüzden teknik olarak, bu uygulama operatörünün tamamen meşru bir uygulamasıdır. Söylendiği gibi, Guido van Rossum'un bunu bir uygulama operatörü olarak bile kullandığından şüpheliyim. Bu sadece boole'leri karşılaştırmanın bir tutamı.
Mackenzie

Elbette, bunun ilginç bir gözlem olduğunu söyledim, ancak gerçek programlarda kullanmanız gereken bir şey değil çünkü kısa devre yapmıyor ve çalışmayı umarsa birisini şaşırtabilir did_all_possible_stuff = x.do_required_stuff() and (x.supports_optional_stuff() <= x.do_optional_stuff()).
Jon Purdy

2
Bu, C ve C ++ 'da da çalışır.
Ben Voigt

5

Eiffel'in "ima eden" bir operatörü var ve ön ve son şartlarını yazmak için çok güzel. Bu, kodu daha okunaklı kılar, ne yazık ki bu, C benzeri dil için asla temel bir amaç değildir ve çok az kişi eiffel kullanmıştır;


2

Benim için, ima edilen büyük sorun, başlangıç ​​koşulunun yanlış olduğu zaman ortaya çıkıyor; örneğin: "Güneş yeşilse, o zaman meyve sopasıyım." Doğru!

Resmi mantıkta, uygulamanın koşulu karşılanmadığında değere "Doğru" atanması yeterlidir. Ancak programlamada, bu sezgisel ve şaşırtıcı sonuçlara yol açabilir.

Aslında @Heinzi örneğinin yukarıda verdiğini düşünüyorum:

if (sun.color() == "green") then assert(me.species() == "fruitbat")

Mantığı yanlış anlaması nedeniyle anlaşılması çok daha kolay ve hatalara daha az eğilimli.

Test bağlamında, varsayımlarım yanlış olduğu anda durdum:

assert(sun.color() == "green")
assert(me.species() == "fruitbat")

Öyleyse, @Eric Lippert'in amacına göre, bir programcı olarak ne zaman bir ima operatörü kullanacağımı bilmiyorum. "Yanlış, Doğru" davranışı matematiksel, biçimsel mantık bağlamında faydalı görünmektedir, ancak program mantığında beklenmeyen sonuçlara yol açabilmektedir.

...

Kimse ortak "?" Den bahsetmedi. operatör, "A? B: true", "ima" ile aynıdır. Ancak biçimsel mantık "başkası" koşuluna "aittir" iken? geliştiricinin bunu açıkça atamasına izin verir.

Biçimsel mantıkta, "true" kullanımı işe yarar, ancak programlamada, koşul yanlışsa, daha iyi cevap "boş" veya "geçersiz" veya "atlamak", hatta belki yanlış olabilir.

Birisinin "niçin" in "?" Veya "if" ifadelerinden ya da sadece düzenli program akışından daha faydalı bir operatör olduğu konusunda dava açması gerektiğini düşünüyorum.


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.