30

自然言語では、「色が赤、青、または黄色の場合、一部の色は原色です」と言います。

私が見たすべてのプログラミング言語では、それは次のようなものに変換されます。

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))

編集:

非常に興味深い答えであり、私はもっと多くの言語を学ぶべきだという点を指摘しました。回答を読んだ後、厳密に同等の比較のために、セットメンバーシップに似たものが同じことを表現する明確で簡潔な方法であることに同意します(簡潔なインラインリストまたはセットを言語サポートし、メンバーシップをテストする言語の場合)

発生した問題の1つは、比較する値が高価な計算の結果である場合、一時変数を作成する必要がある(まあ、作成する必要がある)ということです。もう1つの問題は、「高価な計算の結果は素数であり、200から300の間である必要がある」など、チェックする必要のあるさまざまな評価が存在する可能性があることです。

これらのシナリオは、より機能的な言語(言語によってはより簡潔ではない場合もあります)、または実際にはパラメーターとして関数をとることができる任意の言語によってもカバーされます。たとえば、前の例は次のようになります。

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

24 に答える 24

23

みたいなことを考える人がほとんどだと思います。

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

これには追加の構文が必要ないことを十分に明確にする必要があります。

于 2010-07-08T15:14:46.010 に答える
18

Python では、次のようなことができます。

color = "green"

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

これはin演算子と呼ばれ、セットのメンバーシップをテストします。

于 2010-07-08T15:15:45.940 に答える
13

perl 6 では、 junctionsでこれを行うことができました:

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

別の方法として、スマート マッチ演算子 ( ) を使用することもできます~~。次の構文は、Python のif value in list:構文とほぼ同じです~~が、他のコンテキストではさらに多くのことを行います。

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

括弧は、perl 5 (>=5.10) でも有効にします。perl 6 ではオプションです。

于 2010-07-08T15:31:17.903 に答える
12

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")]
于 2010-07-08T17:59:18.467 に答える
9

ルビー

リストに含まれるもの:

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
于 2010-07-08T16:11:18.117 に答える
7

これまでのところ、誰も 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
于 2010-07-09T13:58:12.923 に答える
6

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はある程度英語をエミュレートするはずだったので、これはすべて起こったと思います。

于 2010-07-08T15:51:51.580 に答える
5

Perl 6を気に入っていただけると思います。

そして、両方を範囲と組み合わせることができます:

$someNumber ~~ (1..100) | (1000..2000)
于 2010-07-08T15:57:45.887 に答える
4

実際、Python を使用すると、最後のことを非常にうまく行うことができます。

>>> x=5
>>> (1<x<1000 or 2000<x<3000)
True
于 2010-07-08T15:31:41.173 に答える
2

C#の場合:

if ("A".IsIn("A", "B", "C"))
{
}

if (myColor.IsIn(colors))
{
}

これらの拡張機能の使用:

public static class ObjectExtenstions
{
    public static bool IsIn(this object obj, params object [] list)
    {
        foreach (var item in list)
        {
            if (obj == item)
            {
                return true;
            }
        }

        return false;
    }

    public static bool IsIn<T>(this T obj, ICollection<T> list)
    {
        return list.Contains(obj);
    }

    public static bool IsIn<T>(this T obj, IEnumerable<T> list)
    {
        foreach (var item in list)
        {
            if (obj == item)
            {
                return true;
            }
        }

        return false;
    }
}
于 2010-10-07T17:58:01.823 に答える
2

Pythonでは、次のように言うことができます...

isPrimaryColor = someColor in ('Red', 'Blue', 'Yellow')

(== "Red" or == "Blue")...あなたの構文よりも読みやすいと思います。言語機能の構文サポートを追加する理由はいくつかあります。

  • 効率: 速度の向上がないため、ここでは理由になりません。
  • 機能性:これも問題ありません。古い構文でできないことで、新しい構文でできることは何もありません。
  • 読みやすさ : ほとんどの言語は、複数の値の等価性を問題なくチェックしているケースを処理します。他の場合 (例: someNumber (> 1 and < 10)) の方が便利かもしれませんが、それでもあまりメリットはありません (Python では と言うことができますが1 < someNumber < 10、これはさらに明確です)。

したがって、提案された変更が特に役立つかどうかは明らかではありません。

于 2010-07-08T15:25:35.857 に答える
2

