Отношения с деталью

Не доводит лень до добра или Опять ленивые вычисления?

// PascalABC.NET 3.2, сборка 1399 от 08.03.2017

begin
  var St:=new stack<char>;
  '12345'.Foreach(e->St.Push(e));
  var tmp:=new stack<char>;
  repeat
    tmp.Push(St.Peek); St.Pop;
  until (St.Count=0) or (St.Peek=tmp.Peek);
  tmp.Println
end.

Тут все хорошо и получаем вывод 12345. Но стоит поменять местами термы логического “ИЛИ” в until…

begin
  var St:=new stack<char>;
  '12345'.Foreach(e->St.Push(e));
  var tmp:=new stack<char>;
  repeat
    tmp.Push(St.Peek); St.Pop;
  until (St.Peek=tmp.Peek) or (St.Count=0);
  tmp.Println
end.

… и “получи, фашист, гранату!”

Я минут двадцать был в растрепанных чувствах, потому что начинал именно с этого, последнего варианта… И почему-то вспомнилось из анекдота:

…рабочий сказал, что он состоит в особых отношениях с мастером, начальником цеха, председателем профкома, директором завода и этой деталью…

Ну, это Вы к чему?

Неправильный алгоритм - он и есть неправильный. Первый стек становится пуст. В чём же мастер виноват?

Я на всякий случай напоминаю про сокращённое вычисление логических выражений (см. справку по логическим выражениям) - Вы не это имели в виду?

Это самое. Виноват, конечно, Периодически забываю, что в этой версии Паскаля в логических выражениях может вычисляться только часть (до первого true в дизъюнкции или до первого false в конъюнкции). Допустил ляп с контролем стека и он прошел из-за этих самых “сокращенных”. Т.е. надо было делать примерно так:

begin
  var St:=new stack<char>;
  '123345'.Foreach(e->St.Push(e));
  var tmp:=new stack<char>;
  repeat
    tmp.Push(St.Peek); St.Pop;
    if St.Count=0 then break
  until St.Peek=tmp.Peek;
  tmp.Println
end.

P.S. А мастера никто и не обвинял. Как часто бывает в первый момент ,когда “не клеится”, был виноват весь мир. Кроме себя, естественно. Пока не “отпустит” и не поймешь, что виноваты, как чаще всего бывает, собственные кривые ручонки.