Czy jest jakiś powód, dla którego większość języków programowania nie ma operatorów „!>” (Nie więcej niż) i „! <” (Nie mniej niż)?

28

Zastanawiam się, czy istnieje jakikolwiek powód - lub, jeśli jest to tylko przypadek historyczny - że nie istnieją !>i !<operatorzy w większości języków programowania?

a >= b (większa OR równa się b) może być zapisana jako !(a < b) (NIE mniejsza b) , która równa się a !< b.

To pytanie uderzyło mnie, gdy byłem w trakcie kodowania własnego konstruktora drzewa wyrażeń. Większość języków programowania ma a != boperatora !(a=b), więc dlaczego nie !>i !<?

AKTUALIZACJA:

  • !<(nie mniejszy) jest łatwiejszy do wymówienia niż >=(większy lub równy)
  • !<(nie mniejszy) jest krótszy do wpisania niż >=(większy lub równy)
  • !<(nie mniej) jest łatwiejszy do zrozumienia * niż >=(większy lub równy)

* ponieważ ORjest operatorem binarnym, twój mózg musi operować dwoma operandami (większa, równa), podczas gdy NOTjest operatorem jednoargumentowym i twój mózg musi operować tylko jednym operandem (mniejszym).

Alex Burtsev
źródło
3
To nie koniecznie łatwiej wymówić w każdym języku. Na przykład w języku niemieckim mówimy „größer / gleich”, nigdy nie słyszałem „nicht kleiner”.
Ingo
1
Łatwiej zrozumieć argument nie wytrzymuje albo. W obu przypadkach musisz operować 2 operandami, ponieważ jest to normalne w przypadku operatorów relacyjnych. Co więcej, po prostu zakładasz, że mózg może łatwiej operować 1 operandem zamiast 2. Czy masz na to jakieś dowody z dziedziny neuronauki?
Ingo

Odpowiedzi:

84

Język programowania D i rozszerzenie DMC do C i C ++ wspierały te operatory (wszystkie 14 ich kombinacji), ale co ciekawe, D zamierza wycofać te operatory , głównie dlatego, że

  1. co to dokładnie jest a !< b? Jest a>=b || isNaN(a) || isNaN(b). nie!< jest tym samym, co , ponieważ jest prawdą, podczas gdy fałszem. IEEE 754 jest trudny do opanowania, więc używanie do spowoduje po prostu zamieszanie związane z obsługą NaN - możesz wyszukiwać takich operatorów w Phobos (standardowa biblioteka D), a całkiem sporo zastosowań ma komentarze, które przypominają czytelnikom, że NaN jest zaangażowany,>=NaN !< NaNNaN >= NaNa !< b
  2. dlatego niewiele osób będzie z niego korzystać, nawet jeśli operatorzy tacy jak w D,
  3. i trzeba zdefiniować jeszcze 8 tokenów dla tych rzadko używanych operatorów, co komplikuje kompilator z niewielką korzyścią,
  4. i bez tych operatorów nadal można użyć ekwiwalentu !(a < b), lub jeśli ktoś chce być wyraźny a >= b || isNaN(a) || isNaN(b), i są łatwiejsi do odczytania.

Poza tym relacje (≮, ≯, ≰, ≱) rzadko są postrzegane w podstawowej matematyce, w przeciwieństwie do !=(≠) lub >=(≥), więc dla wielu osób trudno je zrozumieć.

Są to prawdopodobnie również powody, dla których większość języków ich nie obsługuje.

kennytm
źródło
seldomly seen in basic math- bardziej jak nigdy. Uczymy się w algebrze, aby po prostu przerzucić ją na matematycznie równoważną (zwłaszcza, NaNże nie pojawia się w podstawowej matematyce)
Izkata
To, co naprawdę jest potrzebne, to metoda deklarowania zmiennych, które zachowują się jako double wyjątki od swoich NaNzachowań. W wielu przypadkach kod, który może wykonać dowolne porównanie, NaNbędzie chciał NaNporównywać większe niż wszystko, porównywać mniejsze niż wszystko lub rzucać wyjątek przy próbie porównania. Zezwolenie kodowi na deklaratywne określenie sposobu, w jaki NaNnależy go traktować, zmniejszyłoby potrzebę użycia kodu imperatywnego w celu osiągnięcia poprawnego zachowania.
supercat
@ superupat: Możesz wykonywać operacje NaN w celu zgłaszania wyjątku za pomocą <fenv.h>funkcji takich jak fesetexceptflag.
kennytm
@KennyTM: Konieczność ustawienia flagi przed wykonaniem operacji i rozbrojenia po niej wydaje się być trudna i podatna na awarie, i nie rozwiązuje problemu możliwości narzucenia całkowitego zamówienia. Z tego, co rozumiem, IEEE wprowadziło właśnie kilka nowych metod porównywania, które narzucą całkowity porządek, co uważam za mile widziane, jeśli zmiana będzie opóźniona; ciekawie będzie zobaczyć, jak zareagują języki.
supercat
47