私の推測では、言語は習慣の力によって設計されています。初期の言語には、実装が簡単なため、二項比較演算子しかありませんでした。誰もが ( x > 0 and x < y) と言うことに慣れていましたが、言語設計者が数学の一般的な形式 ( ) をわざわざサポートすることはありませんでした0 < x < y

ほとんどの言語では、比較演算子はブール型を返します。の場合、これが意味をなさないと0 < x < y解釈されると、ブール値を比較する意味がないためです。したがって、新しいコンパイラは下位互換性を損なうことなく解釈できます。ただし、の場合、変数が既にブール値である場合、これが を意味するのか を意味するのかはあいまいです。(0 < x) < y<0 < x < ytmp:=x, 0 < tmp && tmp < yx == y == zx == y && y == z(x == y) == z

C# では、次の拡張メソッドを使用して、次のように記述できるようにしますsomeColor.IsOneOf("Red", "Blue", "Yellow")。直接比較 (値型の場合は配列、ループ、Equals()呼び出し、およびボックス化) よりも効率は劣りますTが、確かに便利です。

public static bool IsOneOf<T>(this T value, params T[] set) 
{
    object value2 = value;
    for (int i = 0; i < set.Length; i++)
        if (set[i].Equals(value2))
            return true;
    return false;
}
于 2010-07-08T15:25:41.503 に答える
2

アイコンには、あなたが説明した機能があります。

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

私はアイコンのその側面がむしろ好きです。

于 2010-07-08T16:03:33.743 に答える
1

それは、プログラミング言語が特に数学、論理、集合論の影響を受けているためです。ブール代数は、∧、∨ 演算子を、話し言葉の自然言語のようには機能しないように定義します。あなたの例は次のように書かれます:

Let p(x) be unary relation which holds if and only if x is a primary color
p(x) ⇔ r(x) ∨ g(x) ∨ b(x)
or
p(x) ⇔ (x=red) ∨ (x=green) ∨ (x=blue)

ご覧のとおり、プログラミング言語で使用される表記法にかなり似ています。数学は強力な理論的基盤を提供するため、プログラミング言語は、常に解釈のための多くのスペースを残す自然言語ではなく、数学に基づいています。

編集:上記のステートメントは、セット表記を使用して簡略化できます。

p(x) ⇔ x ∈ {red, green, blue}

実際、一部のプログラミング言語、特に Pascal には set が含まれていたため、次のように入力できます。

type
    color = (red, green, blue, yellow, cyan, magenta, black, white);

function is_primary (x : color) : boolean;
begin
    is_primary := x in [red, green, blue]
end

しかし、言語機能としてのセットは普及しませんでした。

PS。私の不完全な英語で申し訳ありません。

于 2010-07-08T20:41:24.470 に答える
1

数学者として、原色のセット {赤、緑、青} のメンバーである場合にのみ、その色は原色であると言えます。

Delphi では次のように言えます。

isPrimary := Colour in [clRed, clGreen, clBlue]

実際、私はこのテクニックを頻繁に使用しています。前回は3日前。自作スクリプト言語のインタプリタを実装して書いた

const
  LOOPS = [pntRepeat, pntDoWhile, pntFor];

そして、数行で、

if Nodes[x].Type in LOOPS then

質問の哲学的部分

@supercatなど(「なぜ誰もそれをしなかったのか、私にはわかりません。」):

おそらく、プログラミング言語の設計者は数学者 (または、少なくとも数学に傾倒している) であるためです。数学者が 2 つのオブジェクトの等価性を述べる必要がある場合、彼女は次のように言うでしょう。

X = Y,

当然。しかし、X がいくつかある A、B、C、... のうちの 1 つである場合、彼女はS = {A, B, C, ...}これらのもののセットを定義して次のように記述します。

X ∈ S.

実際、あなた(数学者)が書くことは非常にX ∈ S一般的です、ここで S は集合です

S = {x ∈ D; P(x)}

を書く代わりに、プロパティ P を持つユニバース D 内のオブジェクトのP(X)。たとえば、「x は正の実数です」または「PositiveReal(x)」と言う代わりに、x ∈ ℝ⁺.

于 2010-07-08T17:12:44.380 に答える
1

Objective-C の回答はまだありません。これが1つです:

BOOL isPRimaryColour = [[NSSet setWithObjects: @"red", @"green", @"blue", nil] containsObject: someColour];
于 2010-07-08T16:33:04.927 に答える
1

