Есть ли ключевое слово или оператор для «ни»?

56

Есть ли оператор, эквивалентный ни ? Например, мой любимый цвет - ни зеленый, ни синий.

И код будет эквивалентен:

// example one
if (color!="green" && color!="blue") { 

}

// example two
if (x nor y) {
    // x is false and y is false
}
1,21 гигаватт
источник
12
Нет, потому что у нас уже есть orи !, и потому что двойные негативы используются редко - большинство людей находят их особенно трудными для чтения.
Килиан Фот
70
@KilianFoth прав. Тем не менее, отрицательные отзывы должны быть за плохие вопросы, а не за вопросы, которые нам не нравятся. Кроме того, уже есть три голоса, чтобы закрыть вопрос, потому что он будет «основанным на мнении», несмотря на то, что вопрос является полностью нейтральным и не противоречивым (либо есть такие операторы в каком-то экзотическом языке, либо их нет).
Кристоф
3
Есть ли имя для этого? Да, нет. Это оператор? На каком языке? А учитывая язык, вы можете посмотреть это в спецификации / документации.
Jonrsharpe
9
@Troyer Ваш комментарий демонстрирует проблему: вы неправильно поняли логику. ;) Это не эквивалентно ни.
jpmc26
3
В языках с большим количеством операторов это будет (например, в python)color not in ['green', 'blue']
Izkata

Ответы:

71

Хотя основные языки не имеют выделенных операторов NOR и NAND, некоторые менее известные языки (например, некоторые языки «игры в гольф») имеют. Например, APL имеет и для NOR и NAND, соответственно.

Другой класс примеров можно найти в языках проектирования аппаратных средств, таких как VHDL , Verilog и т. Д. Затворы NAND и NOR весьма полезны при проектировании аппаратных средств, поскольку обычно они дешевле (требуют меньше транзисторов), чем эквивалентная схема, сделанная из И / ИЛИ / НЕ. gates, что является одной из причин, по которой языки проектирования аппаратных средств, как правило, включают их; Другая причина в том, что они могут быть полезны для некоторых хитростей.

nomadictype
источник
40
APL - это не язык игры в гольф , а язык , ориентированный на массивы, который позволяет интерактивно разрабатывать мультипарадигмальные приложения с полным стеком с промышленной мощью.
Адам
59
@ Adám: Бинго .
Эрик Думинил
6
@EricDuminil :-) Это все правда, хотя.
Адам
20
@EricDuminil Нет, правда. APL - это не язык игры в гольф, а практический язык, который хорошо подходит для игры в гольф. Perl похож в этом отношении, нет?
Павел
13
OP на самом деле не сказал, что APL был языком «игры в гольф», кстати.
Уилл Кроуфорд
45

Нет, norв любом языке программирования высокого уровня нет оператора.

Почему ?

Главным образом потому, что трудно читать:

  • это требует умственной комбинации нескольких операторов (« и нет », или в более литературном стиле: « далее отрицательный », « каждый неверный » )
  • это подразумевает неявный notпервый операнд, но читатель понимает это только потом
  • он отличается от человеческих языков, которые используют явное отрицание первого операнда, такого как « ни х, ни у », « ни х, ни у ». Таким образом, читатель может спутать (x nor y)с (x and not y)вместо((not x) and (not y))
  • некоторые читатели путают очевидную orсемантику, которая не применима

Но это так часто встречается в оборудовании ...

norявляется элементарным аппаратным элементом, который может использоваться для создания всех других логических элементов. Поэтому можно утверждать, что все остальные логические операторы являются комбинациями и norявляются простейшим элементарным логическим оператором.

Однако то, что верно для аппаратного обеспечения, не обязательно верно для людей. И несмотря на свою популярность на аппаратном уровне, некоторые основные процессоры даже не предлагают NORв своем наборе инструкций ассемблера (например, x86 ).

альтернативы

Читаемость имеет значение. И иногда это может быть улучшено другими средствами.

Использование существующих операторов

Например:

if x not in [1,2]    // use of 'in' or 'not in' operator instead of x!=1 and x!=2

Заказ условий

if x==1 or x==2 
     action A
else 
     action B  

вместо

if x!=1 and x!=2 
    action B
else 
    action A

Использование до цикла

Некоторые языки также предлагают циклические инструкции, которые позволяют выражать условия с помощью whileили с помощью until, позволяя выбрать более «позитивный» способ. Эти инструкции, например , until c do ...в рубин , do until c ...в VB , или repeat ... until cв паскале и его потомков.

Например:

Until (x==1 or x==2) do
     ...

эквивалентно:

While (x!=1 and x!=2)
    ...

Сделать функцию

Теперь, если вы все еще предпочитаете norсинтаксис, вы можете определить функцию, но только если вы не ожидаете, что произойдет сокращение:

If ( nor(x,y) )   // attention, x and y will always be evaluated
    ...  

Преимущество функции перед оператором в удобочитаемости, поскольку читатель сразу понимает, что отрицание применимо ко всем аргументам. В некоторых языках вы можете определить функцию с переменным числом аргументов.

