ek9_create_dynamic_function

Inserts `variableName <- (captures) is|extends Base as [pure] function` with its body (or an inline `(expr)`, or an //AI: stub) after the line; answers status, edits[] and summary, with a would-fail carrying the compiler's own diagnostics.

Category: Editor · Compare: IntelliJ "Introduce Lambda" / anonymous-class generate action

When to use it

'A closure gt over the captured min implementing discriminator' is one call with file, line (the line it goes after), variableName, baseType and bodyExpression.

When not to use it

Details

Single-mode - the syntactic variant is derived from the args: body -> multi-line block; bodyExpression -> inline `(expr)` for a named base, promoted to block for a parameterised base (grammar makes `function` mandatory there); both omitted -> `//AI:` scaffold stub. pure and inheritanceKeyword (is|extends) auto-detect from the base (is + non-pure for a user base; extends + pure for a pure built-in super), both overridable. Conflict kinds: target-not-function-body (escalation - anchor line not inside a callable body), dynamic-body-not-supported (nesting inside a dynamic body, V1 refusal), bodyless-stub-needs-body (a no-return base like Consumer/Acceptor needs a body); everything else - base unresolved, purity mismatch, capture syntax E06230/E06240/E02040 - surfaces as the scratch-compile's own diagnostics (the fresh binding's expected E08090 is tolerated).

Arguments

ArgumentTypeRequiredWhat it is
baseTypestringyesThe abstract function being implemented: a user-defined function name in scope, or a parameterised built-in (e.g. `Function of (Integer, String)`, `Predicate of Integer`, `Consumer of String`).
bodystringMulti-line body. Mutually exclusive with bodyExpression. Refers to the base function's parameter names and its return-variable name. Omit BOTH body and bodyExpression to scaffold a `//AI: provide implementation` stub (block form + default-initialised inherited return) — supported only for a base that RETURNS a value; a no-return base (Consumer/BiConsumer/Acceptor/BiAcceptor) requires a body and a bodyless request is refused.
bodyExpressionstringSingle-expression inline body (e.g. `rtn: number > threshold`). Mutually exclusive with body. For a NAMED base emitted inline as `(<expr>)`; for a PARAMETERISED base it is promoted to the block form (EK9's grammar makes the `function` keyword mandatory there).
capturesarray of objectCapture list (may be empty). Each entry: {fieldName?, sourceExpression}. Captures are by-pointer-value — mutating the captured object inside the closure is visible to the caller (copy via :=: before capture for isolation).
filestringyesThe .ek9 source file containing the host body (workspace-relative; an absolute path inside the workspace is accepted).
inheritanceKeywordstring: is | extends`is` and `extends` are synonyms. Default: `extends` for a parameterised (generic) base, `is` otherwise.
lineintegeryes1-based line AFTER which the dynamic function is inserted (read it from ek9_read_file lineNumbers:true). Must be inside a function/program/method body and AFTER the captured variables are declared (a closure with captures cannot be hoisted above them).
purebooleanEmit `as pure`. Default: auto — true for a pure built-in super (Predicate/Function/Consumer/...), false otherwise. Must match the base's purity or the scratch-compile reports a purity mismatch.
variableNamestringyesLocal variable that receives the closure (e.g. gt, transformer, predicate1).

It also takes the arguments every tool takes.

Recorded calls

Real calls, recorded against small projects and checked on every build - a changed answer fails it. 3 of the 9 recorded are shown.

Parameterised inline promoted

Request

{
  "baseType" : "Predicate of String",
  "bodyExpression" : "r: t?",
  "dryRun" : true,
  "file" : "Dyn.ek9",
  "insertAfterLine" : 12,
  "variableName" : "gt"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "      gt <- () extends Predicate of String as pure function\n        r: t?",
    "endLine" : 13,
    "file" : "Dyn.ek9",
    "startLine" : 13,
    "type" : "insert"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 1,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "ready",
  "summary" : "Would insert dynamic function gt (extends Predicate of String, pure, block) at line 13",
  "workspaceHash" : "<workspace-hash>",
  "wouldBeDiagnostics" : [ ],
...

Cut short here: 2 more lines. The whole recorded call.

Builtin super purity

Request

{
  "baseType" : "Predicate of String",
  "bodyExpression" : "r: t?",
  "dryRun" : true,
  "file" : "Dyn.ek9",
  "insertAfterLine" : 12,
  "variableName" : "isSet"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "      isSet <- () extends Predicate of String as pure function\n        r: t?",
    "endLine" : 13,
    "file" : "Dyn.ek9",
    "startLine" : 13,
    "type" : "insert"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 1,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "ready",
  "summary" : "Would insert dynamic function isSet (extends Predicate of String, pure, block) at line 13",
  "workspaceHash" : "<workspace-hash>",
  "wouldBeDiagnostics" : [ ],
...

Cut short here: 2 more lines. The whole recorded call.

Bodyless stub user base

Request

{
  "baseType" : "discriminator",
  "dryRun" : true,
  "file" : "Dyn.ek9",
  "insertAfterLine" : 12,
  "variableName" : "gt"
}

Response

{
  "conflicts" : [ ],
  "edits" : [ {
    "after" : "      gt <- () is discriminator as function\n        rtn: false\n        //AI: provide implementation",
    "endLine" : 13,
    "file" : "Dyn.ek9",
    "startLine" : 13,
    "type" : "insert"
  } ],
  "meta" : {
    "serverMs" : "<timing>"
  },
  "risk" : {
    "crossesModuleBoundary" : false,
    "estimatedSeverity" : "trivial",
    "fileCount" : 1,
    "lineCount" : 1,
    "touchesPublicApi" : false,
    "touchesTests" : false
  },
  "status" : "ready",
  "summary" : "Would insert dynamic function gt (is discriminator, stub) at line 13",
  "workspaceHash" : "<workspace-hash>",
  "wouldBeDiagnostics" : [ ],
...

Cut short here: 2 more lines. The whole recorded call.

See also