Какая польза от операции цикла NERFIN в LOLCODE?
Петли итерации имеют вид:
IM IN YR <label> <operation> YR <variable> [TIL|WILE <expression>]
<code block>
IM OUTTA YR <label>
Где < операция > может быть UPPIN (приращение на единицу), NERFIN (декремент одним), или любой унарной функцией. Что операция/функция применяется к <variable> , которая является временной, и локально к контуру. TIL < выражение > оценивает выражение как TROOF: если он оценивает как FAIL, цикл продолжается еще раз, если нет, то выполнение цикла прекращается, и продолжается после соответствия IM OUTTA YR < label. WILE <expression> является обратное: если выражение WIN, выполнение продолжается, иначе петля завершается.
Вопрос
Моя проблема с spec - это комбинация:
- отсутствие инициализатора переменной цикла
- факт, что он временный и локальный для цикла
Как я понимаю, это означает, что он должен начинаться с 0.
В то время как это большинство обычно используется для большинства использования UPPIN
, оно полностью отключается для большинства (моих) целей использования NERFIN
. Мое наиболее распространенное использование переменной декрементирующего цикла на других языках - это "повторение n раз (n не повторно используется)" идиома и строковые операции, что в любом случае не будет хорошей идеей в LOLCODE.
Можно ли использовать NERFIN
для получения декремента цикла от n до 1 или 0 таким образом, чтобы он был менее подробным, чем эквиваленты с UPPIN
или безоперационные формы цикла?
Сравнение альтернатив
Печать 5 4 3 2 1 с вариантом UPPIN
:
IM IN YR LOOPZ UPPIN YR COWNTR TIL BOTH SAEM COWNTR AN 5
VISIBLE DIFF OF 5 AN COWNTR
IM OUTTA YR LOOPZ
Плюсы:.
Минусы: переменная реального цикла недоступна напрямую.
В варианте без операции:
I HAS A COWNTR ITZ 5
IM IN YR LOOPZ
VISIBLE COWNTR
COWNTR R DIFF OF COWNTR AN 1
BOTH SAEM COWNTR AN 0, O RLY?
YA RLY, GTFO, OIC
IM OUTTA YR LOOPZ
Плюсы: переменная цикла доступна.
Минусы: дольше.
Лучше всего я могу получить NERFIN
:
IM IN YR LOOPZ NERFIN YR COWNTR TIL BOTH SAEM COWNTR AN -5
VISIBLE SUM OF 5 AN COWNTR
IM OUTTA YR LOOPZ
Плюсы: err... использует NERFIN
?
Против: переменная цикла недоступна; менее читаемый (hah!), чем вариант UPPIN
; нет выгоды в многословии.
Вопрос TL;DR, повторный
Можно ли использовать NERFIN
для получения декремента цикла от n до 1 или 0 таким образом, чтобы он был менее подробным, чем эквиваленты с UPPIN
или безоперационные формы цикла?
Я использую интерпретатор lci на уровне описания языка 1.2.
Ответы
Ответ 1
С 2007 года по этой точной теме обсуждалось обсуждение дизайна. Консенсус в то время, казалось, предлагал добавить FROM
в качестве решения, которое рабочая группа хотела ускорить в 1.2:
http://forum.lolcode.com/viewtopic.php?pid=2484
Проблема была представлена и не попала в спецификацию 1.2. Однако это, по-видимому, в спецификации 1.3:
http://lolcode.com/proposals/1.3/loop2
Тем не менее в работах. Я проверил, и он еще не находится в "будущей" ветке хранилища. Мы можем это увидеть, просмотрев код интерпретатора цикла. Начиная с 8/24/2011 (в редакции 72c983d0667d4d650657e1b7c5f4c7054096b0dd) он по-прежнему всегда назначает переменную цикла a NUMBR
0:
https://github.com/justinmeza/lci/blob/72c983d0667d4d650657e1b7c5f4c7054096b0dd/interpreter.c#L3434
Однако даже со старой спецификацией теоретически возможно использовать a TROOF
в сочетании с тестом против -1, чтобы обеспечить относительно чистую форму отсчета от 5 до 0:
BTW countdown-test.lol
CAN HAS STDIO?
HAI 1.2
HOW DUZ I COUNTDOWN YR BOWNDZ
I HAS A FIRSTIES
FIRSTIES R WIN
IM IN YR LOOPZ NERFIN YR COWNTR TIL BOTH SAEM COWNTR AN -1
FIRSTIES
O RLY?
YA RLY
COWNTR R BOWNDZ
FIRSTIES R FAIL
OIC
VISIBLE COWNTR
IM OUTTA YR LOOPZ
IF U SAY SO
COUNTDOWN 5
KTHXBYE
К сожалению, существует "взлом эффективности", который запрещает коду внутри цикла изменять переменную цикла с помощью R
:
https://github.com/justinmeza/lci/blob/a6ef5811e8eb98935a16600b799bccbe4adffdde/interpreter.c#L3408
Тем не менее, поскольку это, похоже, является ошибкой в коде, а не упущением в спецификации, скорее всего, он будет исправлен до выхода версии 1.3. Патч interpreter.c
сказать if (0 && stmt->update->type == ET_OP)
делает код для countdown-test.lol
выполненным, как ожидалось. Это может быть подходящее временное решение для существующих 1.2 развертываний LOLCODE, если вам не нужно использовать код с незагруженными установками.