-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes/standardizes the behavior of a repetition '_index' within a 'repeat-until' expression #245
base: master
Are you sure you want to change the base?
Conversation
e19049b
to
0905a2e
Compare
Hey, thanks for looking into this and writing a detailed analysis and fix! Officially supporting I don't quite follow the argument for the "inclusive"
But the I do see the advantage that the "inclusive" behavior matches what you would get in a C-style loop, where the index is incremented before the loop condition is evaluated. This indeed also makes it easier to write a maximum array size in a |
Great find on the two specs which employ this already! I've been thinking about this some more... If this is the case, perhaps TLDR: |
I think that |
Introduction of a further parameter My suspicion is that many of the problems of the current representation could be addressed by introducing needed functionality into a I would love to see a discussion between the senior maintainers and the user-base addressing the limitations of the |
100% agree. I also think that With the "inclusive" If you want to emulate Looking at your list in #245 (comment), this decision may break existing specs relying on the inclusive behavior, but I don't think there are that many specs using |
I failed to consider the more common use of I now agree exclusive evaluation makes more sense and modified the PR to implement this. |
#787 is related documenting issue |
…into fix-958-rep-index
@@ -333,7 +333,8 @@ class GoCompiler(typeProvider: ClassTypeProvider, config: RuntimeConfig) | |||
handleAssignmentRepeatEos(id, r) | |||
|
|||
override def condRepeatUntilHeader(id: Identifier, io: String, dataType: DataType, untilExpr: Ast.expr): Unit = { | |||
out.puts(s"for i := 1;; i++ {") | |||
out.puts("i := 0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I anticipate a problem with multiple declarations of the variable i
in the same function/scope here (IIRC, the :=
operator in Go must introduce at least one new variable). This should be solved by wrapping the i
declaration along with the for
loop into a block scope. Note that this is already done in C# and Java.
The test RepeatUntilComplex (repeat_until_complex.ksy
) should test this case.
Technically, there are already common methods blockScope{Header,Footer}
in each language compiler. The reason the condRepeatUntil{Header,Footer}
methods of CSharpCompiler
and JavaCompiler
don't use it is probably because blockScope{Header,Footer}
were only added later (in 0.9 I think) for another feature and nobody went through the existing codebase to see whether it can't be used somewhere else (but it's no big deal, just two lines here and there).
This redeclaration issue typically only occurs in statically-typed languages, because the dynamically-typed are usually OK with redeclaring arbitrary variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to let my PR go a bit stale.
Thanks for your continued interested in this as I believe this usecase is very important.
I'll check on this later this week and add the appropriate scoping.
Thanks for your patience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to let my PR go a bit stale.
You don't have to apologize. I'm sorry, because I was the one who let this PR go stale :) Unfortunately, there is always something with a higher priority, and it's hard to allocate time for less "urgent" things.
I appreciate your quick response and hopefully we get this merged soon.
Defines/Standardizes the Behavior of a Repetition
_index
within arepeat-until
ExpressionNOTE: This PR standardizes the previously-undefined behavior of
_index
withinrepeat_until
.Fixes issue #958. Because this standardizes something that was previously undefined, this PR may
warrant further discussion beyond the scope of a typical code review.
Standardizing this Behavior
Need
Issue #958 presents a basic scenario which warrants using (and therefore defining the behavior of)
_index
within arepeat-until
expression. Generally speaking, any data structure which containsa list of entries of a variable-size
N
that is capable of terminating early (beforeN
items have been processed),benefits from this functionality.
Possible Behaviors
Inclusive
_index
(Implemented in this PR)'Inclusive' means that
_index
gives the total number of elements processed plus the current entry.Thus, for the first item processed in a
repeat-until
block,_index
will yield a value of 1.This is in contrast to the typical evaluation of
_index
outside arepeat-until
expression.However, I believe this treatment of_index
within arepeat-until
expression is justified (and, in-general, the expected behavior) - see the Reasoning for Inclusive Evaluation section.Exclusive
_index
'Exclusive' means that
_index
gives the total number of elements processed without counting the current entry.Thus, for the first item processed in a repeat-until block,
_index
will yield a value of 0.This is the typical behavior of
_index
in expressions outsiderepeat-until
blocks.Current Behavior
Currently,
_index
withinrepeat-until
blocks is evaluated differently depending on the language target, see issue #958.C++:
_index
is inclusiveC#:
_index
is inclusiveGo:
_index
is inclusive both within and outsiderepeat-until
expressions.This is unlike every other language target where expressions (outside
repeat-until
)treat
_index
as exclusive (as they should).Java:
_index
is inclusiveJavascript:
_index
is inclusiveLua:
_index
is exclusiveNim:
_index
is exclusivePerl: Use of
_index
withinrepeat-until
expressions results in code that does not compilePHP:
_index
is inclusivePython:
_index
is exclusiveRuby:
_index
is inclusiveRust: Use of
_index
withinrepeat-until
expressions results in code that does not compileReasoning for Inclusive EvaluationNOTE: This PR now implements exclusive evaluation. See the discussion in the comments.
Typically,
_index
is evaluated exclusively. This way,_index
gives the current index of theentry being processed. My argument, however, is that by the time the condition within a
repeat-until
expression is being evaluated, the current item is already considered to beprocessed.
This is supported by the fact that the contents of the current item
can be referred to by the
_
reference within arepeat-until
expression - further reinforcingthat the current item is already be considered to have been 'processed' when evaluating
repeat-until
expression.Inclusive evaluation is also consistent with most implementations of a 'do while' loop, a
structure to which a
repeat-until
block is roughly analogous.Finally, inclusive evaluation will provide coverage for the most common use case:
where the maximum number of repetitions (
N
) is known, but has the potential to terminate early. Exclusive evaluation would require that the condition_index >= N - 1
is tested, rather than the cleaner_index >= N
.