Ну вот как раз из за инкапсуляции, чтоб эта переменная не была видна там, где её не надо использовать. Отсутствие инкапсуляции создаёт возможность ошибиться. К примеру, использовать эту переменную вместо другой. Компилятор примет, а такую ошибку будет не легко найти. Можно ещё сделать так:
begin
//код
begin
var sym: char;
Repeat
sym := CurrentIOSystem.read_symbol;
Until (sym = END_OF_LINE_SYMBOL) or (sym = char(-1))
end;
//код
end.
Извините, но не нужно путать мягкое с теплым. С чего бы вдруг рекомендации, принятые для блоков begin … end и цикла со счетчиком, стали вдруг руководящими указаниями для циклов с пред- и постусловиями?
Для блоков - там понятно, это позволяет компилятору строить более компактный код, да и программисту проще не скакать истерически по листингу в поисках описаний. Для цикла со счетчиком понятно: локализация счетчика не позволяет пользователю “выстрелить себе в ногу”, используя последнее значение параметра цикла за пределами цикла, поскольку значение это языком не определено и остается на усмотрении реализатора. Но циклы с пост- и предусловием тут каким боком?
А в одном из ранних Бейсиков, встроенных в прошивку персоналки, была странная константа с комментарием “Так захотел Билл [Гейтс]” - и что? Ну написали так авторы, забожалось им сделать замену на while…
Автор выше пишет, что замену сделать сложно и я пытаюсь понять почему. Посмотрел код, не смог понять, где там вообще области видимости вводятся в конструкцию.
Если заключать во внешние begin end и не вставлять принудительно ограничение видимости между repeat и until (если сам пользователь туда блок не вставит с begin end), не видно особенных проблем. Там у вас проблемы появлялись когда переменную пытались после until описывать.
И регион r2.1 свёрнут. Теперь в регион r2.2 добавим регион r3.1:
begin
{$region r1.1}
{$region r2.1}
{$endregion r2.1}
{$region r2.2}
{$region r3.1}
{endregion r3.1}//А эту строчку ещё не успели написать
{$endregion r2.2}
{$endregion r1.1}
end.
Ещё до того как для r3.1 добавили его $endregion - большая часть точек сворачивания ломаются, а r2.1 (тот что был свёрнут) не только разворачивается, но его ещё начинает глючить. Когда в каждом регионе по 150 строчек - это заставляет текст программы сходить с ума. Вот примеры того как глючит r2.1:
И:
Очень похоже на очередное проявление этого бага, но в данном случае его можно легко обойти, добавив эту фичу в $endregion.
repeat_stmt
: tkRepeat stmt_list tkUntil expr
{
$$ = new repeat_node($2 as statement_list, $4, @$);
($2 as statement_list).left_logical_bracket = $1;
($2 as statement_list).right_logical_bracket = $3;
$2.source_context = @1.Merge(@3);
}
;
Я правильно понял, что …logical_bracket означают как раз инкапсуляцию между repeat-until вместо заключения всей конструкции? То есть
repeat begin … end until expr
используется вместо
begin repeat … until expr end
Кстати, если я попробую поэкспериментировать с этим файлом y, что мне надо потом запустить, чтобы он сгенерировал нужные коды? Или там не всё так просто и надо руками что-то ещё делать?
А зачем? То, что Вы предлагаете, всё равно не будет делаться. В смысле спортивного интереса - чтобы создать дикий язык - его можно поэкспериментировать создать с нуля для собственного интереса.
Ещё раз - задайте себе вопрос: “в каком языке есть то, что я хочу?”
Почему дикий. Понятно же, что выражение в until использует то, что в блоке, почему ему перекрывают вид? Если добавляется некая возможность (в данном случае локальные переменные), то наверное логично её до конца довести. А так получается, что repeat-until вообще выбивается из общей картины.
В большинстве функциональных языков - достаточно естественно такие вещи описывать, даже в TRAC который я недавно упомянул это достаточно наглядно можно было бы пояснить (если там инкапсуляцию пытаться вставить)
Так я и не рекомендую это Вам делать. Более того, при отсутствии деления на стабильную и нестабильную версии я бы даже побоялся, если такое попытаются сделать, если это может привести к каким-нибудь порушениям в синтаксических деревьях. Я поэтому и спрашиваю, как с этим можно проэкспериментировать.
Ну, что то в этом конечно есть, всё же в C#, C++ и джаве такое запрещено, проверил. В общем это 1 из тех случаев, когда разработчики поступили по стандарту, не зависимо от того - какой он.