Есть ли язык, который вырывается из условных утверждений, как только они становятся ложными? - PullRequest
1 голос
/ 16 февраля 2012

Я думал, что сталкивался с этим раньше, но не могу вспомнить, когда и на каком языке это было. В основном, если у меня есть следующее в C #:

someCondition = true
if(someCondition)
{
    // Do Something
    if(anotherCond) {
        someCondition = false;
        continue;
    }
    // Do Something Else
}

В C # это выйдет из тела оператора if при изменении someCondition, что означает, что //DO Something Else обрабатывается, только если someCondition не изменяется ...

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

someCondition = true
if(someCondition)
{
    // Do Something
    if(anotherCond){
        someCondition = false;
    }
    // Do Something Else
}

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

Редактировать: Сокращены примеры, так что, надеюсь, люди смогут видеть, что происходит, когда изменяется какое-то условие (т. Е. Условие, на которое положил оператор if, мы должны выйти из оставшегося оператора if. Я не смотрю для способа сделать это в C # или любом другом языке, но для языка, который делает это автоматически.

Ответы [ 6 ]

1 голос
/ 17 февраля 2012

Насколько я понял, нужно следующее:

if (cond) {
    A;
    B;
    C;
}

должен вести себя так, как если бы он был написан так:

if (cond) {
   A;
   if (cond) {
       B;
       if (cond) {
           C
       }
   }
}

ИМХО, это было бы глупо, вряд ли будет реализовано на любом языке, кроме, может быть, в INTERCAL. Почему я так думаю?

Хорошо, предположим, что кто-то хочет изменить код и переместить B;C в подпрограмму.

if (cond) {
    A;
    BC();
}

subroutine BC() { B;C }

Блок - согласно нашей функции - будет означать, как и раньше:

if (cond) {
    A;
    if (cond) BC();
}

Но как насчет нашей подпрограммы? У языкового дизайнера есть 2 варианта:

  • Считайте вызов BC() атомарным, т. Е. В подпрограмме условие cond не проверяется перед оператором C. Это будет означать такой простой рефакторинг изменит смысл программы сильно .
  • Каким-то образом передают информацию, что каждое утверждение должно быть защищено с cond на подпрограмму, чтобы поведение нашего блока оставалось без изменений. Это, конечно, приводит к глупой ситуации, когда поведение любой подпрограммы будет зависеть от контекста вызывается. Подпрограмма с n атомарными операторами может иметь n возможных способов поведения , даже если , она не имеет аргументов и не будет явно использовать нелокальное изменяемое состояние, в зависимости от того, сколько заявления будут фактически выполнены. (Обратите внимание, что в настоящее время существует тенденция сводить к минимуму наиболее часто вредные эффекты общего нелокального состояния. ОО-языки делают это с инкапсуляцией, языки ФП, вообще запрещая изменяемое состояние.)

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

1 голос
/ 16 февраля 2012

Я думаю, что вы можете смоделировать то, что вы хотите в C #, примерно так:

void ExecuteWhile( Func<bool> condition, 
    IEnumerable<Action> executeWhileTrue, 
    IEnumerable<Action> executeWhileFalse)
{
    if (condition())
    {
         foreach (Action action in executeWhileTrue)
         {
             action();
             if (!condition())
                 return;
         }
    }
    else
    {
         foreach (Action action in executeWhileFalse)
         {
             action();
             if (condition())
                 return;
         }
    }
}

и затем использовать это так:

truth = true;
while (true) // loop forever
{
    ExecuteWhile( () => truth,
        new List<Action> { () => { /* do something that might set truth to false*/},
                           () => { /* do something else*/}},
        new List<Action> { () => { /* do something that might set truth to true*/},
                           () => { /* do something else*/}});
}

И чтобы ответить на ваш вопрос: нет, яне думайте, что есть язык с такой встроенной функцией.

1 голос
/ 16 февраля 2012

Вы можете создать свойство в C #, которое выдает исключение при любом заданном вами условии, или truth=true.Исключение вырвется из цикла, где бы вы ни находились.

Пример на C #:

public class MyException : Exception { }

public bool truth
{
    get { return _truth; }
    set
    {
        _truth = value;
        if(value)
            throw new MyException();
     }
}
bool _truth;
0 голосов
/ 16 февраля 2012

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

0 голосов
/ 16 февраля 2012

Если вы разбили большую кучу операторов if / else на лаконичные маленькие методы, которые тестировали каждый маленький кусочек головоломки, вы можете рассчитывать на логическую оценку короткого замыкания компиляторов

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

0 голосов
/ 16 февраля 2012

Вы можете использовать цикл do.. while:

        do
        {

        } while (truth == true);

вот если я правильно понял!

...