Christophe
источник
5
Забавно, я обычно пишу это, поскольку, while (not (x == 1 or x == 2))поскольку я нахожу x != 1 and x != 2версию трудной для чтения, и обнаруживаю, что «x не является ни 1, ни 2», намного легче обрабатывать, чем «x не равен 1, и x не равен 2».
Mael
1
@ Балдрикк, можешь уточнить?
Надеюсь, что это
4
@HopefullyHelpful Repeat... Untilвсегда выполняет тело цикла хотя бы один раз. Если x равен 1, тело цикла все еще выполняется, но не повторяется. WhileЦикл не будет выполняться тело в этом случае.
Сина
2
@ Балдрикк, да, ты совершенно прав. Когда я писал эквивалент, я говорил только об условии цикла, поскольку булевы операторы были предметом вопроса. Спасибо, я перефразирую это, чтобы уточнить
Кристоф
3
Оценка x и y nor(x,y)всегда выполняется в зависимости от языка и способа nor()его реализации. Существуют языки (D, Io,…), где вызываемая функция может решить, когда и когда оценивать аргументы.
Блэкджек,
18

@ KilianFoth комментирует вопрос на месте.

Вы можете синтезировать norиз notи or:

if (x nor y)

точно так же, как

if (not (x or y))

Введение norв качестве отдельного оператора внесло бы в язык избыточности, которые не нужны и не нужны (или - которые не нужны и не нужны).

Кроме того , я не знаю ни одного языка , имеющего nandоператор - вероятно , потому , что он может быть синтезирован из notи andоператоров.

Теоретически вы могли бы создать язык только nandили только с norоператорами. Все and, orи notможет затем synthesied из них. Единственная проблема в том, что это было бы смехотворно громоздко. Например, см NOR логики и NAND логики в Википедии.

Мэл
источник
4
Избыточности также могут быть не нужны или не нужны :)
Дейв
@Dave Это каламбур был предназначен, рад видеть, что вы заметили ;-)
Mael
5
Одни только избыточности не объясняют, почему они norне включены. Иначе, почему у языков есть andи or? Они излишни, благодаря Де Моргану. На самом деле, вы могли бы заменить все три обычные логические операторы ( and, or, not), предоставляя только nor , как вы справедливо заметили.
Конрад Рудольф
1
@KonradRudolph Технически все, что вам нужно, это лямбда-оператор . Причина, по которой мы делаем больше, заключается в том, чтобы соответствовать ментальной модели, которую имеет большинство программистов. Большинство программистов думать о логике в терминах and, orи not- потому что это то , что используют большинство человеческих языков. Как только вы соответствуете ментальной модели и / или / нет, тогда ни & nand становятся излишними. Их избыточность даже кодируется в их именах: «n (ot) и» и «n (ot) или». Если бы у нас были отдельные, ранее существовавшие английские термины для них, а не только синтезированные, то вы, вероятно, видели бы их чаще.
RM
1
Re избыточность в качестве аргумента: Есть языки с более чем not, and, or. Например, некоторые базовые диалекты (GW-BASIC, QuickBASIC,…) имеют эксклюзивные или XOR, импликации IMP (→ NOT (x XOR y)) и эквивалентные EQV (→ NOT (x) OR y) в качестве дополнительных операторов.
Блэкджек,
11

Да, APL и некоторые из его диалектов не имеют ни (и не NAND ). В APL, ни обозначается (так как это , или и ~это не ):

 resultExampleOne color
  :If (color'green')⍱(color'blue')
      result'warm'
  :Else
      result'cold'
  :EndIf


 resultExampleTwo(x y)
  :If xy
      result'x is false and y is false'
  :Else
      result'at least one of them is true'
  :EndIf

Попробуйте онлайн!

Адам
источник
10

Этот ответ взят из языка ассемблера для компьютера, сделанного в середине 1960-х годов. Это довольно неясно, но в некоторых отношениях это решает ваш вопрос.

DEC (Digital Equipment Corporation) выпустила компьютер PDP-6 в середине 1960-х годов. Эта машина имела в общей сложности 64 инструкции, которые были логическими операциями над двумя операндами (включая некоторые вырожденные случаи). Эти 64 инструкции были действительно 16 операторами с 4 вариантами в каждом операторе.

Два из операторов, ANDCB и ORCB, реализовали NOR и NAND соответственно (если я не запутался в двойной отрицательной логике). Вы можете увидеть таблицу кодов операций . Таблица кодов операций на самом деле предназначена для компьютера PDP-10, преемника PDP-6.

Если вы посмотрите на числовую инструкцию в двоичном виде, она становится более интересной. Оказывается, что для всех кодов операций в диапазоне 400-477 (восьмеричное) четыре бита в самой инструкции обеспечивают четырехбитовую таблицу истинности для 16 возможных логических операторов. Некоторые из этих операторов игнорируют один или оба входа. Например, SETZ и SETO игнорируют оба входа.

Разработчики PDP-6 использовали этот факт для реализации всех этих инструкций с меньшим количеством логики, чем для реализации только некоторых из них. Некоторые из этих инструкций появляются редко, если вообще когда-либо, в коде на ассемблере. Но они все были там.

Таким образом, ANDCB является эквивалентом NOR. (опять же, если я не получил свою логику в обратном направлении, в этом случае ORCB является эквивалентом).

Уолтер Митти
источник
3

В Perl есть unlessключевое слово, которое позволяет инвертировать условия:

unless ($color eq 'green' or $color eq 'blue') {
    # code
}

Не являясь оператором NOR, вы можете выразить свои намерения аналогичным образом.

Рори Хантер
источник
3

norОператор , как вы описали это не будет повторяемые, что неизбежно приведет к большому количеству трудно обнаружить ошибки.

Ваш «Пример 2» по сути такой:

if (false nor false) {
becomes
if (true) {

Но попробуйте это снова с тремя переменными и посмотрите, что произойдет:

if (false nor false nor false) {
becomes
if ((false nor false) nor false) {
becomes
if (true nor false) {
becomes
if (false) {
Бух Бух
источник