Ponieważ nie ma sensu mieć dwóch różnych operatorów o dokładnie tym samym znaczeniu.

  • „Nie większy” ( !>) jest dokładnie taki sam jak „mniejszy lub równy” ( <=)
  • „Nie mniejszy” ( !<) jest dokładnie taki sam jak „większy lub równy” ( >=)

Nie dotyczy to „nie równa się” ( !=), nie ma operatora o tym samym znaczeniu.

Tak więc modyfikacja sprawiłaby, że język byłby bardziej skomplikowany bez żadnych korzyści.

svick
źródło
5
Co o x = x + 1, x += 1i x++?
33
@dunsmoreb: Żaden z nich nie jest tym samym. Tylko jeden służy celowi „przyrostu”. Fakt, że wykorzystałeś pozostałe dwa wyrażenia do tego samego celu, jest nieistotny - oba są znacznie bardziej ogólne.
DeadMG,
1
<>jest operatorem o takim samym znaczeniu jak !=, a Python 2 ma oba.
krlmlr
9
@ user946850 i mające obie są obecnie powszechnie uważane za błąd, stosowanie <>została zaniechana przez długi czas i jest usuwana od 3.0 (a przeszkadza ci ostatni release 2.x kiedykolwiek , 2,7, został wydany w lecie 2010 roku).
3
@svick Co sprawia, że ​​operator ++ jest jeszcze bardziej genialny, uniemożliwi to programistom C # przyjście tutaj, racjonalne założenia dotyczące zachowania programu, a następnie kradzież mojej pracy programisty C ++!
10

!<jest synonimem >=. Później to tylko sposób na wpisanie dobrze zdefiniowanego symbolu matematycznego . Masz rację, że w języku mówionym używa się słowa „nie mniej niż” , ale jest ono potoczne i może być dwuznaczne (może być interpretowane lub interpretowane jako >). Z drugiej strony programowanie i matematyka wykorzystują jasno zdefiniowaną, jednoznaczną terminologię.

Nawet w logice 3 wartości, takich jak ANSI SQL, not x < yjest równoważne x >= y, ponieważ dadzą NULLjeżeli jeden xlub yjest NULL. Istnieją jednak dialekty SQL niezgodne z ANSI, w których nie są one równoważne, i tak jest!< .

vartec
źródło
10
Zazwyczaj nie są one jednak równoważne przy użyciu liczb zmiennoprzecinkowych. Na przykład porównywanie czegokolwiek NaNjest fałszywe, więc !(2 < NaN) == truepóki (2 >= NaN) == false.
hammar
@hammar: To prawda, ale dotyczy to wszystkich relacji arytmetycznych wokół NaNs. Wszystkie przestają się normalnie zachowywać.
Nicol Bolas,
@hammar - jest to błąd zmiennoprzecinkowy, po prostu niepoprawnie implementuje porządek, że tak powiem. Nie jest to jednak duży problem, ponieważ nikt nie zmusza nas do wdrożenia a !< b = not (a < b), moglibyśmy po prostu powiedzieć (! <) = (> =).
Ingo
8

Transact-SQL ma !> (Nie większy niż) i ! <(Nie mniej niż) operatorów.

Tak więc, oprócz ciebie, ktoś w Sybase Microsoft również pomyślał, że to byłby dobry pomysł. Podobnie jak Microsoft Bob! :)

Yannis
źródło
Czy nie dodano tego w wersji 2005?
JeffO
5
na świecie jest wielu szalonych, źle poinformowanych ludzi, którzy nie są sami w zgodzie ze sobą, konsensus! = poprawność.
@JeffO Więc powinniśmy winić Microsoft, a nie Sybase?
yannis
Ciekawy. Jestem ciekaw historii, która się za tym kryje.
surfasb
@surfasb Tak, ja też. Domyślam się, że to tylko cukier syntaktyczny, nic specjalnego.
yannis
4

Myślę, że odpowiedź brzmi: po prostu nie ma potrzeby !<operatora. Jak podkreślił w swoim pytaniu nie ma już >=i <=wraz z możliwością zanegować istniejący wyraz, więc dlaczego dodać innego operatora?

