Почему большинство языков программирования имеют только операторы сравнения двоичного равенства? - PullRequest
29 голосов
/ 08 июля 2010

В естественных языках мы бы сказали, что «какой-то цвет является основным цветом, если цвет красный, синий или желтый».

На каждом языке программирования, который я видел, это выглядит примерно так:

isPrimaryColor = someColor == "Red" or someColor == "Blue" or someColor == "Yellow"

Почему нет синтаксиса, который более точно соответствует английскому предложению.В конце концов, вы бы не сказали, что «какой-то цвет является основным цветом, если этот цвет красный или синий или желтый».

Я понимаю, просто isPrimaryColor = someColor == ("Red" or "Blue" or "Yellow"), потому что вместо красногоСиние и желтые они могут быть логическим выражением, в этом случае применяется булева логика, но как насчет чего-то вроде:

isPrimaryColor = someColor ( == "Red" or == "Blue" or == "Yellow")

В качестве дополнительного бонуса этот синтаксис обеспечит большую гибкость, скажем, вы хотите увидеть, если числоот 1 до 100 или от 1000 до 2000, вы можете сказать:

someNumber ((>= 1 and <=100) or (>=1000 and <=2000))

Редактировать:

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

Одна проблема, которая возникла, состоит в том, что, если сравниваемое значение является результатом дорогостоящего вычисления, временная переменная должна быть (ну, должна быть) создана.Другая проблема заключается в том, что могут быть проверены различные оценки, такие как «результат некоторых дорогостоящих вычислений должен быть простым и между 200 и 300»

Эти сценарии также охватываются более функциональными языками (хотя в зависимости от языка не может быть более кратким), или на самом деле любой язык, который может принимать функцию в качестве параметра.Например, предыдущий пример может быть

MeetsRequirements(GetCalculatedValue(), f(x):x > 200, f(x):x < 300, IsPrime)

Ответы [ 24 ]

23 голосов
/ 08 июля 2010

Я думаю, что большинство людей считают что-то вроде

isPrimaryColor = ["Red", "Blue", "Yellow"].contains(someColor)

достаточно ясным, что им не нужен дополнительный синтаксис для этого.

18 голосов
/ 08 июля 2010

В Python вы можете сделать что-то вроде этого:

color = "green"

if color in ["red", "green", "blue"]:
    print 'Yay'

Он называется in оператором, который проверяет набор членства.

13 голосов
/ 08 июля 2010

В Perl 6 вы можете сделать это с помощью соединений :

if $color eq 'Red'|'Blue'|'Green' {
    doit()
}

В качестве альтернативы вы можете сделать это с помощью оператора интеллектуального сопоставления (~~).Следующее примерно эквивалентно синтаксису if value in list: в Python, за исключением того, что ~~ делает намного больше в других контекстах.

if ($color ~~ qw/Red Blue Green/) {
    doit()
}

Парены также делают его допустимым perl 5 (> = 5.10);в perl 6 они необязательны.

12 голосов
/ 08 июля 2010

В Haskell легко определить функцию для этого:

matches x ps = foldl (||) False $  map (\ p -> p x) ps

Эта функция принимает список значений предикатов (типа a -> Bool) и возвращает True, если любой изпредикаты соответствуют значению.

Это позволяет вам что-то вроде этого:

isMammal m = m `matches` [(=="Dog"), (=="Cat"), (=="Human")]

Приятно то, что это не должно быть просто равенством, вы можете использовать что угодно справильный тип:

isAnimal a = a `matches` [isMammal, (=="Fish"), (=="Bird")]
9 голосов
/ 08 июля 2010

рубин

Содержится в списке:

irb(main):023:0> %w{red green blue}.include? "red"
=> true
irb(main):024:0> %w{red green blue}.include? "black"
=> false

Числовой диапазон:

irb(main):008:0> def is_valid_num(x)
irb(main):009:1>   case x
irb(main):010:2>     when 1..100, 1000..2000 then true
irb(main):011:2>     else false
irb(main):012:2>   end
irb(main):013:1> end
=> nil
irb(main):014:0> is_valid_num(1)
=> true
irb(main):015:0> is_valid_num(100)
=> true
irb(main):016:0> is_valid_num(101)
=> false
irb(main):017:0> is_valid_num(1050)
=> true
7 голосов
/ 09 июля 2010

Пока никто не упомянул SQL.Он имеет то, что вы предлагаете:

SELECT
    employee_id
FROM 
    employee
WHERE
    hire_date BETWEEN '2009-01-01' AND '2010-01-01' -- range of values
    AND employment_type IN ('C', 'S', 'H', 'T')     -- list of values
6 голосов
/ 08 июля 2010

COBOL использует уровни 88 для реализации именованных значений, именованных групп значений и именованные диапазоны значений.

Например:

01 COLOUR         PIC X(10).
   88 IS-PRIMARY-COLOUR VALUE 'Red', 'Blue', 'Yellow'.
...
MOVE 'Blue' TO COLOUR
IF IS-PRIMARY-COLOUR
   DISPLAY 'This is a primary colour'
END-IF

Испытания на дальность охватываются следующим образом:

01 SOME-NUMBER    PIC S9(4) BINARY.
   88 IS-LESS-THAN-ZERO    VALUE -9999 THRU -1.
   88 IS-ZERO              VALUE ZERO.
   88 IS-GREATER-THAN-ZERO VALUE 1 THRU 9999.
...
MOVE +358 TO SOME-NUMBER
EVALUATE TRUE
    WHEN IS-LESS-THAN-ZERO
         DISPLAY 'Negative Number'
    WHEN IS-ZERO
         DISPLAY 'Zero'
    WHEN IS-GREATER-THAN-ZERO
         DISPLAY 'Positive Number'
    WHEN OTHER
         DISPLAY 'How the heck did this happen!'
END-EVALUATE

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

5 голосов
/ 08 июля 2010

Вам понравится Perl 6 , потому что он имеет:

И вы можете комбинировать оба диапазона:

$someNumber ~~ (1..100) | (1000..2000)
4 голосов
/ 08 июля 2010

Python на самом деле дает вам возможность делать последние вещи довольно хорошо:

>>> x=5
>>> (1<x<1000 or 2000<x<3000)
True
2 голосов
/ 08 июля 2010

Icon имеет средство, которое вы описываете.

if y < (x | 5) then write("y=", y)

Мне скорее нравится этот аспект Icon.

...