質問は合理的であり、私はこの変更を構文糖衣とは見なしません。比較される値が計算の結果である場合は、次のように言うほうが適切です。

  if (someComplicatedExpression ?== 1 : 2 : 3 : 5)

言うより

  中間温度;
  temp = someComplicatedExpression;
  if (温度 == 1 || 温度 == 2 || 温度 == 3 || 温度 == 5)

特に、問題の一時変数が他に必要ない場合。最新のコンパイラは、おそらく「temp」の有効期間が短いことを認識してレジスタに最適化し、「変数が特定の定数の 1 つであるかどうかを確認する」パターンを認識できる可能性がありますが、プログラマがコンパイラの手間を省きます。示された構文は既存のコンパイラではコンパイルされませんが、動作が言語仕様で定義されている (a+b >> c+d) よりもあいまいになるとは思いません。

なぜ誰もそれをしなかったのか、私にはわかりません。

于 2010-07-08T16:34:49.510 に答える
1

Basic で初めてプログラミングを学び始めたときのことを思い出します。

if X=3 OR 4

Xが3または4の場合、私はあなたが説明しているようにこれを意図していました.コンパイラはそれを次のように解釈しました:

if (X=3) OR (4)

つまり、X=3 が true の場合、または 4 が true の場合です。0 以外はすべて true として定義されているため、4 は true、OR TRUE はすべて true であり、式は常に true でした。私はそれを理解するのに長い時間を費やしました。

これが議論に何かを追加するとは主張しません。少し面白い逸話かもしれないと思っただけです。

于 2010-07-08T17:31:26.083 に答える
1

その理由を見つけるには、抽象化レイヤーを少し下る必要があります。x86 の比較/ジャンプ命令はバイナリです (数クロック サイクルで簡単に計算できるため)。

必要に応じて、多くの言語がそのための抽象化を提供しています。たとえば、PHP では次のように使用できます。

$isPrimaryColor = in_array($someColor, array('Red', 'White', 'Blue'));
于 2010-07-08T15:19:26.763 に答える
0

2つの可能性

Java

boolean isPrimary = Arrays.asList("red", "blue", "yellow").contains(someColor);

Python

a = 1500
if  1 < a < 10 or  1000 < a < 2000:
     print "In range"
于 2010-07-08T21:17:34.177 に答える
0

あなたが与える後者の例は、効果的に構文糖衣です。実行されたコードがある時点で、値を各条件と順番に比較する必要があるため、長い形式と同じコードに評価する必要があります。

ここにいくつかの形式で示されている配列比較構文は、より近いものであり、さらに近い言語が他にもあるのではないかと思います。

構文を自然言語に近づけることの主な問題は、自然言語が単にあいまいであるだけでなく、ひどくあいまいであることです。あいまいさを最小限に抑えたとしても、アプリにバグを導入することはできますが、自然な英語でプログラミングするとどうなるか想像できますか?!

于 2010-07-08T15:23:38.013 に答える
0

言語の例に追加するだけです

図式

(define (isPrimaryColor color)
  (cond ((member color '(red blue yellow)) #t)
        (else #f)))

(define (someNumberTest x)
  (cond ((or (and (>= x 1) (<= x 100)) (and (>= x 10000 (<= x 2000))) #t)
        (else #f)))
于 2010-07-08T21:03:54.093 に答える
0

これは、いくつかのメタ可能な魔法を使用してLuaで複製できます:D

local function operator(func)
    return setmetatable({},
        {__sub = function(a, _)
            return setmetatable({a},
                {__sub = function(self, b)
                    return f(self[1], b)
                end}
            )
        end}
    )
end


local smartOr = operator(function(a, b)
    for i = 1, #b do
        if a == b[i] then
            return true
        end
    end
    return false
end)


local isPrimaryColor = someColor -smartOr- {"Red", "Blue", "Either"}

注: -smartOr- の名前を -isEither- のような名前に変更して、さらに読みやすくすることができます。

于 2015-08-11T14:40:20.983 に答える
-1

コンピューター上の言語はすべて、バイナリーを使用して情報を表現するマシン用であるため、バイナリーとして比較されます。これらは、同様のロジックを使用して設計されており、ほぼ同様の目標を持っています。英語は論理的に設計されておらず、アルゴリズムを記述するように設計されておらず、人間の脳 (英語が実行されるハードウェア) はバイナリに基づいていません。これらは、さまざまなタスク用に設計されたツールです。

于 2010-07-08T16:55:49.633 に答える