{
  "isError" : false,
  "request" : {
    "file" : "Loops.ek9",
    "line" : 8
  },
  "response" : {
    "directions" : [ {
      "candidateShape" : "<result> <- cat 1 ... 10 | <stage>... | collect as Integer",
      "confidence" : "medium",
      "observation" : "Loop body accumulates [running] from source `1 ... 10`. Element type is `Integer`. `running`'s type `Integer` already implements 'operator |', so `collect as Integer` works directly (no collector synthesis needed).",
      "requiresSynthesis" : [ "a dynamic function for any conditional filter/map stage (EK9 has no arrow lambdas)" ],
      "suggestedTools" : [ "ek9_create_dynamic_function", "ek9_add_operator", "ek9_new_construct" ],
      "summary" : "candidate-stream-aggregation"
    }, {
      "candidateShape" : null,
      "confidence" : "low",
      "observation" : "If the accumulation is used once and locally, the imperative loop may read as clearly as a pipeline.",
      "requiresSynthesis" : [ ],
      "suggestedTools" : [ ],
      "summary" : "keep-as-loop"
    } ],
    "loop" : {
      "bodyCallPurity" : "pure",
      "containsNestedLoops" : false,
      "control" : null,
      "elementType" : "Integer",
      "headerGuard" : null,
      "line" : 8,
      "loopKind" : "for-range",
      "loopVarMutated" : false,
      "loopVariable" : "i",
      "source" : "1 ... 10",
      "writes" : [ {
        "conditional" : false,
        "declaredInsideLoop" : false,
        "guard" : null,
        "kind" : "compound-assign",
        "line" : 9,
        "name" : "running",
        "rhs" : "i",
        "via" : "+="
      } ]
    },
    "meta" : {
      "serverMs" : "<timing>"
    },
    "outputs" : [ {
      "conditionalWrite" : false,
      "declaredLine" : 7,
      "declaredType" : "Integer",
      "interpretation" : "accumulation -> candidate 'collect as' (collection) or a collector ('operator |') if reducing to one scalar",
      "mutationKinds" : [ "compound-assign" ],
      "name" : "running",
      "pipeEligible" : true,
      "readAfterLoop" : true,
      "writeLines" : [ 9 ]
    } ],
    "resources" : {
      "references" : [ {
        "pointer" : "ek9 -q collect as custom aggregator",
        "topic" : "custom collectors via 'operator |'"
      }, {
        "pointer" : "ek9 -q stream pipeline filter map collect",
        "topic" : "stream pipelines (filter/map/collect)"
      }, {
        "pointer" : "ek9 -q dynamic function capture",
        "topic" : "dynamic functions (EK9 has no lambdas)"
      } ],
      "workedExample" : "compiler-main/src/test/resources/examples/parseAndCompile/streams/StreamsCollectAs.ek9"
    },
    "unknowns" : [ "Commutativity/associativity of the accumulation operator is NOT checked — a reduction is only stream-safe if reordering elements preserves the result (Integer '+' commutes; String '+' and user-defined operators may not).", "'pipeEligible' is tested against the SOURCE element type; if a map stage changes the element type, re-check 'operator |' against the mapped type.", "Single-consumption of the source iterator and aliasing of the accumulator are not analysed." ]
  },
  "scenario" : "advise_shape",
  "tool" : "advise_loop"
}
