Пишет ли `if (foobar == (" this "||" that "))` для проверки, поддерживается ли foobar для "this" или "that" в каких-либо основных языках? - PullRequest
7 голосов
/ 14 марта 2009

У меня слабая память о том, что я могу написать оператор if на таком языке, как этот:

if (foobar == ("this" || "that"))

Вместо:

if (foobar == "this" || foobar == "that")

Последнее более многословно и, следовательно, менее эстетично для меня.

Поддерживается ли прежнее соглашение на каких-либо основных языках? Есть ли причина, по которой это не поддерживается?

Ответы [ 6 ]

4 голосов
/ 14 марта 2009

Язык программирования Icon имеет эту функцию.

С помощью генераторов вы можете сделать

if i = (0 | 1) then write("0 or 1")

, что успешно, если i = 0 или i = 1. Вы даже можете сделать:

if (i | j | k) = (0 | 1) then write("0 or 1")

, который успешно выполняется, если любое из i, j или k равно 0 или 1.

Основная идея этого заключается в том, что каждая из этих (1|2|3..) последовательностей создает генератор, который будет возвращать каждое из значений по очереди, пока у него не закончатся значения. Когда вы используете генератор в логической ситуации, подобной этой, значения будут запрашиваться у генератора, пока сравнение не будет успешным. Когда вы комбинируете два генератора по обе стороны от сравнения, будут предприниматься все возможные комбинации, пока один из них не будет успешным. (Вместо возврата false оператор равенства «завершается ошибкой», если значения не равны.)

2 голосов
/ 14 марта 2009

Единственное место, где я помню, используя этот синтаксис, это COBOL, около 25 лет назад.

Я подозреваю, что причина, по которой он не поддерживается широко, заключается в том, что это приводит к неясностям, которые компилятор не может разрешить. В вашем конкретном случае это не особая проблема, потому что «this» и «that» являются строками, для которых условный оператор OR не имеет смысла. Но рассмотрим этот фрагмент на языке, подобном C, где результатом условного выражения является логическое значение 0 или 1:

int a = 22;
int b = 99;
int rslt = SomeFunction();
if (rslt == (a || b))

На данный момент компилятор не может надежно определить, что вы хотите. Вы намерены это:

if (rslt == a || rslt == b)

или вы намеревались:

if ((rslt == 0 && a == 0 && b == 0) || (rslt == 1 && a == 1 && b == 1))

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

Это также заставляет выражения вычисляться в условных выражениях иначе, чем в операторах присваивания. Это также, несомненно, усложнит компилятор.

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

2 голосов
/ 14 марта 2009

Кажется, я помню, что у Паскаля был оператор in, как в:

if x in (foo, bar) then
  ...

Что касается того, почему он не поддерживается более широко, то меня больше. Кажется, это очень хороший кусочек синтаксического сахара.

1 голос
/ 14 марта 2009

Язык создания интерактивных художественных текстов (текстовых приключений) Inform поддерживает его с помощью оператора ‘или’ (в отличие от обычного логического-или который пишется ‘||’):

if (qty==2 or 3)
    print "some";
else
    print "many";

Есть ли причина, по которой это широко не поддерживается?

Это немного особая магия; непонятно, что он делает во всем, кроме простого примера выражения.

if (n or 8==m+(1 or 2) or 7) // plausible
if (qty<4 or 5) // huh?
a= "cat" or "dog" // er

Доступная в Python и других современных языках сценариев нотация if value (sequence), вероятно, заняла эту нишу навсегда.

0 голосов
/ 15 марта 2009

В Python вы можете написать так

if(foobar in ('this', 'that', 'and something else'))

('this', 'that', 'и что-то еще') - это тип списка.

Итак, я думаю, что на любом открытом языке вы можете создать свой собственный класс:

MyClass(object):

  List values

  def in(value):
     return search_value_in_values(value)

и напишите что-то вроде этого:

if(new MyClass('this', 'that', 'and something else').in(foobar))
0 голосов
/ 14 марта 2009

Оператор || - это двоичный оператор, который принимает два операнда и возвращает одно значение. Из-за того, как выражения оцениваются в большинстве основных языков, было бы невозможно использовать этот синтаксис, чтобы проверить, равно ли значение одному из набора значений. Вот почему он не поддерживается в большинстве основных языков.

Синтаксис in, который публикует @ 1800 INFORMATION, поддерживается многими языками. Если это не поддерживается на вашем языке, вы можете просто создать функцию с именем in() или in_array(), которая принимает два аргумента, значение и массив и возвращает true, если массив содержит это значение. (Например, PHP имеет встроенную функцию in_array () .)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...