Bryan Oakley
źródło
Zgadzam się, że dodawanie operatora, który robi to samo, nie ma sensu, ale dlaczego „oni” wybrali> = zamiast! <, O wiele łatwiej jest wymówić NOT LESSER, to WIĘCEJ LUB RÓWNIEŻ, krótsze jest pisanie, łatwiej jest mózg do zrozumienia.
Alex Burtsev
!<nie jest krótszy do pisania niż >=, czy coś mi brakuje?
Bryan Oakley,
Miałem na myśli to przedstawienie tekstu (wymowy tekst).
Alex Burtsev
4

Od RFC 1925

doskonałość została osiągnięta nie wtedy, gdy nie ma już nic do dodania, ale kiedy nie ma już nic do zabrania.

Dodanie dodatkowych operatorów, które powielają istniejącą funkcjonalność, nie robi nic innego, niż tylko (niepotrzebną) złożoność języka (a tym samym tokenizera i parsera).

Rozważ również w językach, w których możliwe jest przeciążenie operatora, miałbyś jeszcze jednego operatora do przeciążenia. Rozważ zamieszanie, kiedy bool operator<=i bool operator!>może zwrócić różne rzeczy (tak, wiem, że można już dokonać niespójnych porównań).

Na koniec pomyśl o językach, w których metody lub operatory są wielokrotnie zdefiniowane (Ruby - patrzę na ciebie ) i masz jednego programistę, który używa <= podczas gdy inny używa!> I masz wiele stylów kodu dla tego samego wyrażenia.


źródło
Tak! To zasada naukowego parsimony.
luser droog
3

! <jest równe> = Teraz mamy drugi, a nie pierwszy, ponieważ wszystkie języki najpierw implementują operator dodatni, a następnie podejście do operatora ujemnego, ponieważ implementacja> = obejmuje również! <i <= obejmuje!>. i pomyślał, że będą zbędni i pominą ich.

Zawsze najpierw próbuj zaimplementować przypadek pozytywny, a następnie przejdź do przypadku negatywnego (:) pozytywne myślenie, tylko dla mnie widok osobisty)

Notatnik
źródło
2

Powodem jest to, że operatorzy w językach programowania zapożyczają się z tradycji matematycznej, a w matematyce nikt tak naprawdę nie używa „nie większych” i „nie mniejszych”, ponieważ „mniejszy lub równy” i „większy lub równy” wykonują równie dobrą robotę.

Tak więc w językach programowania zwykle otrzymujemy symbol wyglądający jak ≠ dla nie równy ( !=lub /=, chyba że ktoś ma ochotę <>lub operator tekstowy)

i rzeczy, które wyglądają jak ≤ i ≥ ( <=i >=)


Przy okazji, nie zgadzam się z twoim twierdzeniem, że NIE jest łatwiejsze do zrozumienia i uzasadnienia na temat LUB. W matematyce dowody zawierające wiele negacji (jak redukcja do absurdu) są zwykle odrzucane, jeśli istnieje bardziej bezpośrednia alternatywa. Ponadto w przypadku zamawiania podstawową wiedzą, którą posiadamy (i która jest wykorzystywana podczas myślenia lub udowadniania czegoś), jest trikotomia pomiędzy <, = i>, więc dowolne wyrażenie! <Prawdopodobnie należy przekonwertować na> =, jeśli chcesz to zrobić cokolwiek przydatnego z tym.

hugomg
źródło
2

Częściowo winiłbym zestaw instrukcji montażu. Masz instrukcje takie jak jge„skacz, jeśli większy lub równy”. W przeciwieństwie do „skoku, jeśli nie mniej niż”.

Autorzy kompilatora mogli odejść od tego, co wymyślili autorzy asemblera, co prawdopodobnie opierało się na tym, jak zostało oznaczone przy projektowaniu na chipie.

...możliwie.

Ed Marty
źródło
1

Wydaje mi się, że kilka lat temu widziałem kilka języków, w których zamiast !=operatora (nie równego) <>użyto czegoś podobnego . Nie pamiętam jednak ich nazw ...

Myślę, że jest to trudniejsze do odczytania !(a < b)lub a !< bnie a >= b. Prawdopodobnie to jest powód, dla którego !<nie jest używany (moim zdaniem wygląda brzydko).

Radu Murzea
źródło
1
<>jest (był?) używany głównie przez dialekty BASIC, SQL i Pascal.
yannis
@Yannis Rizos dzięki za przypomnienie. Nauczyli nas Pascala w liceum i tam to zobaczyłem :).
Radu Murzea
2
Python 2 również <>, chociaż został usunięty w wersji 3.
Daniel Lubarov
Z logicznego punktu widzenia !=jest bardziej ogólny niż <>, ponieważ można mieć rzeczy (takie jak liczby zespolone), w których równość jest dobrze zdefiniowana, ale tak naprawdę nie ma użytecznej kolejności.
David Thornley